为什么反引用操作符(*)也用来声明一个指针?

我不确定这是否是一个适当的编程问题,但这一直是困扰着我的东西,我想知道我是否是唯一的问题。

最初学习C ++时,我理解了引用的概念,但是指针让我感到困惑。 你为什么问? 由于你如何声明一个指针。

考虑以下:

void foo(int* bar) { } int main() { int x = 5; int* y = NULL; y = &x; *y = 15; foo(y); } 

函数foo(int*)接受一个int指针作为参数。 因为我已经将yint指针,所以我可以将y传递给foo ,但是当第一次学习C ++时,我将*符号与解引用关联起来,因此我认为需要传递一个取消引用的int 。 我会尝试将*y传递给foo ,这显然不起作用。

拥有一个单独的运算符来声明一个指针会不会更容易? (或取消引用)。 例如:

 void test(int@ x) { } 

在“C语言的发展”一书中,丹尼斯·里奇这样解释他的推理:

第二个创新最清楚地区分C和它的前辈是这个更完整的types结构,尤其是它在expression语法中的expression…给定一个任何types的对象,应该有可能描述一个新的对象, ,从一个函数产生它,或者是一个指向它的指针…. [这] 导致一个声明语法的名称镜像名称通常出现的expression式语法。 从而,

int i, *pi, **ppi; 声明一个整数,一个指向一个整数的指针,一个指向一个整数指针的指针。 这些声明的语法反映了当在expression式中使用时, i, *pi, and **ppi都会产生一个inttypes。

同样, int f(), *f(), (*f)(); 声明一个函数返回一个整数,一个函数返回一个指向一个整数的指针,一个返回一个整数的函数的指针。 int *api[10], (*pai)[10]; 声明一个指向整数的指针数组,以及一个指向整数数组的指针。

在所有这些情况下,variables的声明类似于在声明头部命名的expression式中的用法

语法的事故促成了语言的复杂性。 在C语言中拼写*的间接运算符在语法上是一个一元前缀运算符,就像在BCPL和B中一样。在简单expression式中运行良好,但在更复杂的情况下,需要使用括号来指导parsing。 例如,为了区分通过函数返回的值来调用指针指定的函数,分别写入*fp() and (*pf)() 。 expression式中使用的样式贯穿于声明,所以可能会声明名称

int *fp(); int (*pf)();

在更华丽但仍然现实的情况下,情况变得更糟: int *(*pfp)(); 是指向返回指向整数的指针的函数的指针。

有两个效果发生。 最重要的是,C有相对丰富的描述types的方法(与Pascal相比)。 像C-Algol 68这样具有expression能力的语言中的声明 – 描述的对象同样很难理解,因为对象本身是复杂的。 第二个效果是由于语法的细节。 C中的声明必须以“内外”的方式阅读,很多人难以理解。 Sethi [Sethi 81]观察到,如果间接运算符被视为后缀运算符而不是前缀,那么许多嵌套的声明和expression式会变得更简单,但是到那时为时已晚。

如果你这样写,理由就更清楚了:

 int x, *y; 

也就是说,x和* y都是整数。 因此y是一个int *。

这是一个早于C ++的语言决策,因为C ++从Cinheritance了C语言。我曾经听说动机是声明和使用是等价的,也就是说,给定一个int *p;的声明int *p; expression式*pinttypes与int i;相同, expression式iinttypes的。

因为这个委员会和那些在标准化前几十年开发C ++的人决定*应该保留原来的三个含义

  • 指针types
  • 解除引用操作符
  • 乘法

你是正确的build议, * (和,同样, & )的多重含义是混淆。 多年来,我一直认为,他们是理解语言新手的重要障碍。


为什么不为C ++select另一个符号?

向后兼容性是根本原因……最好在新的上下文中重用现有符号,而不是通过将先前不是运算符翻译成新的含义来破坏C程序。


为什么不selectC的另一个符号?

当然不可能知道,但是有几个论点可以被制定。 最重要的是这样的想法:

当[an]标识符出现在与声明符相同forms的expression式中时,它将生成指定types的对象。 {K&R,p216}

这也是为什么C程序员倾向于[需要引用]倾向于将他们的星号向右而不是向左alignment,即:

 int *ptr1; // roughly C-style int* ptr2; // roughly C++-style 

尽pipe这两种语言的程序都是不同的。

专家C程序devise:深C秘密包括以下内容: 然后,有一个C的哲学,对象的声明应该看起来像它的使用。

C编程语言第2版(又名K&R)的第216页包括: 声明符被读为一个断言,当它的标识符出现在与声明符相同forms的expression式中时,它产生一个指定types的对象。

我更喜欢范德林登所说的。

哈哈,我感到你的痛苦,我也有同样的问题。

我认为一个指针应该被声明为&int因为它是有道理的,指针是一个东西的地址。

过了一段时间,我为自己想,C中的每一个types都必须反向读取

int * const a

是为了我

a constant something, when dereferenced equals an int 。 一些必须被解除引用的东西,必须是一个指针。