【问题标题】:How to distinguish different pointer's meaning?如何区分不同指针的含义?
【发布时间】:2016-01-31 09:34:40
【问题描述】:

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

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

【问题讨论】:

  • 我真的不明白这个问题。如果您是初学者,指针可能会令人困惑,并且您建议的内容可能很有用,但是在习惯它之后,这没什么大不了的。指针总是以类似的模式使用,过一段时间你就会学会它们。
  • 使用变量命名约定,以及描述其属性的指针声明上方的代码cmets(即,它是否将拥有它所指向的内容,以及它是否可能指向数组的第一个)
  • 三重间接是令人困惑的,没有办法解决这个问题。尽量避免三重间接。

标签: c pointers pointer-to-pointer


【解决方案1】:

您有什么建议来编写更容易理解指针含义的代码?

确实,对于代码的局外人来说,指针的含义可能是不清楚的。我建议在变量名称前加上前缀以赋予它们更多含义。

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

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

【讨论】:

    【解决方案2】:

    指针的含义总是一样的。它实际上总是只指向一个对象。因此,指针是指向内存中单个位置的变量


    至于你的不同例子

    当你做类似的事情时

    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() 语句中的作用相同,

    【讨论】:

    • 我不认为这是一个非常有用的回应;指针通常指向一个对象,该对象是一系列对象(又名数组)中的第一个对象,并且 OP 询问我们如何知道这种情况是否正在发生。例如。当char_ptr 可能被声明为char x; char *char_ptr = &x; 时,你怎么知道printf("%s", char_ptr); 是否安全
    • @MM,好的。我觉得OP被问到如何知道它们在理论上是否不同。我发帖说它们在理论上没有什么不同。
    • 你是对的,指针的 nature 是这样定义的,但是 OP 对可以归因于的不同 roles 更感兴趣指针。以此类推,所有人都是一样的,但我们有不同的工作。
    • 虽然它们在理论上是不同的,指向 1 个对象的情况只需要不同的代码处理与可能指向 1 个对象的情况(这是系列中的第一个对象)
    • @M.M,在 C 标准的情况下,理论上没有什么不同。所有的指针都只是指向一个对象。
    【解决方案3】:

    这与代码风格有关,因此可能会有不同的答案,而且它们都可能是正确的,但如果您愿意,可以呈现不同的风格或观点。

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

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

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

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

    【讨论】:

    • 我的建议是永远不要使用指针类型定义;读者必须建立一个准确的内存布局心智模型,并且 * 被遮盖会干扰这一点
    猜你喜欢
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多