【问题标题】:How to decipher complex pointer declarations in C?如何在 C 中破译复杂的指针声明?
【发布时间】:2015-04-12 15:39:11
【问题描述】:

所以我想举个例子:

int *pi; // pi is a pointer that points to an integer
const int *cpi; // cpi is a pointer that points to a constant integer
char *pc; // pc is a pointer to a char 

如何阅读这些内容:

char **x; //x is a pointer to a char pointer?
char *y[];
char **z[];

谢谢。

【问题讨论】:

  • @BillLynch 我认为不太正确。这不应该是 char *titles[] 等于 char **titles; ?
  • @BillLynch 然后呢??
  • @BillLynch:取决于放置的位置。在函数的参数列表中,T * t[] 等于 T ** t

标签: c pointers declaration


【解决方案1】:

cdecl.org 经常与此类问题相关联。毫无疑问,它更容易破译任何复杂的声明,但同时它只是提供了一个抽象的信息。作为一名 C 或 C++ 程序员,应该知道如何手动破译复杂的声明。 Spiral Rule 在某种程度上有所帮助,但在某些 cases 中失败了。这个答案将帮助程序员手动破译任何复杂的声明。


记住这两条简单的规则:

  1. 始终从由内而外阅读声明。
  2. 当有选择时,总是偏爱[]() 而不是*

第一条规则简单地说,找到正在声明的变量并开始从它的声明中解密。

对于第二条规则,如果* 在标识符之前,[]() 在其之后,则标识符代表一个数组或函数(分别),而不是指针。

示例 1:

char *y[5]; 
  • 变量/标识符是y
  • *y 之前并在 [] 之后。
  • y 必须是一个数组。

结合上述解密将导致:y5 指向char 的指针的数组

还请注意,您始终可以使用括号覆盖[]() 的正常优先级。

示例 2:

void (*pf) (int);
  • 变量/标识符是pf
  • *pf 括在括号中,它必须是一个指针。
  • () 跟在*pf 之后,意味着pf 必须指向一个函数。
  • 由于() 包含int,函数必须需要int 类型的参数。

所以,pf 是一个指向函数的指针,它需要一个 int 参数并且什么都不返回

现在,破译以下声明后你会得到什么

int *(*a[5])(void);  

答案:

a 是一个指向函数的指针数组,该函数不需要参数并返回指向 int 的指针。


注意: 请注意,这两个

char *y[];
char **z[];  

如果它们没有被声明为函数的参数,将会导致编译错误。如果它们是函数的参数,则char *y[] 等效于char **y 并且char **z[] 等效于char ***z
如果不是这种情况,那么您需要像我在第一个示例中所做的那样指定维度。

【讨论】:

    【解决方案2】:

    从 HELPPC 实用程序(David Jurgens 编写)中提取的一些示例 C 声明挽救了我在九十年代的(编程)生活(该实用程序的在线版本:http://stanislavs.org/helppc

    int i;                  i as an int
    int *i;                 i as a pointer to an int
    int **i;                i is a pointer to a pointer to an int
    int *(*i)();            i is a pointer to a function returning a
                              pointer to int
    int *(*i[])();          i is an array of pointers to functions
                              returning pointers to an int
    int *i[5];              i is an array of 5 pointers to int
    int (*i)[5];            i is a pointer to an array of 5 ints
    int *i();               i is a function returning a pointer to an int
    int (*i)();             i is a pointer to a function returning int
    int *(*(*i)())[5]       i is a pointer to a function returning a
                              pointer to an array of 5 pointers to an int
    

    【讨论】:

      【解决方案3】:

      y 是指向 char 的指针数组,z 是指向 char 指针的指针数组。 x 是指向 char 的指针

      【讨论】:

      • 为什么你认为y 是一个指向char 的指针数组?在我看来,y 不是一个数组。
      【解决方案4】:
      char **x; //x is a pointer to a pointer to char
      char *y[]; // y is an array of pointers to char
      char **z[]; // z is an array of pointers to pointers to char
      

      【讨论】:

      • 一般来说,读这样的表达式最简单的方法是从右端开始读到左端
      • @KorayTugay,'x' 的定义并不表示会有多个字符,也不表示多个字符将以 NUL 字节终止。然而,上下文可能表明这是真的。
      • y 不是char 指针的数组。会导致编译错误。 z 也一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 2015-05-02
      • 2021-12-03
      • 1970-01-01
      相关资源
      最近更新 更多