此表达式的实际含义是'n =(n << 3)+(n << 1)+ ch-'0',ch = getchar_unlocked();`?

问题描述 投票:0回答:4

在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)是什么意思?

c performance bit-manipulation bit-shift
4个回答
0
投票

如果您的输入流包含字符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

依此类推。


1
投票

<<是左移运算符,在任何C教程中都很容易找到。只需在google中搜索C运算符列表即可查看。

(n << 3) + (n << 1) = n*8 + n*2 = n*10

这是一个古老的优化技巧,但在具有快速乘数的现代体系结构中可能不会像以前那样有效


0
投票

[n<<3表示n左移3位,n<<1表示n左移1位,然后从0中减去ASCII值ch以获得int中的实际数字。

示例:当n=2n左移1位时,它变为4。因为2的二进制表示形式是010,并且当它向左移动1位时,它变为100,即4的二进制形式。对于n<<3,其工作方式相同。


0
投票

逗号运算符分隔两个表达式。首先评估然后丢弃,然后评估第二(可以使用此值)。逗号运算符的优先级比赋值的优先级低,因此解释就像其他人所说的]

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 */
}
© www.soinside.com 2019 - 2024. All rights reserved.