这个C代码有什么问题吗?

时间:2015-08-14 09:42:55

标签: 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;
}

我使用Ubuntu 14和gcc编译它,打印出来的是:

1
2
3
...
125
126
127
-128
-127
-126
-125
...

为什么它不算数到150?

4 个答案:

答案 0 :(得分:3)

<{> 1}} int的值可以是0到255或-127到127,具体取决于实现。 因此,在您的情况下,一旦值达到127,它就会溢出,您将得到负值作为输出。

答案 1 :(得分:2)

普通char的签名是实现定义的。

在您的情况下,charsigned char,可以将范围的值保存为-128到+127。

当您将i的值增加到超出限制signed char时,可以保持并尝试将其分配给myArray[i],您将面临实现定义的行为。

引用C11,章节§6.3.1.4,

  
      
  1. 否则,新类型为signed,并且无法在其中表示值;结果是实现定义的,或者引发实现定义的信号。
  2.   

答案 2 :(得分:1)

因为char SIGNED BYTE 。这意味着它的值范围是-128 - > 127。

  

编辑由于以下所有评论暗示这是错误/不是问题/ signdness /什么不...

运行此代码:

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
Try yourself

原因是一样的。 a&amp; b是带符号的字符(大小字节的有符号变量 - 8位)。 c&amp; d未签名。为签名变量分配200溢出并获得值-56。在内存中,ab, c & d`都具有相同的值,但在使用时,其类型&#34; signdness&#34;指示如何使用该值,在这种情况下,它会产生很大的不同。

关于标准

的注意事项

已经注意到(在对此答案的评论以及其他答案中)标准并未强制要求对char进行签名。那是真实的。但是,在OP提供的案例中,以及上面的代码中,char已签名。

答案 3 :(得分:0)

默认情况下,您的编译器会将char类型视为类型signed char。在这种情况下,CHAR_MIN等于SCHAR_MIN,而等于-128,而CHAR_MAX等于SCHAR_MAX,而等于127 (见标题<limits.h>

根据C标准(6.2.5类型)

  

15 char,signed char和unsigned char这三种类型   统称为字符类型。实施应   将char定义为具有相同的范围,表示和行为   要么是签名字符,要么是unsigned char

对于有符号类型,一位用作符号位。因此,对于类型signed char,最大值对应于十六进制表示法中的以下表示

0x7F

并且等于127.最高有效位是有符号位,等于0.

对于负值,有符号位设置为1,例如-128表示为

0x80

在程序中,存储在char中的值达到其正最大值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]);