首页 > 解决方案 > 数组算术 - 指针类型索引

问题描述

在我之前的问题中: Pointer dereference array index我问过关于 struct 被取消引用的问题。(我将从那里粘贴一段代码进行回顾):

#include <stdio.h>
#include <stdlib.h>
struct Test { char c; } foo;

int main (void) {

   struct Test **ar;
   ar=malloc(16);
   *ar=malloc(0); //prerequisite for second case (without getting some address from OS, I cannot go 'through' *ar to (*ar+1). 
   //Does not matter allocation of zero bytes. (only to get some valid address)
   *(ar+1) = &foo;
   //(**(ar+1)).c='c'; //// first case - works
   (*(*ar+1)).c='c'; //// second case - also works, with prerequisite
   printf("%c\n", (*(*ar+1)).c); //prints 'c'

   return 0;
}

我仍然理解+1在第一种和第二种情况下添加指针之间的关系。好吧,我在第二个中做 - 添加sizeof(struct Test*)到地址*ar,这就像数组索引(数组*ar的名称指针也是如此)。但在第一种情况下?做(**(ar+1))什么?sizeof(struct Test**)ar不是数组时,如何添加(什么?)某种指针类型?*(ar+1)不属于我的解引用地址,但是 (*ar+1)sizeof(struct Test*)确实属于我的指针 ( ) 的解引用地址(数组成员)。那么为什么第一个案例有效呢?(从链接中,我试图通过解析被索引的类型来给出我的理解[例如 - 在第一种情况下,“步骤/索引”sizeof(struct Test**)sizeof(struct Test*)) - 看看链接。

标签: carrayspointers

解决方案


那么为什么第一个案例有效呢?

(**(ar+1)).c='c'在我的特定系统上根本不起作用。

(**(ar+1))struct Test **类型(*(*ar+1))执行指针算术,并对类型执行指针算术struct Test*

这意味着在前一种情况下,算术是由 完成的sizeof(struct Test *) bytes,在后一种情况下是sizeof(struct Test)字节。

编译器可能会在您的结构中添加填充,以便它最终为 4 个字节等,无论您的系统上的指针大小如何。所以他们可能会幸运地到达同一个地址。指针大小通常为 2、4 或 8 字节,具体取决于是否使用 16、32 或 64 位地址总线。

去思考像这样晦涩难懂的代码是做什么的,意义不大。[]通常应避免显式指针算术,使用运算符获得可读代码是更好的做法。

另请注意,malloc(0)给出“要么返回空指针,要么行为就像大小是某个非零值,但返回的指针不应用于访问对象。” 如果你得到一个空指针然后尝试算术,你有未定义的行为,任何事情都可能发生。


推荐阅读