如何区分不同指针的含义?
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_array
在 printf()
语句中的表现,
这里有很多关于代码风格的内容,所以可能会有不同的答案,而且它们都可能是正确的,但如果您愿意,可以呈现不同的风格或观点。
我的建议是永远不要超过两个 *。如果我还记得我的 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
当然,您不必详细遵循此示例。您可以找到多种方式来添加前缀或组成您自己的方式。只要你在什么地方解释一下就可以了。
指针在很多方面都很有用,以至于有时无法理解它们在特定代码行中的含义。
例如,有时您使用指针来表示一系列元素:
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_array
在 printf()
语句中的表现,
这里有很多关于代码风格的内容,所以可能会有不同的答案,而且它们都可能是正确的,但如果您愿意,可以呈现不同的风格或观点。
我的建议是永远不要超过两个 *。如果我还记得我的 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
当然,您不必详细遵循此示例。您可以找到多种方式来添加前缀或组成您自己的方式。只要你在什么地方解释一下就可以了。