C 声明遵循通常被描述为“声明模仿使用”的约定。声明的结构与代码中表达式的结构匹配(尽可能接近)。
例如,假设您有一个指向名为 p 的 int 的指针。要访问存储在指向对象中的值,我们使用一元 * 运算符取消引用指针,如下所示:
printf( "value of what p points to is %d\n", *p );
表达式*p的类型为int,所以我们将p声明为
int *p;
这表明变量p 具有“指向int 的指针”类型,因为在声明器中p 和取消引用运算符* 的组合 产生了一个类型为的表达式int。
这就是为什么在 C 中不使用 & 运算符声明指针的主要原因,因为 表达式 &p 的类型不会是 int。
C++ 使用一元& 运算符来声明引用,这与指针不同:
void foo( int &ref )
{
ref = new_value(); // writes a new value to the actual parameter ref references
}
int main( void )
{
int x = 1;
std::cout << "x before foo = " << x << std::endl;
foo( x );
std::cout << "x after foo = " << x << std::endl;
return 0;
}
引用破坏了这个系统 - 没有&ref 表达式 类型为int,它只是注意到ref 解析为与其他标识符相同的对象。
C 声明由两部分组成 - 声明说明符 序列(存储类说明符、类型限定符、类型说明符)后跟一系列(可能已初始化) 声明符。指针性、数组性和函数性在声明器中指定:
declaration specifiers declarators
| |
+--------------------+----------------+ +--------+--------+
| | | |
static const volatile unsigned long int a[10], *p, f(void);
| | | | | | | |
| | | | | | | +––––––– function declarator
| | | | | | +––––––––––– pointer declarator
| | | | | +––––––––—–––––——–– array declarator
| | | +–––––––+––––––—+
| | | |
| | | +––––––––––––––——–––––––––––— type specifiers
| +––––––+–––––+
| |
| +–––––––––––––––––––––––––––––––––––––––––––– type qualifiers
+–––––––––––––—––––––––––––––––––––––––––––––––––––––––– storage class specifier
这很重要 - 没有“指向”类型说明符的“指针”。指针性由声明器指定。如果你写类似
int* a, b;
它会被解析为
int (*a), b;
只有a 会被声明为指针。