【问题标题】:Array Syntax Confusion数组语法混乱
【发布时间】:2015-06-10 09:01:58
【问题描述】:

众所周知,数组名称衰减为指针,例如a[i] 等价于*(a+i)。我偶然发现了一个问题,要求我预测以下输出:

int main(void)
{
   printf("%c", "abcdefgh"[4]);
   return 0;
}

他们说的答案是e,他们给出的原因是a[4]被转换成*(a+4),其中a是数组a的基地址在类似的行上我们可以找到上面的输出问题。

但是我怎么不理解 a[i] 衰减到 *(a+i) 因为编译器就是这样处理它,但是在上面的代码 sn-p 中我们将如何以及为什么要处理 "abcdef"[4] 这个?

【问题讨论】:

    标签: c arrays string


    【解决方案1】:

    如果我说你甚至可以这样写,你会更想知道:)

    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] 指定E1 的第E2 个元素(从零开始计数)。

    因此这个表达式(*((E1)+(E2)))不依赖于初始记录是E1[E2]还是E2[E1]

    回到你的代码shippet,你在这个表达式中有那个

    4["abcdefgh"]
    

    字符串文字被转换为指向其第一个字符的指针。你可以想象这样的

    char *p = "abcdefgh";
    

    你会得到

    4[p] 等价于*( 4 + p ) 并产生字符'e' 的左值

    【讨论】:

      【解决方案2】:

      "abcdefgh"[4] 等价于*("abcdefgh" + 4)。在表达式中使用时(除非它是一元&sizeof 运算符的操作数)"abcdefgh" 表示字符串的基地址。

      一般来说,请记住,只要允许char * 指针,就可以使用字符串文字。在sn -p

      char *ptr;
      p = "abcdefgh";  
      

      分配不会将字符复制到p,而是使p 指向字符串的第一个字符。 C 允许指针下标,因此我们可以为字符串文字下标:

      char ch;  
      ch = "abcdefgh"[4];  
      

      【讨论】:

      • “在表达式中使用时”——不,不在任何表达式中,仅当它不是 sizeof& 运算符的操作数时。
      • @TheParamagneticCroissant;是的。已编辑。
      【解决方案3】:

      "abcdefgh" 是一个数组。它是一个字符数组,类似于(但不完全相同)就好像您声明了一个类型为 char[9]static 的变量的存储持续时间:

      static char str[9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0 };
      

      因此,您可以像使用任何其他数组一样对其进行索引,使用 [] 下标运算符。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-11
        • 2020-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-13
        • 1970-01-01
        相关资源
        最近更新 更多