数组语法混淆

时间:2015-06-10 09:01:58

标签: c arrays string

众所周知,数组名称衰减为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>

3 个答案:

答案 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 };

因此,您可以使用[]下标运算符将其编入索引,就像任何其他数组一样。