为什么大多数C程序员这样命名变量:
int *myVariable;
而不是像这样:
int* myVariable;
两者都成立。在我看来,星号是类型的一部分,而不是变量名的一部分。有人能解释一下这个逻辑吗?
为什么大多数C程序员这样命名变量:
int *myVariable;
而不是像这样:
int* myVariable;
两者都成立。在我看来,星号是类型的一部分,而不是变量名的一部分。有人能解释一下这个逻辑吗?
当前回答
当你在一个语句中初始化和赋值一个变量时,例如:
int *a = xyz;
将xyz的值赋给a,而不是*a。这使得
int* a = xyz;
一个更一致的符号。
其他回答
一位伟大的大师曾经说过:“你必须按照编译器的方式来阅读它。”
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
虽然这是关于const放置的主题,但同样的规则也适用于这里。
编译器将其解读为:
int (*a);
而不是:
(int*) a;
如果您养成了将星号放在变量旁边的习惯,它将使您的声明更容易阅读。它还避免了一些碍眼的东西,比如:
int* a[10];
——编辑——
为了准确解释我说它被解析为int (*a)时的意思,这意味着*与a的绑定比与int的绑定更紧密,就像在表达式4 + 3 * 7中,3与7的绑定比与4的绑定更紧密,因为*的优先级更高。
为了对ascii艺术表示歉意,解析int *a的A.S.T.大致如下所示:
Declaration
/ \
/ \
Declaration- Init-
Secifiers Declarator-
| List
| |
| ...
"int" |
Declarator
/ \
/ ...
Pointer \
| Identifier
| |
"*" |
"a"
如图所示,*与a的绑定更紧密,因为它们的共同祖先是Declarator,而您需要沿着树一直向上走到Declaration才能找到涉及int的共同祖先。
在这里,我要大胆地说,对于变量声明以及参数和返回类型,这个问题都有一个直接的答案,那就是名称后面应该有星号:int *myVariable;。要理解其中的原因,看看如何在C语言中声明其他类型的符号:
Int my_function(Int arg);对于一个函数;
为数组浮动my_array[3]。
一般的模式,被称为声明遵循使用,是一个符号的类型被分为名称前的部分和名称周围的部分,而名称周围的这些部分模仿了你用来获得左侧类型值的语法:
Int a_return_value = my_function(729);
浮动an_element = my_array[2];
and: int copy_of_value = *myVariable;
c++在引用方面遇到了麻烦,因为使用引用的语法与值类型的语法是相同的,所以你可能会说c++采取了与C不同的方法。另一方面,c++在指针的情况下保留了与C相同的行为,所以引用在这方面确实是一个奇怪的例子。
喜欢int* x的人;试图将他们的代码强行带入一个虚构的世界,在这个世界中,类型在左边,标识符(名称)在右边。
我说“虚构的”是因为:
在C和c++中,一般情况下,声明的标识符被类型信息包围。
这听起来可能很疯狂,但你知道这是真的。下面是一些例子:
int main(int argc, char *argv[]) means "main is a function that takes an int and an array of pointers to char and returns an int." In other words, most of the type information is on the right. Some people think function declarations don't count because they're somehow "special." OK, let's try a variable. void (*fn)(int) means fn is a pointer to a function that takes an int and returns nothing. int a[10] declares 'a' as an array of 10 ints. pixel bitmap[height][width]. Clearly, I've cherry-picked examples that have a lot of type info on the right to make my point. There are lots of declarations where most--if not all--of the type is on the left, like struct { int x; int y; } center.
这种声明语法源于K&R希望声明能够反映用法。阅读简单的声明是凭直觉的,而阅读更复杂的声明可以通过学习右-左-右规则(有时称为螺旋规则或只是右-左规则)来掌握。
C语言非常简单,许多C程序员都接受这种风格,并将简单的声明写成int *p。
在c++中,语法变得有点复杂(有类、引用、模板、枚举类),作为对这种复杂性的反应,您将在许多声明中看到将类型与标识符分离的更多努力。换句话说,如果你检查了大量的c++代码,你可能会看到更多的int* p风格的声明。
在任何一种语言中,你都可以将类型放在变量声明的左边,方法是(1)永远不要在同一个语句中声明多个变量,以及(2)使用typedefs(或别名声明,讽刺的是,它将别名标识符放在类型的左边)。例如:
typedef int array_of_10_ints[10];
array_of_10_ints a;
因为当你有这样的声明时更有意义:
int *a, *b;
它们是完全相等的。 然而,在
int *myVariable, myVariable2;
显然,myVariable的类型是int*,而myVariable2的类型是int。 在
int* myVariable, myVariable2;
很明显,两者都是int*类型,但这是不正确的,因为myVariable2的类型是int。
因此,第一种编程风格更直观。