我听过很多关于这一行的消息:void typedef name
。
编译良好:
void typedef name;
int main(){}
void
到底是什么意思?这难道不意味着某些东西只是空虚的吗?如何在像typedef
这样的关键字之前使用它?void
不是无效使用吗?这似乎和做一样:
typedef void name;
并使name
成为void
的别名。编译器是否重新排列typedef
和void
?
我认为void
只能用于以下功能:
void func();
但是void
可以用来做什么?它意味着什么?即使void typedef name
不是函数声明,它是如何工作的?
typedef
在语法上是存储类说明符,其中声明说明符中只能有一个(_Thread_local除外(。
声明说明符的顺序(声明的"T"部分,而不是"D"部分(是最自由的,即const char
,而不是char const
。但是也使用例如CCD_ 15。
从语义上讲,typedef
创建";仅";给定类型的同义词。因此,是的,编译器确实重新排列(解析该声明(
当void x;
声明给出错误时,它使用typedef
进行编译。取决于您以后如何使用它,例如用于指针:
typedef void _0;
_0 *y;
即使_0* y
相同,也不能切换*
的位置。它在声明符("D"(的左边,给出具有所有空白变化的T*D
。
在C中,声明是一个或多个声明说明符,后面是带有可选初始值设定项的宣告符列表。人类倾向于按特定顺序编写说明符,但C语法允许按任何顺序编写说明符。它们是:
-
存储类说明符:
typedef
、extern
、static
、_Thread_local
、auto
和register
-
类型说明符:
void
、char
、short
、int
、long
、float
、double
、signed
、unsigned
、_Bool
、_Complex
、_Atomic (type-name)
,以及结构说明符、并集说明符、枚举说明符和(以前定义的(typedef名称 -
类型限定符:
const
、restrict
、volatile
和_Atomic
-
函数说明符:
inline
和_Noreturn
-
对齐说明符:
_Alignas (type-name)
和_Alignas (constant-expression)
有一些关于各种说明符可能出现的次数的规则,以及关于哪些说明符可能与哪些说明符一起出现的规则。然而,它们出现的顺序并没有规定。因此,以上所有内容都可以根据需要进行重新排列。这包括将一些说明符放在我们通常分组在一起的类型说明符之间,例如const long static int _Alignas (double) long signed x;
,它以一种令人困惑的方式包含signed long long int
。编译器不在乎;它会记住所有的事情并想清楚。
因此CCD_ 50与CCD_;它将CCD_ 52定义为CCD_。
从上面的列表中可以看出,void
是类型说明符。很简单,它指定了一个类型。该类型被定义为不完整,这意味着它没有定义的大小。此外,C标准规定它不能完成;不能给它任何大小。它没有大小的事实有助于防止程序意外引用void
对象:如果p
是void *
,那么*p
将引用void
对象,如果程序实际上试图访问它,编译器应该发出诊断消息。
补充说明
声明中的声明符是围绕声明的标识符构建的:
- 一个普通的标识符
-
声明符跟在括号
[
和]
后面,表示一个数组,括号内有各种选项 -
声明符,后跟括号
(
和)
,表示函数,括号内有各种选项 - 前面有
*
的声明符,用于指示指针,在*
和声明符之间可以选择带有类型限定符- 括号内的声明符,用于覆盖混合指针和数组等的复杂宣告符中的默认分组