我的源代码:
#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; }
我使用的是Ubuntu 14和gcc来编译它,它打印出来的是:
1 2 3 ... 125 126 127 -128 -127 -126 -125 ...
为什么不计算到150?
看来你的编译器默认认为类型char
类型signed char
。 在这种情况下, CHAR_MIN
等于SCHAR_MIN
,而等于-128
而CHAR_MAX
等于SCHAR_MAX
,又等于127
(参见标题<limits.h>
)
根据C标准(6.2.5类型)
三种类型的char,signed char和unsigned char被统称为字符类型。 实现应该定义char与signed char或unsigned char具有相同的范围,表示和行为
对于签名类型,一个位用作符号位。 因此,对于类型signed char
,最大值对应于以十六进制表示法的以下表示形式
0x7F
等于127.最高有效位是有符号位,等于0。
对于负值,有符号位设置为1,例如-128
表示为
0x80
在你的程序中,存储在字符中的值达到正的最大值0x7F
,并增加到等于0x80
,十进制表示等于-128
。
如果您希望程序执行的结果不依赖于编译器设置,则应明确使用类型unsigned char
而不是char
。
或者在printf语句中,您可以明确地将类型char
为键入unsigned char
。 例如
printf("%d\n", ( unsigned char )myArray[i]);
或者比较结果,你可以写在循环中
printf("%d %d\n", myArray[i], ( unsigned char )myArray[i]);
char
int
值的范围可以从0到255或-127到127,具体取决于实现。 因此,一旦在你的情况下值达到127,它溢出,你得到负值作为输出。
一个普通char
的签名是实现定义的。
在你的情况下,一个char
是一个有signed char
,它可以将范围的值保存为-128到+127。
当你增加i
的价值超过极限signed char
可以容纳并试图分配给myArray[i]
你正在面对一个实现定义的行为。
引用C11
第6.3.1.4章,
- 否则,新的类型被
signed
并且值不能被表示; 结果是实现定义的或实现定义的信号被引发。
因为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都具有相同的值,但是当使用他们的类型“signdness”时,这个值就是如何使用的,在这种情况下,它会产生很大的差别。
已经注意到(在对这个答案的评论以及其他答案中)标准没有要求字符被签名。 那是真实的。 然而,在OP提供的情况下,以及上面的代码,char被签名。