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

MoS*_*She 13 c++ syntax declaration

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

int a,b,c,d;
Run Code Online (Sandbox Code Playgroud)

要么

string strA,strB,strC,strD;
Run Code Online (Sandbox Code Playgroud)

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

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

int *a,*b,*c,*d;
Run Code Online (Sandbox Code Playgroud)

和这样的引用:

int &a,&b,&c,&d;
Run Code Online (Sandbox Code Playgroud)

应该是一致的

int* a,b,c,d;
Run Code Online (Sandbox Code Playgroud)

int& a,b,c,d;
Run Code Online (Sandbox Code Playgroud)

为什么不一致?

cyc*_*130 11

这是因为C遗产.该*修改适用于变量C.所以C++设计者提出&类推适用于该变量为好,因为他们无法在不破坏C兼容性改变第一.数组语法也是如此:

int anInt, *aPointerToInt, anArrayOfInt[100];
Run Code Online (Sandbox Code Playgroud)

C++的设计和演变中 Bjarne Stroustrup表示他对此并不满意,但不得不接受它以实现C兼容性.他特别不满意这件事:

int *a[10];
Run Code Online (Sandbox Code Playgroud)

从声明中可以看出,如果a是指向数组或指针数组的指针(它是指针数组,则需要使用括号来覆盖).

当然,你总是可以用一个typedef来清理一下.

  • +1引用来源(_C++的设计和演变_) (3认同)
  • @ cyco130:http://stackoverflow.com/questions/7967594/different-between-c-syntax/7967844#7967844怎么样? (3认同)

Nat*_*ohl 10

我已经看到的最好的答案为什么*应用于变量而不是类型的事情是声明应该遵循使用的想法.

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

例如,

int *a, b;
...
*a = 42;
b = 314159;
Run Code Online (Sandbox Code Playgroud)

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

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

类比推理导致名称的声明语法镜像表达式语法的名称,其中名称通常出现...在所有这些情况下,变量的声明类似于在表达式中的用法,该表达式的类型是在头部命名的类型.宣言.

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


Sal*_*iti 7

其原因是:在现实&*在C和C++适用于可变和没有键入.

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

int *a, *b, *c, *d;
Run Code Online (Sandbox Code Playgroud)

写作int* a, b;意味着

int *a;
int b;
Run Code Online (Sandbox Code Playgroud)

出于这个原因,很多人喜欢写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
Run Code Online (Sandbox Code Playgroud)

在其他语言(如C#int[] array;)中,使用了语法.

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

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

我们正在应用*变量名.

在我看来,使用*&应用变量,即使我们90%的人更喜欢不同,也更符合其他语言.

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

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


bam*_*s53 5

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

int i;
Run Code Online (Sandbox Code Playgroud)

使用此变量看起来像i,并且该表达式会产生一个int.

int *i;
Run Code Online (Sandbox Code Playgroud)

使用此变量看起来像*i,并且该表达式会产生一个int. 这也意味着表达式i会产生指向int.

int i(void);
Run Code Online (Sandbox Code Playgroud)

使用此变量看起来像i(), 并产生一个int. 这也意味着这i是一个不接受任何内容并返回一个 的函数int

int (*i[5])();
Run Code Online (Sandbox Code Playgroud)

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

所以:

int a, *b, c(void), (*d[5])(void);
Run Code Online (Sandbox Code Playgroud)

声明了几个表达式,它们的类型都是int,但变量本身并不都是ints 。

请注意,在函数和数组的声明中,子声明实际上并不类似于变量的使用。Ieint i[5];并不意味着您在使用 时需要在方括号内放入“5” i,也不int i(int);意味着您通过说 来调用该函数i(int);。此外,结构类型变量的声明与其用途不匹配,因为您必须为每个成员变量声明表达式。

与声明变量的语法相关的是 typedef 的语法。要声明具有某种类型的 typedef,您可以使用与声明所需类型的变量相同的语法,但您要放在typedef声明前面,并且变量名称将成为 typedef 名称。

typedef int (*array_of_function_pointers[5])(void);
Run Code Online (Sandbox Code Playgroud)

C++ 添加了引用、模板、指向成员的指针和一堆东西。它在某种程度上尝试遵循旧的 C 约定,但该约定对于 C++ 添加的许多内容来说并没有真正发挥作用,因此您确实开始遇到不一致的情况。您只需要了解 C 和 C++ 之间的特质,并将其归因于不完美的结合。