[英]Why is the dereference operator (*) also used to declare a pointer?
我不确定这是否是一个正确的编程问题,但它总是困扰我,我想知道我是否是唯一的。
在最初学习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)
{
}
在C语言的发展中 ,Dennis Ritchie解释了他的推理:
第二个最明显区别C与其前辈的创新是这种更全面的类型结构,尤其是它在声明语法中的表达......给定一个任何类型的对象,应该可以描述一个新的对象,它将几个聚集到一个数组中,从函数中产生它,或者是指向它的指针.... [This] 导致了一个声明语法,用于反映名称通常出现的表达式语法的名称。 从而,
int i, *pi, **ppi;
声明一个整数,一个指向整数的指针,一个指向整数指针的指针。 这些声明的语法反映了在表达式中使用i, *pi, and **ppi
都会产生int
类型的观察结果。同样,
int f(), *f(), (*f)();
声明一个返回整数的函数,一个返回指向整数的指针的函数,一个指向返回整数的函数的指针。int *api[10], (*pai)[10];
声明一个指向整数的指针数组,以及一个指向整数数组的指针。在所有这些情况下,变量的声明类似于在表达式中的用法,该表达式的类型是在声明的头部命名的类型 。
语法意外导致了语言的复杂性。 在C语言中拼写为*的间接运算符在语法上是一元前缀运算符,就像在BCPL和B中一样。这在简单表达式中很有效,但在更复杂的情况下,需要使用括号来指导解析。 例如,为了区分间接通过函数返回的值与调用指针指定的函数,分别写入
*fp() and (*pf)()
。 表达式中使用的样式贯穿于声明,因此可以声明名称
int *fp(); int (*pf)();
在更华丽但仍然现实的情况下,事情变得更糟:
int *(*pfp)();
是一个指向函数的指针,该函数返回一个指向整数的指针。发生了两种效应。 最重要的是,C有一套相对丰富的描述类型的方法(比如用Pascal比较)。 例如,像C-Algol 68那样富有表现力的语言中的声明描述同样难以理解的对象,仅仅因为对象本身很复杂。 第二个效果归功于语法的细节。 C中的声明必须以“由内而外”的方式阅读,许多人都难以理解。 Sethi [Sethi 81]观察到,如果将间接运算符作为后缀运算符而不是前缀,许多嵌套的声明和表达式会变得更简单,但到那时为时已经太晚了。
如果你这样写的原因更清楚:
int x, *y;
也就是说,x和* y都是整数。 因此y是int *。
这是一个早于C ++的语言决策,因为C ++从C继承了它。我曾经听说过,动机是声明和使用是等价的,也就是说,给出一个声明int *p;
表达式*p
的类型为int
,与int i;
方式相同int i;
表达式i
是int
类型。
因为委员会以及那些在标准化之前几十年内开发C ++的委员会决定*
应保留其原有的三个含义 :
你是正确的建议*
(和,类似地, &
)的多重含义令人困惑。 多年来我一直认为它是理解语言新手的重要障碍。
向后兼容性是根本原因......最好在新环境中重用现有符号,而不是通过将先前非运算符转换为新意义来破坏C程序。
这是不可能确定的,但有几个论点可以 - 并且已经 - 制作。 最重要的是:
当[an]标识符出现在与声明符相同的表达式中时,它会生成指定类型的对象。 {K&R,p216}
这也是为什么C程序员倾向于[引用需要]更喜欢将他们的星号与右边而不是左边对齐,即:
int *ptr1; // roughly C-style
int* ptr2; // roughly C++-style
虽然两种语言的程序都有不同的变化。
专家C编程的第65页:Deep C Secrets包括以下内容: 然后,C哲学认为对象的声明应该看起来像它的用法。
C编程语言第216页(又名K&R)包括: 声明符被读作断言,当它的标识符出现在与声明符相同的表达式中时,它产生一个指定类型的对象。
我更喜欢范德林登所说的方式。
哈哈,我感觉到你的痛苦,我有同样的问题。
我认为指针应该声明为&int
因为指针是某个东西的地址是有意义的。
过了一会儿,我为自己想,C中的每一种类型都必须向后阅读,比如说
int * const a
对我来说
a constant something, when dereferenced equals an int
。 必须被解除引用的东西必须是一个指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.