为什么C ++变量声明语法不一致?

时间:2011-11-01 14:00:40

标签: c++ syntax declaration

当我声明C ++变量时,我这样做:

int a,b,c,d;

string strA,strB,strC,strD;

即,首先是类型,然后是逗号分隔的变量名列表。

但是,我声明了这样的指针:

int *a,*b,*c,*d;

和这样的引用:

int &a,&b,&c,&d;

为了保持一致,它应该是

int* a,b,c,d;

int& a,b,c,d;

为什么不一致?

5 个答案:

答案 0 :(得分:11)

这是因为C传承。 *修饰符适用于C中的变量。因此,C ++设计者将&应用于变量以及类比,因为它们无法在不破坏C兼容性的情况下更改第一个变量。数组语法也是如此:

int anInt, *aPointerToInt, anArrayOfInt[100];

C ++的设计和演变 Bjarne Stroustrup表示他对此并不满意,但不得不接受C兼容性。他特别不满意这一点:

int *a[10];

从声明中不清楚a是否是指向数组或指针数组的指针(它是一个指针数组,你需要用括号覆盖)。

当然,你总是可以使用typedef来清理一下。

答案 1 :(得分:10)

我见过的最好的答案为什么类似*之类的内容适用于变量,而不适用于类型{@ 3}}。

基本上,声明变量的方式应与使用变量的方式类似。

例如,

int *a, b;
...
*a = 42;
b = 314159;

...使用ab看起来类似于ab的声明。

C的创造者之一Dennis Ritchie甚至引用了这种行为:

  

类比推理导致了一个声明语法,用于反映名称通常出现的表达式语法的名称...在所有这些情况下,变量的声明类似于在表达式中的用法,该表达式的类型是在声明负责人。

  • Dennis Ritchie,declaration should follow use 编程语言的历史 - 第二版。 Thomas J. Bergin,Jr。和Richard G. Gibson,Jr。ACM Press(纽约)和Addison-Wesley(雷丁,马萨诸塞州),1996;国际标准书号0-201-89502-1。

答案 2 :(得分:7)

原因是:实际上C和C ++中的&*适用于变量而不适用于类型。

所以问题是如果你想要声明4指向整数的指针你应该写

int *a, *b, *c, *d;

int* a, b;表示

int *a;
int b;

出于这个原因,很多人更喜欢写int *a;而不是int* a;,只是代码风格。

当然int*是一种类型,但C语法清楚地表明在变量声明中*&将适用于变量。

出现这种情况的原因与C中的数组以这种方式声明的相同:

int a[10], b;

std::cout << typeid(a).name() << std::endl; // it will print int[10]
std::cout << typeid(b).name() << std::endl; // it will print int

在C#等其他语言中,使用了语法int[] array;

另一件事是指向函数语法的指针:

// Now we declare a variable that is a pointer to function
int (*pt2Function)(char, char) = NULL;

我们正在将*应用于变量名称。

在我看来,使用*&应用于变量,如果我们90%的人更喜欢不同的话,则与语言的其他部分更加一致。

以同样的方式,回到数组:

// Now we declare a variable that is a pointer to an array of 10 integers.
int (*arrayptr)[10];

答案 3 :(得分:4)

C对其声明有一个规则:声明模仿使用。这意味着变量的声明看起来像变量的使用方式。例如:

int i;

使用此变量看起来像i,该表达式会产生int

int *i;

使用此变量看起来像*i,该表达式会产生int。这也意味着表达式i会生成指向int的指针。

int i(void);

使用此变量看起来像i(),并产生int。这也意味着i是一个不带任何东西并返回int的函数。

int (*i[5])();

使用此变量看起来像(*i[x])(),并产生int。这也意味着*i[x]是一个返回int的函数,i[x]是指向返回int的函数的指针,而i是一个指向函数的指针数组返回int

所以:

int a, *b, c(void), (*d[5])(void);

声明了几个都具有int类型的表达式,但变量本身并非都是int

N.B。在函数和数组的声明中,子声明并不完全类似于变量的使用。即int i[5];并不意味着您在使用i时需要在方括号内放置“5”,int i(int);并不意味着您通过说{{1}来调用该函数}}。此外,结构类型变量的声明与它们的使用不匹配,因为您必须为每个成员变量声明表达式。

与声明变量的语法相关的是typedef的语法。要声明具有特定类型的typedef,可以使用与声明所需类型的变量相同的语法,但是在声明前加上i(int);,变量名称变为typedef名称。

typedef

C ++添加了引用,模板,指向成员的指针以及一堆东西。它试图在某种程度上遵循旧的C约定,但是对于C ++添加的许多东西,该约定并没有真正起作用,所以你开始得到不一致。你只需要学习这些特性,并将其归结为C和C ++之间不完美的结合。

答案 4 :(得分:2)

C ++从C继承了这种语法.K&amp; R书(§5.1)说表达式

int *ip, **ipp;

意图是助记符(即您阅读“*ip**ipp具有类型int”),他们希望它模仿使用语法。

我同意它对人类来说非常神秘且违反直觉,并且与typedef不一致,例如

typedef int* intptr;
intptr a, b; // equivalent to: int *a, *b

但它从来就不是C ++作者的决定,使用这种语法暗示语言与C兼容的选择,这就是原因。