【发布时间】:2015-08-03 10:55:39
【问题描述】:
我有这个简单的代码,为什么它会返回这个随机字符?
#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?
【问题讨论】:
我有这个简单的代码,为什么它会返回这个随机字符?
#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' 和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' 是不连续的。不过,对于字母来说,情况就不同了。
'0' 到 '9' 必须是连续的 stackoverflow.com/q/9416926/995714
左移一次将一个值乘以 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
【讨论】:
您似乎正在尝试访问 c 的下一个字符值。当你执行语句c = c << 2
实际发生的事情:
1的ASCII值是49)然后乘以2(c << 2基本上是左移2,第一个左移是原始值乘以2,第二个左移是结果乘以二)196 而不是2 类型转换后存储在c 中的值。你应该做什么:
你应该简单地将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
希望这会有所帮助。
【讨论】:
整数'1' 具有ASCII 值49。所以它的左移,c<<2 产生196,然后分配回char 变量c。如果 char 是 signed,它将溢出 char。
这可能是您的平台上发生的情况,打印随机字符。
不知道为什么你期望位移产生2。如果您想要字符 '2',那么只需将 1 添加到 c。
c = c+1;
【讨论】:
'0' 到 '9' 保证在 C 标准中是连续的
a .. z 混淆了。