指针取消引用[]和*之间的差异

时间:2019-12-11 14:48:36

标签: c arrays pointers

我遇到一种观点,如果我们有一个指向指针的指针,那么在分配的内存相邻的情况下,我们可以通过[][]对其进行取消引用。如果不是这样,则只能使用通过指针算法取消引用。但是我无法完全重现这种情况,即下面是示例代码:

#include <stdio.h>
#include <stdlib.h>

#define ITEMS_NO    3
#define LETTERS_NO  4

int main(void)
{
    char* theArray[ITEMS_NO];
    char* dummyArr[ITEMS_NO];

    for (int i = 0; i < ITEMS_NO; ++i)
    {
        theArray[i] = malloc(LETTERS_NO);
        dummyArr[i] = malloc(LETTERS_NO); // make sure mem is not adjecent

        for (int k = 0; k < LETTERS_NO - 1; ++k)
        {
            theArray[i][k] = '0' + i;
            dummyArr[i][k] = 'z';
        }

        theArray[i][LETTERS_NO - 1] = 0;
        dummyArr[i][LETTERS_NO - 1] = 0;
    }

    for (int i = 0; i < ITEMS_NO; ++i)
    {
        printf("item by square bracket %i = %c \n", i, theArray[i][1]);
        printf("item by ptr %i = %c \n", i, *((*(theArray + i)) + 1));
        free(theArray[i]);
        free(dummyArr[i]);
    }
}

在此示例中,我分配了dummyArr,以确保为theArray分配的内存彼此不相邻。两个printf调用都给出相同的结果。我不是在这里得到东西,还是两种解引用方法都以完全相同的方式工作?

1 个答案:

答案 0 :(得分:3)

这两种方法完全相同。 C standard的第6.5.2.1p2节关于数组下标状态:

  

后缀表达式,后跟方括号[]中的表达式   是数组对象元素的下标名称。的   下标运算符[]的定义是E1[E2]与   (*((E1)+(E2)))。由于适用于   二进制+运算符,如果E1是一个数组对象(相当于一个指针)   到数组对象的初始元素),E2是一个整数,   E1[E2]指定E2的第E1个元素(从零开始计数)。

您拥有一个指针到指针的事实,即每个指针都指向一个独立的数组,而不是真正的2D数组。