不同的行为

问题描述:

我写这篇文章的代码输出功率为这样B C D E不同的行为

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
char *b = a + 2; 
int i = 0 ; 
for(i = 0 ; i < 4 ; i ++) 
{ 
    *b = (a[i] + 1); 
    printf("%c",*b); 
} 

但是当我添加这样的参考:

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
    char *b = &a + 2; 
    int i = 0 ; 
    for(i = 0 ; i < 4 ; i ++) 
    { 
     *b = (a[i] + 1); 
     printf("%c",*b); 
    } 

输出成为刚刚B

+3

'&a + 2'正在添加2 *大小的数组。当然,完全启用警告的编译器会抱怨。节省时间,启用编译器警告。 – chux

+4

这应该产生一个编译器警告。如果没有,你需要提醒你的警告,并*修复*(不掩盖)所提到的问题。在这种情况下,它是一个指针算术的东西。 '&a'是'char(*)[5]',而不是'char *',所以表达式'a + 2'自然会产生与'&a + 2'不同的结果。给伤口加盐,后者也引起*未定义的行为*。 – WhozCraig

+0

感谢您的帮助 –

这与指针算术如何完成有关。当你给一个指针添加一个值时,它会通过该值增加指针乘以它引用的类型的大小。

在表达式a + 2中,a的类型为char *,所以加2将地址增加2 * sizeof(char) == 2个字节。

鉴于&a + 2,&a具有类型char (*)[5],即指向数组的指针5 char。对此添加2会使地址增加2 * sizeof(char [5]) == 10字节。这指向数组末尾的内存位置,因此解除引用会调用undefined behavior,在这种情况下会导致循环提前退出。

在第二种情况下,您也有一个无效的赋值,因为您试图将char (*)[5]类型的值赋值为类型为char *的值。

编译器应该

char a[5] = {'A' , 'B' , 'C' , 'D'}; 
char *b = &a + 2; // <<< compile error 
int i = 0 ; 
for(i = 0 ; i < 4 ; i ++) 
{ 
    *b = (a[i] + 1); 
    printf("%c",*b); 
} 

报告错误,如果你删除生成编译错误的行,输出应该是没有从你的第一段代码差异。