代码之家  ›  专栏  ›  技术社区  ›  David

C中的数组是指针的语法糖吗?

  •  7
  • David  · 技术社区  · 7 年前

    让我们看一下以下代码:

    int arr[n];
    // s.t. i<n
    arr[i] = 12;
    // s.t. i<n 
    *(arr + i) = 12;
    

    arr[i] 是的语法糖 *(arr+ i) ?

    5 回复  |  直到 4 年前
        1
  •  9
  •   alk    7 年前

    是的,你可以这么说- 数组下标访问 与指针访问相同 * 取消引用。

    从…起 6.5.2.1p2 C11标准N1570

    后缀表达式后跟方括号中的表达式 [] 是数组对象元素的下标指定。 下标运算符的定义 [] 是吗 E1[E2] 与相同 (*((E1)+(E2))) . 因为二进制文件的转换规则 + 操作员,如果 E1 是数组对象(相当于指向数组对象初始元素的指针),并且 E2 是整数, E1[E2] 指定 E2级 -第个元素 E1级 (从零开始计数)。

    绝对不是 应该给您留下数组是指针的印象。有趣的是,当你申请时 [] 数组衰减为指向第一个元素的指针,该指针用于访问后续元素。

    数组对象是另一回事——有时数组不会衰减为指针。它们不是语法上的糖——你可以考虑一个例子-

    int p[] = {1, 2 ,3};
    int *t = p;
    size_t sz1 = sizeof p;
    size_t sz2 = sizeof t;
    printf("%zu %zu\n", sz1, sz2);
    

    运行此命令,我将了解与您的问题更相关的内容。数组不能用数组本身以外的东西来实现。数组访问与指针解引用相同,但这并不意味着指针取数组的位置,反之亦然。

    C编程的外卖键或红色药丸:

    数组是数组,指针是指针。它们是不同的东西。


    顺便说一下,如果 sizeof 骗了你一点-别担心,有一个标准的章节这么说。从…起 6.3.2.1p3

    除非它是 sizeof公司 操作人员 这个 _Alignof 运算符或一元数 & 运算符,或是用于初始化数组的字符串文字,该表达式的类型为 'array of type' 转换为类型为的表达式 'pointer to type' 它指向数组对象的初始元素,并且不是左值。。。

    数组用作的操作数时,不会转换为指针 sizeof公司 . 这就是问题所在。这就是为什么您得到了在前面的代码片段中得到的东西。

        2
  •  4
  •   Gerhardh    7 年前

    arr[i] 与相同 *(arr+i) 这与 *(i+arr) 这与 i[arr]

    根据法比奥·图拉蒂的评论: 看见 "Why is a[5] == 5[a]" 了解更多详细信息。

        3
  •  0
  •   Nivesh Gadipudi    4 年前

    是的,您可以使用arr[i]/*(arr+i)访问数组元素。

    甚至可以对数组指针使用增量操作。 *ptr=&arr, ptr公司++

    这意味着每次向数组指针添加整数或增量时,指针都会向上一个指针添加(数据类型的大小)*i。

        4
  •  0
  •   ivan.ukr    4 年前

    严格地说,数组不是指针的语法糖。根据定义,“句法糖”是一种语言结构,它可以让你写得更短/更清晰,相当于其他一些语言结构。指针和数组的情况不同。指针是包含某个值的内存地址的变量。不同的是,数组是包含这些值本身的变量。然而,C的语法是以某种方式构建的,它允许您将指针视为数组第一个元素的地址,并对其应用索引运算符。但我不会说这是语法糖,这是语言的基本语法。

        5
  •  -1
  •   Shachar Shemesh    7 年前

    绝对不是!要了解这一点,只需在示例中用指针替换数组即可:

    int *arr;
    // s.t. i<n
    arr[i] = 12;
    // s.t. i<n 
    *(arr + i) = 12;
    

    这可以很好地编译,但它是未定义的行为。它不能保证工作。事实上,有 没有什么 这个程序可能会这样做,这将被视为编译器中的一个bug。

    数组是数组;包含数据的类型。指针指向数据所在的位置。指针不包含实际数据,而数组包含实际数据。

    一些 数组名称的行为方式与指针相同的情况。这并不能使两者完全相同。

    例如,请查看以下内容:

    int arr[12];
    int ptr;
    
    ptr = arr; // Legal
    printf("array size %ld\n", sizeof(arr)); // Usually prints 12*4=48
    printf("pointer size %ld\n", sizeof(ptr)); // Depending on your arch, will likely print either 4 or 8.