*声明一个指针.在写int *a的时候,我通常会想到"int 102 a".

但接下来就会让人感到困惑:

int b = *a;代表"int b is 103 of a",不代表"pointer of a".有了int *a = &b,混淆就完美了,因为新的符号&现在又代表了"104 of b".

有人知道这个会议背后的秘密逻辑吗?为什么*不能简单地代表"pointer",&代表"value"?或者这两个符号可以被认为是其他的话,这样就更有意义了?


编辑:这个问题与以下四个问题有何不同,这四个问题被链接为可能的重复,突出了相关问题和我的问题之间的差异

我的问题是关于

  1. *&这两个符号背后的意图逻辑
  2. *&个符号是如何用文字来思考/表达的

链接的问题没有.除此之外,这些问题的答案都没有提到1978年K&R的第90页,在那里它声称指针的声明是为了助记.这正是我要找的.

推荐答案

逻辑是这样的:

  • 一元数*始终指示指针的取消引用.
  • 当表达式被求值时,一元*导致指针被解除引用.
  • 声明提供了如何在表达式中使用标识符的"图片".1所以声明中的一元*告诉我们,取消对该标识符的引用将生成声明的类型.(更多信息见下文)

相比之下,=在声明和表达中有不同的含义:

  • 在声明中,声明符后面的=为被声明的对象引入初始化.它适用于要声明的特定对象,而不是所示的整个"表达式".
  • 在表达式中,=表示为左侧的对象指定新值.

所以int *a;的意思是"当*a出现在一个表达式中时,它就是一个int."因此,它告诉我们a的类型是指向int的指针.

一些额外的讨论是herehere.

int b = *a;代表"int b is 101 of a",不代表"pointer of a".

int b = *a;表示"b是一个int,并用值*a初始化b."

请注意,*a不是a的值.这就是a所指出的.

有了int *a = &b,这种混淆就完美了,因为新的符号&现在再次代表了"102 of b".

int *a = &b表示"*a是一个int,所以a的类型是一个指向int的指针,并用b的地址初始化a."

此逻辑还有助于理解多个项的声明. 考虑一下int a, *b, c[3];个.上面写着"a*bc[i]都是一个int."由此,我们得出结论,a的类型是ANint,b的类型是指向int的指针,c的类型是int的array.("图片"逻辑由数组扩展,因为c[3]中的3告诉我们数组的大小,而不是显示c的用法示例.因此,这个类比并不完美.)

(这也是为什么编写int *a比编写int* a更适合C和C++语法;形式语法先绑定*a,然后再绑定int.)

脚注

1Kernighan和Ritchie在1978年The C Programming Language年第90页告诉我们:

指针px的声明是新的.

int *px;

用作助记符;它表示组合*pxint,也就是说,如果px出现在上下文*px中,则它等同于int类型的变量.实际上,变量声明的语法模仿了变量可能出现的表达式的语法.

C++相关问答推荐

为什么这个gcc迂腐的人忽视了扩展?

C中char数组指针的问题

错误:八进制常数中的数字9无效

自定义malloc实现上奇怪的操作系统依赖行为

为什么已经设置的值在C中被重置为for循环条件中的新值?

在C中使用强制转换将uint16_t转换为uint8_t [2]是否有效?

如何将不同长度的位转换成字节数组?

仅在给定的大小和对齐方式下正确创建全局

在C++中头文件中声明外部 struct

使用scanf在C中读取和存储文件中的值

CC2538裸机项目编译但不起作用

在每种If-Else情况下执行语句的最佳方式

如何将另一个数组添加到集合中,特别是字符串?

C:如何将此代码转换为与数组一起使用?

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

';malloc():损坏的顶部大小';分配超过20万整数后

未使用sem_open正确初始化信号量

GCC认为这是一个VLA是对的吗?

使用 _Atomic float 时,MSVC 编译的代码会命中调试断言

#define X Defined(Y) 是有效的 C/C++ 宏定义吗?