这个C代码有什么问题?
我的源代码:这个C代码有什么问题?,c,ubuntu,gcc,C,Ubuntu,Gcc,我的源代码: #include <stdio.h> int main() { char myArray[150]; int n = sizeof(myArray); for(int i = 0; i < n; i++) { myArray[i] = i + 1; printf("%d\n", myArray[i]); } return 0; } 为什么它不直接计数到150呢?因为char是一
#include <stdio.h>
int main()
{
char myArray[150];
int n = sizeof(myArray);
for(int i = 0; i < n; i++)
{
myArray[i] = i + 1;
printf("%d\n", myArray[i]);
}
return 0;
}
为什么它不直接计数到150呢?因为
char
是一个有符号字节。这意味着它的值范围是-128->127
编辑,因为下面的所有评论都表明这是错误的/不是问题/签名/什么不是
运行此代码:
char a, b;
unsigned char c, d;
int si, ui, t;
t = 200;
a = b = t;
c = d = t;
si = a + b;
ui = c + d;
printf("Signed:%d | Unsigned:%d", si, ui);
打印:已签名:-112 |未签名:400原因是一样的
a
和b
是有符号字符(大小为字节-8位的有符号变量)<代码>c和d
未签名。将200赋值给有符号变量溢出,它们得到的值为-56。在内存中,a
,b,
c&
d`都具有相同的值,但在使用时,它们的类型“signedness”指示如何使用该值,在这种情况下会产生很大的差异
关于标准的说明
已经注意到(在对本答案以及其他答案的评论中)该标准并未要求签署char。这是真的。但是,在OP提出的情况下,以及上面的代码中,char是有符号的。普通的
char
的有符号性是由实现定义的
在您的例子中,char
是一个signed char
,它可以保存范围为-128到+127的值
当您将i
的值增加到超出signed char
所能容纳的限制,并试图将其分配给myArray[i]
时,您将面临一个实现定义的行为
引用第§6.3.1.4章中的C11
int
字符的值可以在0到255或-127到127之间变化,具体取决于实现。
因此,在您的例子中,一旦值达到127,它就会溢出,并且您会得到负值作为输出。在默认情况下,您的编译器将类型
char
视为与类型有符号char
类似。在这种情况下,CHAR_MIN
等于SCHAR_MIN
,反过来等于-128
,CHAR_MAX
等于SCHAR_MAX
,反过来等于127
(参见页眉
)
根据C标准(6.2.5类型)
15 char、signed char和unsigned char这三种类型是
统称为字符类型。实施应:
定义char,使其具有与相同的范围、表示形式和行为
有符号字符或无符号字符
对于有符号类型,一位用作符号位。因此,对于类型有符号字符
,最大值对应于以下十六进制表示法
0x7F
等于127。最高有效位是有符号位,等于0
对于负值,有符号位设置为1,例如-128
表示为
0x80
在您的程序中,存储在字符中的值达到其正最大值0x7F
并增加后,它将变为等于0x80
,在十进制表示法中等于-128
如果希望程序执行结果不依赖于编译器设置,则应显式使用typeunsigned char
而不是char
或者在printf语句中,可以显式地将typechar
强制转换为typeunsigned char
。比如说
printf("%d\n", ( unsigned char )myArray[i]);
或者,为了比较结果,您可以在循环中写入
printf("%d %d\n", myArray[i], ( unsigned char )myArray[i]);
你不觉得它停在127(2^7-1)是可疑的吗?同样令人不快的是,你使用的是
int
,其中应该使用size\u t
,因为sizeof
的计算结果就是这样的。另外,它至少应该是int main(void)
@alk为什么int main()
不正确?除了字符串之外,不要使用普通char
类型。相反,使用uint8\u t
@fuzzxl在一些独立系统上可能是正确的,但我对此表示怀疑。在大多数C版本中,这是不正确的。但是它在C++中是完美的。因为字符是有符号字节。错了,标准没有说明它是有符号的还是无符号的。你得到了3张赞成票,真让赞成票的人感到羞耻。字符是一个有符号的字节。你能引用点什么吗?@cnicutar-你对标准的看法是对的,我对发生的事情的看法是对的(myArray
是一个有符号的字节数组…@Amit-Ummm.)。。我想没有,因为这是UB。所以,没有什么是可以保证的。@cnicutar只是为了澄清一下,char
的签名性是实现定义的,签名类型的溢出是UB。对吗?先生,我不认为原因是编译器的问题。导致这种情况的是printf的格式说明符“%d”。这与作为数据类型的“char”无关。@vish4071您错了。当参数从char类型提升到int类型时,它的符号性被保留。更常见的是二的补码,从-128到127。也许这就是你的意思。应该注意的是,有符号整数溢出在C中是未定义的。
printf("%d %d\n", myArray[i], ( unsigned char )myArray[i]);