指针对很多东西很有用,有时候无法理解它们在特定代码行中的含义。
例如,有时您使用指针来表示一系列元素:
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编辑的内容。
这可能是双刃剑,因为在某些情况下我会获得可读性,但它也会混淆代码
您建议如何生成更容易理解指针含义的代码?
答案 0 :(得分:1)
指针的含义始终相同。它实际上总是指向一个对象。因此,指针是指向内存中单个位置的变量
至于你的不同例子
当您执行类似
的操作时char* char_array = "abcd";
int* int_array = malloc(5 * sizeof(*int_array));
同样,指针char_array
指向单个char
,它是整个字符串a
的{{1}}。碰巧的是,由于它的初始化方式(字符串文字),有一些字符存储在下一个内存位置。
<小时/> 上例中的指针实际上与
下面的
"abcd"
相同
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
的行为
答案 1 :(得分:1)
您建议如何生成更容易理解指针含义的代码?
对于代码的局外人来说,指针的含义确实是不明确的。我建议在变量名前加上前缀,以赋予它们更多的含义。
请参阅:https://en.wikipedia.org/wiki/Hungarian_notation#Examples
当然,您不必详细了解此示例。你可以找到多种方式来加上你自己的前缀或组成。只要你在某个地方解释它就应该是好的。
答案 2 :(得分:0)
这是关于代码风格的很多内容,所以可能有不同的答案,它们都可以是正确的,但如果你愿意,可以提出不同的风格或观点。
我的建议是永远不要超过两个*。如果我记得我的C编码很好,我只用了两个*用于void **类型。
在所有其他情况下,使用typedef(不是宏!)并构建对象的良好结构。
使用typedef,为每个级别创建名称。因此,如果您从类型CELL开始,并且您想要这些类型的数组,请将其称为例如CELL_LIST,它是(指向)CELL的数组。你想要CELL_LIST数组吗?例如,将它命名为BOARD。
所以CELL_LIST是指向CELL的指针。 BOARD是指向CELL_LIST的指针(也可以命名为ROW)。需要另一个维度?称之为BOARD_LIST或BOARD_3D ......