首页 > 解决方案 > 取消引用 [] 和 * 之间差异的指针

问题描述

我遇到了一个观点,如果我们有一个指向指针的指针,我们可以通过取消引用它[][],以防分配的内存是相邻的。如果不是,只能使用通过指针算术解除引用。但我不能完全重现这种情况,即这里是一个示例代码:

#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调用都给出相同的结果。我在这里没有得到什么,或者两种解除引用方法的工作方式完全相同?

标签: carrayspointers

解决方案


这两种方法是完全等价的。C 标准的第 6.5.2.1p2 节关于数组下标状态:

后缀表达式后跟方括号[] 中的表达式是数组对象元素的下标指定。下标运算符的定义[]E1[E2]相同 (*((E1)+(E2)))。由于适用于二元+运算符的转换规则,ifE1是一个数组对象(相当于,一个指向数组对象的初始元素的指针)并且E2是一个整数, E1[E2]指定E2第一个元素E1(从零开始计数)。

您有一个指向指针的指针,其中每个指针指向一个不同的数组,而不是真正的二维数组,这一事实不会改变这一点。


推荐阅读