2015-07-10 82 views
2

我正在学习C语言。 当我将一个元素的数组值赋给另一个时,(看起来)奇怪的事情发生。 我的代码如下。将数组的元素赋值给另一个时,意外的值包含

int main(void){ 
    int i =0; 
    char a2[] = "aaaa"; 
    char a1[] = "bbb"; 

    printf("%lu\n",sizeof(a2)); 
    printf("%lu\n",sizeof(a1)); 
    printf("%c\n",a2[4]); 
    printf("---\n"); 
    for(i =0; i < sizeof(a2); i++){ 
     a2[i]=a1[i]; 
     printf("%c\n", a2[i]); 
    } 
    printf("---\n"); 
    printf("%c\n", a2[4]); 

    return 0; 
} 

结果在下面。

 
5 
4 

--- 
b 
b 
b 

b 
--- 
b 

我不知道为什么 一个[4] A2 [4]值是 “B”。首先,我想如果我尝试编译这段代码,编译器会通过错误,但它说OK。 因此,我显示结果,并看到a2 [4]元素包含“b”字符。 数组如何在C中工作?

我应该学习更深入理解机制的概念吗?

+1

注意:在打印'size_t'值时,使用'“%zu”'而不是''%lu“'。 – chux

+0

注意:使用'char a2 [] =“abcd”; char a1 [] =“efg”;'很可能会促成更深入的理解。 – chux

+0

谢谢** chux **!我必须尝试这种情况。 – csyouk

回答

6

因为它已经指出,当你下面您将得到未定义的行为:

for(i =0; i < sizeof(a2); i++){ 
    a2[i]=a1[i]; 
    printf("%c\n", a2[i]); 
} 

这是因为a2大小为5和a1大小为4,所以你已经访问a1a1[4])的第五个元素,它超出了数组范围。因此,当你做a2[4] = a1[4]时,这是for循环的最后一次迭代所做的工作,因为a1[4]的值没有很好地定义,所以可以将任何值分配给a2[4]。因此,尽管a2[4]是数组中的有效元素,但您已将其指定给它的内容没有很好定义,并且当您打印a2[4]时,您可以打印任何东西。请参阅最后一段,了解您最有可能得到的原因b

有几件事情要记住这一点。第一个数组是基于零的索引,C中的第二个字符串是空终止的,因此sizeof("aa")其实是3不是2.

由于您的程序具有未定义的行为,因此可以打印任何值,因为任何值都可以在a1 [4]中。话虽如此,如果编译器在a1之后立即放置数组a2,您将始终看到b已打印,因为您在循环的第一次迭代中将值b指定为a2[0]。这只是一个可能的解释,为什么你看到一个b。编译器不必将数组放在这个位置,实际上在我的机器上它不会将数组放在这个位置。这就是当行为在C中未定义时的含义。

1

“为什么a[4]的值是"b"”不正确。 (当然,装置OP这里a2

注意的a2尺寸被打印为5以下的不a2阵列边界之外访问。代替代码简单地打印空字符'\0'最初,然后....

char a2[] = "aaaa"; 
.... 
printf("%c\n",a2[4]); 

代码进入未定义行为与以下循环中最后一次迭代作为a2[4] = a1[4];访问a1以外的4 char大小。所以其余的代码行为是undefined

char a1[] = "bbb"; 
... 
for(i =0; i < sizeof(a2); i++){ 
    a2[i]=a1[i]; 
    printf("%c\n", a2[i]); 
} 
相关问题