如何区分不同指针的含义?

How to distinguish different pointer's meaning?

指针在很多方面都很有用,以至于有时无法理解它们在特定代码行中的含义。
例如,有时您使用指针来表示一系列元素:

char* char_array = "abcd";
int* int_array = malloc(5 * sizeof(*int_array));

有时您使用指针在堆上分配单个对象或使一个元素指向另一个元素:

int a = 5;
int* int_ptr = &a;
struct item* an_item = malloc(sizeof(*an_item));

当两者都使用碰撞时,连续的指针变得不可读:

    struct cell** board;
 // Does this represent a succession of cell allocated on the heap,
 // a succession of pointers to uniques cells (like an array),
 // a succession of pointers to multiples cells (like a two dimensional array)?

 // Of course the more you add pointers the more it becomes confusing.
    struct cell*** board;

我考虑过使用 typedef 或宏来创建一个类型,该类型表示用作引用或已被 malloc 的指针的指针。
这可能是双刃剑,因为在某些情况下我会获得可读性,但它也会混淆代码。
对于生成指针含义更容易理解的代码,您有什么建议?

指针的含义始终相同。它实际上始终仅指向单个对象。因此,指针是指向内存中单个位置的变量


至于你的不同例子

当你做类似

的事情时
char* char_array = "abcd";
int* int_array = malloc(5 * sizeof(*int_array));

同样,指针char_array指向单个char,即整个字符串"abcd"a。碰巧的是,由于它的初始化方式(字符串文字),有字符存储在下一个内存位置。


上面例子中的指针其实和下面的char_ptr一样

char* char_array = "abcd";
char* char_ptr = char_array;

如果你喜欢这样

printf(" %c", char_ptr);

它将打印a

如果你这样做

printf(" %s", char_ptr);

它将打印整个字符串"abcd"

在这里你可以看到 char_ptr 也按照 char_arrayprintf() 语句中的表现,

这里有很多关于代码风格的内容,所以可能会有不同的答案,而且它们都可能是正确的,但如果您愿意,可以呈现不同的风格或观点。

我的建议是永远不要超过两个 *。如果我还记得我的 C 编码,我只对 void ** 类型使用了两个 *。

在所有其他情况下,使用 typedef(不是宏!)并构建良好的对象结构。

使用typedef,为每个级别创建名称。所以,如果你从一个类型的 CELL 开始,并且你想要这些的数组,请将它称为例如CELL_LIST,这将是一个(指向)CELL 的数组。你想要 CELL_LIST 的数组?例如将其命名为 BOARD。

所以CELL_LIST是指向CELL的指针。 BOARD 是指向 CELL_LIST 的指针(也可以命名为 ROW)。需要另一个维度?称之为 BOARD_LIST 或 BOARD_3D ...

What do you recommend to produce code where the meaning of pointers is easier to understand?

的确,代码的外行人可能不清楚指针的含义。我建议在变量名前加前缀以赋予它们更多含义。

参见:https://en.wikipedia.org/wiki/Hungarian_notation#Examples

当然,您不必详细遵循此示例。您可以找到多种方式来添加前缀或组成您自己的方式。只要你在什么地方解释一下就可以了。