在codechef的许多解决方案中,为了获得更快的输入输出,我遇到了这个表达式,但是由于我没有太多经验,所以我无法理解它。
inline int scan( ) {
int n=0;
int ch=getchar_unlocked();
while( ch <48 )ch=getchar_unlocked();
while( ch >47 )
n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked();
return n;
}
在上面的函数中,下面提到的表达式的目的是什么?
n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked();
[(n<<3)+(n<<1)
是什么意思?
如果您的输入流包含字符0-9,则为代码块
while( ch >47 )
n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked();
从字符串中计算十进制整数,只要ch < 58
,即'9'
。如果为ch >= 58
,则结果无意义。
假设进入循环的第一个字符是8
。然后,
n = (n<<3)+(n<<1) + ch-'0' = 8
假设第二个字符是5
。然后,
n = (n<<3)+(n<<1) + ch-'0' = 85
依此类推。
<<
是左移运算符,在任何C教程中都很容易找到。只需在google中搜索C运算符列表即可查看。
(n << 3) + (n << 1) = n*8 + n*2 = n*10
这是一个古老的优化技巧,但在具有快速乘数的现代体系结构中可能不会像以前那样有效
[n<<3
表示n
左移3位,n<<1
表示n
左移1位,然后从0
中减去ASCII值ch
以获得int
中的实际数字。
示例:当n=2
和n
左移1位时,它变为4
。因为2
的二进制表示形式是010
,并且当它向左移动1位时,它变为100
,即4
的二进制形式。对于n<<3
,其工作方式相同。
逗号运算符分隔两个表达式。首先评估然后丢弃,然后评估第二(可以使用此值)。逗号运算符的优先级比赋值的优先级低,因此解释就像其他人所说的]
n = (n<<3)+(n<<1) + ch-'0', ch=getchar_unlocked();
将n乘以10,将ch的偏移值从0开始相加,并将结果存储在n中。然后调用getchar_unlocked()
并将返回值分配给ch。逗号什么都不做,只是给这里的代码增加了混乱。最好使用两个语句。
我从没见过在循环初始化/增量之外使用逗号运算符,但是在这里很方便。
for (count = 0, index = 1; index < MAX_INDEX; count += 1, index += 2) {
/* some code */
}