为什么variables名前面是星号,而不是后面的types?
为什么大多数C程序员都这样命名variables:
int *myVariable;
而不是像这样:
int* myVariable;
两者都是有效的。 在我看来,星号是types的一部分,而不是variables名的一部分。 谁能解释这个逻辑?
他们是完全等效的。 但是,在
int *myVariable, myVariable2;
似乎很明显,myVariable的types为int * ,而myVariable2的types为int 。 在
int* myVariable, myVariable2;
似乎很明显,两者都是int *types,但是myVariable2没有这种types。
因此,第一种编程风格更直观。
如果以另一种方式来看, *myVariable
是int
types,这是有道理的。
因为*更接近于variables而不是types:
int* varA, varB; // This is misleading
但是,即使是最好的单行声明,对我来说似乎也是不直观的,因为*是types的一部分。 我喜欢这样做:
int* varA; int varB;
像往常一样,你的代码越小,它的可读性就越好。 ;)
我要在这里说一说, 这个问题有一个直接的答案 ,无论是variables声明还是参数和返回types,都是星号应该放在名称旁边: int *myVariable;
。 为了理解为什么,看看你如何在C中声明其他types的符号:
int my_function(int arg);
一个function;
float my_array[3]
为一个数组。
被称为声明的一般模式遵循使用 ,就是符号的types被分解成名称之前的部分,名称周围的部分以及名称周围的这些部分模仿了用来获得左边的types值:
int a_return_value = my_function(729);
float an_element = my_array[2];
和: int copy_of_value = *myVariable;
。
C ++在引用中抛出了一个扳手,因为在你使用引用的地方的语法和值types的语法是一样的,所以你可以争辩说C ++采取了与C不同的方法。另一方面,C ++保留了相同的在指针的情况下C的行为,所以引用在这方面确实是奇怪的。
在这里没有人提到的是这个星号实际上是C中的“ 解引用运算符 ”
*a = 10;
上面的这行并不意味着我要把10
赋给a
,这意味着我想把10
赋给任意a
指向的内存位置。 我从来没有见过任何人写作
* a = 10;
你有吗? 所以解引用操作符几乎总是没有空格。 这大概是为了区分它与多行打破的乘法:
x = a * b * c * d * e * f * g;
这里*e
会是误导,不是吗?
好的,下面这一行实际上是什么意思:
int *a;
大多数人会说:
这意味着a
是一个指向int
值的指针。
这在技术上是正确的,大多数人喜欢以这种方式看待/阅读,现代C标准将如何定义它(请注意,C语言本身早于所有ANSI和ISO标准)。 但这不是唯一的方法来看待它。 你也可以阅读这一行如下:
a的解除引用值是int
types的。
所以实际上这个声明中的星号也可以看作是一个解引用运算符,这也解释了它的位置。 而且a
是一个指针,根本就没有被声明,事实上它是隐含的,唯一可以实际提取的是一个指针。
C标准仅为*
运算符定义了两个含义:
- 间接运营商
- 乘法运算符
而间接只是一个单一的含义,没有额外的含义来声明一个指针,只是间接的,这就是解引用操作,它执行间接访问,所以也在一个像int *a;
这是间接访问 ( *
表示间接访问),因此上面的第二个语句比第一个语句更接近标准。
这只是一个偏好问题。
当你读代码的时候,在第二种情况下区分variables和指针是比较容易的,但是当你将一个通用types的variables和指针放在一行中时,这可能会导致混淆(这本身通常会被项目指南所阻碍,因为降低可读性)。
我更喜欢用types名称旁边的对应符号来声明指针,例如
int* pMyPointer;
一个伟大的导师曾经说过:“读它的编译器的方式,你必须。”
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
当然,这是关于常量放置的主题,但同样的规则适用于这里。
编译器将其读取为:
int (*a);
不是:
(int*) a;
如果你养成将变星放置在variables旁边的习惯,它会使你的声明更容易阅读。 它也避免了如下的不利因素:
int* a[10];
因为当你有这样的声明时它更有意义:
int *a, *b;
为了在一行中声明多个指针,我更喜欢int* a, * b;
这更直观地将“a”声明为指向整数的指针,并且当同样声明“b”时不混合样式。 就像有人说的那样,我不会在同一个声明中声明两种不同的types。
在K&R中,它们将指针操作符放在variables名称的旁边,而不是types。 我个人认为这本书是最终的C权威/圣经。 也来自Objective-C背景,我遵循*名称约定。
我已经在CP中回答了一个类似的问题,而且因为没有人提到过,所以在这里我必须指出, C是一种自由格式的语言 ,无论您select何种样式,语法分析器都可以区分每个标记。 C的这个特性导致了一个非常特殊的比赛,叫做C混淆比赛 。