c位操作操作不会乘以字符
我有这个简单的代码,为什么它返回这个随机字符?c位操作操作不会乘以字符
#include <stdio.h>
int main()
{
char c = '1';
printf("%c\n",c);
c = c << 2;
printf("%c\n",c);
return 0;
}
1
? (some random character)
为什么不返回2?
整数'1'
具有ASCII值49
。所以左移,c<<2
产生196
然后被分配回char
变量c
。如果字符是signed
,它将溢出char
。 这可能是在您的平台上发生的,打印随机字符。
不知道你为什么期望位移产生2
。如果你想要字符'2'
,然后简单地加1到c
。
c = c+1;
“ C标准不保证'1'+1会产生'2'“ - 是的。第5.2.1节,(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf):“在源和执行基本字符集中,每个字符后的值在上面的十进制数字列表中的0应该比先前的“ –
http://*.com/q/9416926/995714的值大1”到“9”的“0”保证是连续的C标准 –
@AndrewHenle对不起。我很困惑它与'a' ..'z'。 –
因为'1'
和1
是不一样的东西。 '1'
是表示数字1
的字符字面值,表示字符'1'
的基础值取决于正在使用的字符集。
例如,在ASCII中,字符1
由十进制值49(十六进制0x31)表示。因此,假定ASCII,c = c << 2
将值196(乘以4)分配给c
。如果一个char
被签名并且长度为8位(这通常是这种情况),这将溢出并调用未定义的行为。
如果你想要它打印1
和2
你应该a)乘以2而不是4(即,移位1而不是2),并b)存储数值而不是它的表示(但当然,那么你需要打印时进行调整):
int main()
{
char c = 1;
printf("%c\n", c+'0');
c = c << 1;
printf("%c\n", c+'0');
return 0;
}
没有标准化的字符集,“0”到“9”不是连续的。尽管对于字母来说这是一个不同的故事。在C''0''到''9''上的 – Peter
必须是连续的http://*.com/q/9416926/995714 –
@LưuVĩnhPhúc和彼得,很高兴知道,谢谢。 –
左移一旦乘以2移位值的两倍左乘以所以摆在首位的值乘以4,你肯定不会得到答案2
即使代码是正确的。
现在的细节。您正在使用的打印格式%c
将该值显示为字符。 '1'
的ASCII码是49
。如果乘以2,则得到98
,这是'b'
的ASCII码。
你应该为ASCII调整前和计算后:
#include <stdio.h>
int main(void)
{
char c = '1';
printf("%c\n", c);
c = c - '0'; // ASCII adjustment
c = c << 1; // double
c = c + '0'; // ASCII adjustment
printf("%c\n", c);
return 0;
}
程序输出:
1
2
他将它乘以4,而不是2. –
@LưuVĩnhPhúc,正如我所解释的。但他问“为什么不返回2?”,这意味着他打算乘以2。 –
好像你正在试图访问C的下一个字符值。当您执行该语句c = c << 2
究竟发生了什么:
- 字符先转换成整数(它自己的ASCII值)
- 49(的
1
ASCII值49
)然后两次乘以2(c << 2
基本上是左移2,第一左移使原始值乘以2,第二左移使得结果乘以2) - 因此结果值是在类型转换之后存储在c中的
196
而不是2
。
你应该做的:
你应该简单地添加1
到变量c,因为它会将字符转换为其ASCII,然后将增加1
它即字符c
有ASCII值49
,当它被增加时,新值将是50
,当转换为字符时等于2。试试这个:
c = (int)c + 1; //By force conversion from character to integer to get the ASCII value
希望这会有所帮助。
这里检查你的答案 http://*.com/questions/1097130/in-c-left-shift-char-0xff-by-8-and-cast-it-to-int – venki