如何理解C中的指针星*?

Posted

技术标签:

【中文标题】如何理解C中的指针星*?【英文标题】:How to understand the pointer star * in C? 【发布时间】:2011-07-25 23:19:50 【问题描述】:

我正在为指针符号 * 苦苦挣扎,我发现它在声明和表达式中的使用方式非常令人困惑。

例如:

int *i; // i is a pointer to an int

但是语法背后的逻辑是什么? i 前面的 * 是什么意思?让我们看下面的例子。请纠正我的错误:

char **s;
char *(*s); // added parentheses to highlight precedence

这就是我迷路的地方。括号之间的 *s 表示:s 是指针?但是指向什么的指针?括号外的 * 是什么意思:指向 s 的指针?

所以这里的意思是:指向s所指向的指针是指向一个char的指针吗?

我很茫然。 * 符号在声明和表达式中的解释是否不同?如果是这样,它如何解释不同?我哪里错了?

【问题讨论】:

【参考方案1】:

声明&a 表示它指向*i。毕竟它是一个指向*int 的指针。一个整数指向*i。但如果考虑j = *k 是指向指针this 的指针,则意味着&k 将是k 的值,而k 将具有指向*int 的指针。

【讨论】:

【参考方案2】:

c 中的声明规则是,你以你使用它的方式声明它。

char *p 表示您需要*p 来获取字符,

char **p 表示您需要**p 才能获取字符。

【讨论】:

【参考方案3】:

C 中的声明以表达式为中心,这意味着声明的形式应与可执行代码中的表达式形式相匹配。

例如,假设我们有一个指向名为p 的整数的指针。我们要访问p指向的整数值,所以我们取消引用指针,如下所示:

x = *p; 

表达式的类型*pint;因此,p 的声明采用以下形式

int *p;

在此声明中,int类型说明符*p声明符。声明器引入了被声明对象的名称 (p),以及类型说明符未提供的其他类型信息。在这种情况下,附加的类型信息是p是一个指针类型。声明可以读作“p 是指向int 的类型指针”或“p 是指向int 类型的指针”。我更喜欢使用第二种形式,其他人更喜欢第一种。

您可以将声明编写为int *p;int* p;,这是C 和C++ 语法的一个意外。在这两种情况下,它都被解析为int (*p);——换句话说,* 总是与变量名相关联,而不是类型说明符。

现在假设我们有一个指向int 的指针数组,我们想要访问数组中第 i 个元素所指向的值。我们对数组进行下标并取消引用结果,如下所示:

x = *ap[i]; // parsed as *(ap[i]), since subscript has higher precedence
            // than dereference.

同样,表达式*ap[i]的类型是int,所以ap的声明是

int *ap[N];

其中声明符*ap[N] 表示ap 是指向int 的指针数组。

为了说明问题,现在假设我们有一个指向int 的指针,并且想要访问该值。同样,我们尊重指针,然后我们取消引用该结果以获得整数值:

x = **pp; // *pp deferences pp, then **pp dereferences the result of *pp

由于表达式**pp的类型是int,所以声明是

int **pp;

声明符**pp 表示pp 是指向另一个指向int 的指针。

双重间接出现很多,通常是当您想要修改传递给函数的指针值时,例如:

void openAndInit(FILE **p)

  *p = fopen("AFile.txt", "r");
  // do other stuff


int main(void)

  FILE *f = NULL;
  ...
  openAndInit(&f);
  ...

在这种情况下,我们希望函数更新f 的值;为此,我们必须传递一个指向f 的指针。由于f 已经是指针类型(FILE *),这意味着我们将指针传递给FILE *,因此p 的声明为FILE **p。请记住,openAndInit 中的 表达式 *pmain 中的表达式 f 所指的对象相同。

在声明和表达式中,[]() 的优先级都高于一元 *。例如*ap[i]被解释为*(ap[i]);表达式ap[i] 是一个指针类型,* 取消引用该指针。因此ap 是一个指针数组。如果你想声明一个指向数组的指针,你必须明确地将* 与数组名分组,如下所示:

int (*pa)[N]; // pa is a pointer to an N-element array of int

当你想访问数组中的一个值时,你必须在应用下标之前遵从pa

x = (*pa)[i];

功能类似:

int *f(); // f is a function that returns a pointer to int
...
x = *f(); // we must dereference the result of f() to get the int value

int (*f)(); // f is a pointer to a function that returns an int
...
x = (*f)(); // we must dereference f and execute the result to get the int value

【讨论】:

【参考方案4】:
int i; //i is an int.
int *i; //i is a pointer to an int
int **i;//i is a pointer to a pointer to an int.

*号在声明和表达式中的解释不同吗?

是的。他们完全不同。在声明中 * 用于声明指针。在表达式中,一元 * 用于取消引用指针(或作为二元乘法运算符)

一些例子:

int i = 10; //i is an int, it has allocated storage to store an int.
int *k; // k is an uninitialized pointer to an int. 
        //It does not store an int, but a pointer to one.
k = &i; // make k point to i. We take the address of i and store it in k
int j = *k; //here we dereference the k pointer to get at the int value it points
            //to. As it points to i, *k will get the value 10 and store it in j

【讨论】:

【参考方案5】:

这样说:

int *i表示i指向的值是一个整数。

char **p 表示 p 是一个指针,它本身就是一个指向 char 的指针。

【讨论】:

【参考方案6】:

这里有一些信息

         variable    pointer
declaring     &a           p

reading/      a            *p

processing

【讨论】:

【参考方案7】:

声明中的 * 表示该变量是指向其他变量/常量的指针。意味着它可以保存该类型变量的地址。例如:char *c;表示c可以保存某个char的地址,而int *b表示b可以保存某个int的地址,引用的类型很重要,因为在指针算术中,pointer + 1实际上是@ 987654324@.

表达式中的 * 表示“存储在地址中的值”,因此如果 c 是指向某个字符的指针,则 *c 是特定字符。

char *(*s);表示s是一个指向char的指针,所以s不保存char的地址,而是保存char地址的变量的地址。

【讨论】:

【参考方案8】:

我最喜欢的解析复杂声明符的方法是clockwise-spiral rule。

基本上,您从标识符开始并遵循顺时针螺旋。请参阅链接以了解其具体使用方法。

文章没有提到的两件事:

1- 应该将类型说明符(int、char 等)与声明符分开,解析声明符,然后添加类型说明符。

2- 如果遇到表示数组的方括号,请务必阅读以下方括号(如果有的话)。

【讨论】:

你能给你的1和2举个例子吗?有读数?会很好的补充 请注意,如果您想“顺时针”调用该规则,您还必须记住从名称向上走,否则您会得到不正确的结果。【参考方案9】:

int * i 表示 i 是指向 int 的指针(向后读取,将 * 读取为指针)。 char **pchar *(*p) 都表示指向 char 指针的指针。

这里有一些其他的例子

int* a[3] // a 是一个包含 3 个指向 int 的指针的数组

int (*a)[3] //a 是一个指向 3 个整数数组的指针

【讨论】:

【参考方案10】:

你的问题有答案。

确实用双星来表示指向指针的指针。

【讨论】:

以上是关于如何理解C中的指针星*?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确的理解指针和结构体指针?

如何正确的理解指针和结构体指针?

C语言中的定位,谈谈对指针的基本理解

C语言中的定位,谈谈对指针的基本理解

c语言中的指针应该怎么理解?

C中的语法理解:指针