C 将索引放在指针后面的[]括号内意味着什么?

C 将索引放在指针后面的[]括号内意味着什么?,c,pointers,C,Pointers,我正在研究一些C代码只是为了理解,我发现一个指针的索引在[]之间,就像它是一个数组一样(如“指针[I]”);我不明白它是什么意思,或者它是如何工作的 这是我找到它的一段代码: struct turing_machine_t{ struct linked_list_t*** transitions; bool* acceptors; unsigned int max_steps; unsigned int num_states; }; void delete_tu

我正在研究一些C代码只是为了理解,我发现一个指针的索引在[]之间,就像它是一个数组一样(如“指针[I]”);我不明白它是什么意思,或者它是如何工作的

这是我找到它的一段代码:

struct turing_machine_t{
    struct linked_list_t*** transitions;
    bool* acceptors;
    unsigned int max_steps;
    unsigned int num_states;
};

void delete_turing_machine(struct turing_machine_t* tm){ 
    int i,j;
    for(i = 0; i < tm->num_states; i++){
        if(tm->transitions[i] != NULL){
            for(j = 0; j < ALPHABET_SIZE; j++){
                struct linked_list_t* tl = tm->transitions[i][j];

                //after here there are just some free

结构图灵机{ 结构链接列表***转换; 布尔*受体; 无符号整数最大步长; 无符号整数状态; }; void delete_turing_machine(struct turing_machine_t*tm){ int i,j; 对于(i=0;inum_states;i++){ 如果(tm->transitions[i]!=NULL){ 对于(j=0;jtransitions[i][j]; //在这里之后,只有一些免费的 它来自图灵机器模拟器,但这并不重要;
如果我是正确的,transition是一个三重指针,那么transition[I]和transition[I][j]是什么意思呢?如果它不是一个数组,那么这些索引的含义是什么?

如果指针
ptr
指向一组连续的对象,那么
ptr[I]
将引用该组的
i+1
th元素,就像
ptr
是数组一样。这可能是
tm->transitions
tm->transitions[i]
tl的情况;dr数组的行为类似于指针,您可以在指针上使用数组表示法


transition
是一个三指针。这意味着它是

a pointer to
a pointer to
a pointer to
a `struct linked_list_t`
它也可以解释为3D阵列,因为这实际上是阵列在幕后的工作方式

数组略有不同,因为如果它们是在作用域中创建的,那么您使用的任何IDE或静态分析工具通常都会跟踪它们的范围,但编译器对它们的处理方式是相同的。这是因为,当您对这样的指针进行算术运算时,编译器基本上会将
index
乘以
sizeof(*数组)
(与
sizeof(数组[0])相同)

也就是说,
array+1
是分配给
array
array+2
之后的内存地址指针,假设它的大小与
array
array+3
之后的内存地址相同,依此类推

因此,括号运算基本上是指针运算的语法糖。表达式
transitions[i][j]
可以被视为:

  • transitions
    是一个包含指针大小元素的数组
  • transitions
    (即
    *(transitions+i)
    )获取
    i
    第个指针大小的元素的值
  • 我们刚刚得到的值(我们称之为
    pointer\u val
    )本身就是指向指针大小的元素数组的指针
  • pointer\u val
    (即
    *(pointer\u val+j)
    ,或者直接从
    *(*(transitions+i)+j)
    )中获取
    j
    第个指针大小的元素的值
  • 我们刚刚得到的值是一个指向
    链接列表的指针,我们将其分配给变量
    tl

  • 请注意,在
    转换的定义中有三个星号。我们在这里说明了所有星号-前两个在数组索引中,第三个在我们正在分配的
    链接列表中。

    在Internet中搜索“指针算术”也请参见以下所有等效项:
    a[b]
    b[a]
    *(a+b)
    a
    b
    中的一个应具有指针或数组类型,另一个应具有整数类型。实际上,当
    a[b]使用了
    a
    通常有指针或数组类型,而
    b
    有整数类型,但如果你想让人困惑,你可以将它们反转。你可能会特别喜欢第6节。另请参见数组只是伪装的指针,如果不是一个彻头彻尾的谎言,那么它充其量只是一个危险的半事实。顺便说一句,索引是一个指针操作,而不是数组。索引运算符正是指针算术与解引用结果相结合的语法糖。它就是这样定义的。当一个操作数恰好指定数组时,通常会自动转换为指针。@wattbatt不太正确,因为这是一个定义而不是访问。而不是saying“这是指向指向指针的指针”,在这里,您提前定义了所有内容的大小。这主要影响内存分配的时间和方式(因为现在
    转换
    是一个内存块数组,大小与
    字母表大小*something*sizeof(结构链接列表)一样大)
    。指针算术解释了这一点,因此最终的用途是相同的。但内存分配完全不同,这会影响代码的其他部分。@GreenCoveGuy:数组不是伪装的指针-数组表达式会根据需要转换(“衰减”)为指针表达式。下标运算符
    a[i]
    是根据指针操作定义的-
    *(a+i)
    ,只是如果
    a
    是数组类型的表达式,它将转换为指针类型(值是第一个元素的地址)在计算较大的表达式之前,数组是由一系列元素组成的对象,而指针只是引用另一个单个值位置的单个值。当然,指针可以指向数组中的元素,但数组和指针肯定不是一回事或者,正如您所说,“数组只是伪装的指针”。混淆经常出现,因为当您按名称引用数组时,在大多数(但不是所有)上下文中都存在指向指针(指向第一个元素)的隐式转换。这并不意味着数组是指针!
    int a = array[index];
    int a = *(array + index);