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

时间:2016-01-31 09:34:40

标签: c pointers pointer-to-pointer

指针对很多东西很有用,有时候无法理解它们在特定代码行中的含义。
例如,有时您使用指针来表示一系列元素:

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编辑的内容。
这可能是双刃剑,因为在某些情况下我会获得可读性,但它也会混淆代码 您建议如何生成更容易理解指针含义的代码?

3 个答案:

答案 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 ......