众所周知,数组名称衰减为a[i]
等指针等同于*(a+i)
。我偶然发现了一个问题,要求我预测输出:
int main(void)
{
printf("%c", "abcdefgh"[4]);
return 0;
}
他们说的答案是e
,他们给出的理由是a[4]
被转换为*(a+4)
,其中a
是数组a
的基地址在类似的行上我们可以找到上述问题的输出。
但我如何理解a[i]
衰变为*(a+i)
,因为编译器会以这种方式对待它,但在上面的代码片段中我们将如何以及为什么要对待"abcdef"[4]
这个? / p>
答案 0 :(得分:4)
如果我说你甚至可以用以下方式写作,你会想到更多:)
printf( "%c\n", 4["abcdefgh"] );
C中的字符串文字具有字符数组类型。因此,字符串文字“abcdefgh”具有类型char[9]
。它还包括终止零。
在表达式数组中,正确地提到了衰减指向其第一个元素的指针。所以字符串文字衰减到类型为char *
的指针,指针指向'a'
的文字的第一个字符
根据C标准(6.5.2.1阵列下标)
2后缀表达式后跟方括号
[]
中的表达式 是数组对象元素的下标。该 下标运算符[]
的定义是E1[E2]
与之相同(*((E1)+(E2)))
。由于适用于的转换规则 二进制+
运算符,如果E1
是数组对象(等效于指针 到数组对象的初始元素)并且E2
是一个整数,E1[E2]
指定E2
的{{1}}元素(从零开始计算)。
因此,此表达式E1
不取决于初始记录是(*((E1)+(E2)))
还是E1[E2]
返回您的代码发货地址,您可以使用此表达式
E2[E1]
将字符串文字转换为指向其第一个字符的指针。你可以想象这就像
4["abcdefgh"]
你会得到
char *p = "abcdefgh";
相当于4[p]
,并导致字符*( 4 + p )
的左值
答案 1 :(得分:3)
"abcdefgh"[4]
相当于*("abcdefgh" + 4)
。在表达式中使用时(除非它是一元&
和sizeof
运算符的操作数)"abcdefgh"
表示字符串的基址。
通常,请记住,只要允许char *
指针,就可以使用字符串文字。在摘录
char *ptr;
p = "abcdefgh";
分配不会将字符复制到p
,而是使p
指向字符串的第一个字符。 C允许指针下标,因此我们可以下标字符串文字:
char ch;
ch = "abcdefgh"[4];
答案 2 :(得分:0)
"abcdefgh"
是一个数组。它是一个字符数组,类似于(但不完全相同),就像您声明了char[9]
类型和static
存储持续时间的变量一样:
static char str[9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0 };
因此,您可以使用[]
下标运算符将其编入索引,就像任何其他数组一样。