将数组的元素赋值给另一个时,意外的值包含
我正在学习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中工作?
我应该学习更深入理解机制的概念吗?
因为它已经指出,当你下面您将得到未定义的行为:
for(i =0; i < sizeof(a2); i++){
a2[i]=a1[i];
printf("%c\n", a2[i]);
}
这是因为a2
大小为5和a1
大小为4,所以你已经访问a1
(a1[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中未定义时的含义。
“为什么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]);
}
注意:在打印'size_t'值时,使用'“%zu”'而不是''%lu“'。 – chux
注意:使用'char a2 [] =“abcd”; char a1 [] =“efg”;'很可能会促成更深入的理解。 – chux
谢谢** chux **!我必须尝试这种情况。 – csyouk