char contents[8][2]={"1","2","3","4","5","6","7","8"};
char* contentsx[8]={"1","2","3","4","5","6","7","8"};
printf("Contents: %s\n", contents[1]);
printf("Contents: %s\n", &contents[1]);
printf("Contentsx: %s\n", contentsx[1]);
printf("Contentsx: %s\n", &contentsx[1]);
打印:
Contents: 2
Contents: 2
Contentsx:2
Contentsx: //prints nothing or some garbage character
问题是,为什么 contents [1] 这是元素1的值, 使用& contents [1] 打印相同的结果,这是元素1的地址 根据这种情况,为什么 contentsx [1] 的值不同于 & contentsx [1] (有一些未定义的行为)
答案 0 :(得分:2)
contents
数组是char
的8x2数组。它的元素是char[2]
- 2 char
s的数组。因此,contents[1]
是位于索引char[2]
的{{1}}数组。获取该数组的地址时,它与该数组的初始元素的位置相同,即1
,它与字符串&contents[1][0]
的初始元素的位置相同。
虽然"2"
的地址不 char[2]
'对其printf
格式说明符的期望,但在这种情况下它恰好起作用,因为地址碰巧匹配;但是,这被认为是未定义的行为。
当你在一个指针数组%s
上尝试相同的事情时,结果是不同的:现在你在索引contentsx
传递一个指针的地址,它不再与字符串,再次导致未定义的行为。但是,这一次,未定义的行为表现为无需打印或打印随机字符。
答案 1 :(得分:2)
这是因为contents
是一个数组数组。
contents[1]
表示此数组数组中的第二个数组。因此,它的名称会衰减为指向其第一个元素的指针,该元素的大小为1. &contents[1]
,然而,它指向整个数组,大小为2。
xcontents[1]
是char *
指向给定字符串的确切位置。 &xcontents[1]
是指向该条目的char **
,在这种情况下为char *
。