为什么解除引用运算符(*)也用于声明指针?

时间:2011-12-31 00:56:49

标签: c++ pointers syntax dereference notation

我不确定这是否是一个正确的编程问题,但它总是困扰我,我想知道我是否是唯一的。

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

请考虑以下事项:

void foo(int* bar)
{
}


int main()
{
    int x = 5;
    int* y = NULL;

    y = &x;
    *y = 15;     
    foo(y);

}

函数foo(int*)int指针作为参数。由于我已将y声明为int指针,因此我可以将y传递给foo,但在第一次学习C ++时,我将*符号与解除引用相关联,因此,我认为需要通过一个解除引用的int。我会尝试将*y传递给foo,这显然无效。

使用单独的运算符来声明指针会不会更容易? (或用于解除引用)。例如:

void test(int@ x)
{
}

6 个答案:

答案 0 :(得分:82)

The Development of the C Language中,Dennis Ritchie解释了他的推理:

  

第二项创新,最明显地区分了C和它   前辈是这种更全面的结构,尤其是它   在声明的语法中表达...给定任何对象   类型,应该可以描述一个收集的新对象   几个进入一个数组,从函数中产生它,或者是一个指针   它.... [这] 导致了一个   声明表达式语法的名称的声明语法   通常出现名称。因此,

     

int i, *pi, **ppi;声明一个整数,一个指向整数的指针,a   指向整数指针的指针。这些声明的语法   反映了i, *pi, and **ppi都产生int类型的观察结果   在表达式中使用时。

     

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

     

在所有这些情况下声明a   变量类似于在类型为1的表达式中的用法   在声明的头部命名

     

语法意外导致了感知的复杂性   语言。在C语言中拼写为*的间接运算符在语法上是一个   一元前缀运算符,就像在BCPL和B中一样   简单的表达式,但在更复杂的情况下,括号是   需要指导解析。例如,要区分   间接通过调用a函数返回的值   由指针指定的函数,写一个*fp() and (*pf)()   分别。表达式中使用的样式贯穿始终   声明,因此可以声明名称

     

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

     

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

     

发生了两种效应。   最重要的是,C有一套相对丰富的描述方式   类型(比较,与Pascal相比)。语言声明为   例如,表达为C-Algol 68 - 描述同样难以对象的对象   理解,仅仅因为对象本身很复杂。一个   第二个效果归功于语法的细节。 C中的声明必须是   阅读“内而外”的风格,很多人都难以理解。   Sethi [Sethi 81]观察到许多嵌套   如果间接,声明和表达式会变得更简单   运算符已被视为后缀运算符而不是前缀,但是   到那时为时已晚,无法改变。

答案 1 :(得分:13)

如果你这样写的原因更清楚:

int x, *y;

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

答案 2 :(得分:9)

这是一个早于C ++的语言决策,因为C ++从C继承了它。我曾经听说过,动机是声明和使用是等价的,即给定声明int *p;表达式{ {1}}类型为*p,与int int i;类型i类型相同。

答案 3 :(得分:6)

因为委员会以及那些在标准化之前几十年内开发C ++的委员会决定 *应保留其原有的三种含义

  • 指针类型
  • 解除引用运算符
  • 乘法

您建议*(以及类似地,&)的多重含义令人困惑,这是正确的。多年来我一直认为它是理解语言新人的重要障碍。


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

向后兼容性是根本原因......最好在新环境中重用现有符号,而不是通过将以前不是运算符转换为新意义来破坏C程序。


为什么不为C选择另一个符号?

这是不可能确定的,但有几个论点可以 - 并且已经 - 制作。最重要的是:

  

当[an]标识符出现在与声明符相同的表达式中时,它会生成指定类型的对象。 {K& R,p216}

这也是为什么C程序员倾向于 [citation needed] 更喜欢将它们的星号与右边而不是左边对齐,即:

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

虽然这两种语言的程序都有不同的变化。

答案 4 :(得分:5)

Expert C Programming: Deep C Secrets的第65页包含以下内容:然后,有一个C哲学,即对象的声明应该看起来像它的用法。

The C Programming Language, 2nd edition (aka K&R)的第216页包括:声明器被读作断言,当它的标识符出现在与声明符相同的表达式中时,它会生成一个指定类型的对象。

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

答案 5 :(得分:3)

哈哈,我感觉到你的痛苦,我遇到了同样的问题。

我认为指针应声明为&int,因为指针是某事物的地址是有道理的。

过了一段时间我自己想,C中的每一种类型都要读向后,比如

int * const a

适合我

a constant something, when dereferenced equals an int取消引用的东西必须是指针。