void是C中的数据类型吗?
Posted
技术标签:
【中文标题】void是C中的数据类型吗?【英文标题】:Is void a data type in C? 【发布时间】:2011-03-30 02:20:22 【问题描述】:void
是 C 编程语言中的数据类型吗?如果是这样,它可以存储什么类型的值?如果我们有int
、float
、char
等来存储值,为什么需要void
?虚空的范围是多少?
【问题讨论】:
它完全没有任何意义,甚至不是原始 K&R pre-ansi C 的一部分。一些白痴认为myFunction() /* ... */
看起来太整洁了,只需要添加一些 BS void myFunction(void) /* ... */
- 我认为还有其他更简洁的选择,以防您无法忍受使用char *
,这是在 void 之前声明“通用”指针的常用方法。
@ChristofferBubach 但function(void)
!= function()
在 C 中,因为在前者中您可以完全不输入参数,而在后者中您可以输入任何参数:geeksforgeeks.org/difference-int-main-int-mainvoid(C++ 中除外,两者都意味着函数完全不带参数)
我不得不认为任何 c 编译器都能够很容易地检测到参数使用或外部链接,以便使用最有效的调用入口点。使用“...”或新的可变参数类型清楚地指示未知数量的参数的反向语法会更简洁,并且在仅使用空括号声明时仍然允许自动检测。这基本上就是新代码的外观,所以为什么还要添加 void,编译器在记账符号及其用法方面真的这么糟糕吗?
【参考方案1】:
Void 被认为是一种数据类型(出于组织目的),但它基本上是一个关键字,用作放置数据类型的占位符,表示“无数据”。
因此,您可以将不返回值的例程声明为:
void MyRoutine();
但是,你不能像这样声明一个变量:
void bad_variable;
但是,当用作指针时,则具有不同的含义:
void* vague_pointer;
这声明了一个指针,但没有指定它指向的数据类型。
【讨论】:
并且由于您没有指定 void 指针指向的内容,因此您无法对其执行数学运算。编译器不知道将指针移动多远才能到达内存中的下一项。void MyRoutine();
是 C99 弃用的旧式 (K&R C) 函数声明,而不是原型。这应该是void MyRoutine(void);
。
@fennec:如果您使用 gcc,则可以对 void*
的值执行算术运算,它通过假装 sizeof (void) == 1
来支持它作为扩展。 (我个人认为这很不幸。)
以下定义没有问题:extern void foo;
@AnT:不完整的结构类型没有all 与void
相同的属性。它们都是不完整的类型,但例如所有指向结构的指针类型都具有相同的表示; void*
可能有也可能没有相同的表示。此外,可以完成不完整的结构类型; void
不能。【参考方案2】:
是的,void
是一种类型。是否为 data 类型取决于您如何定义该术语; C 标准没有。
该标准确实定义了术语“对象类型”。在 C99 及更早版本中; void
不是对象类型;在 C11 中,它是。在标准的所有版本中,void
是一个不完整类型。 C11 中的变化是不完整类型现在是对象类型的子集。这只是术语的变化。 (另一种类型是函数类型。)
C99 6.2.6 第 19 段说:
void 类型包含一组空值;这是一个不完整的 无法完成的类型。
C11 标准稍微改变了措辞:
void 类型包含一组空值;它是一个不完整的对象类型 无法完成。
这反映了 C11 对“对象类型”定义的改变,包括不完整类型;它并没有真正改变 void
类型的性质。
void
关键字也可以在其他一些上下文中使用:
作为函数原型中唯一的参数类型,如int func(void)
,表示该函数没有参数。 (C++ 对此使用空括号,但它们在 C 中表示其他含义。)
作为函数的返回类型,如void func(int n)
,表示该函数不返回结果。
void*
是一种指针类型,没有指定它指向什么。
原则上,所有这些用法都是指 type void
,但您也可以将它们视为恰好使用相同关键字的特殊语法。
【讨论】:
int func()和int void()有什么区别 @funky-nd:再看一遍我怀疑你是想问int func()
和int func(void)
之间的区别。不同之处在于后者是一个 prototype,它指定函数不接受任何参数。前者是旧式函数声明,它没有指定它期望的参数。 (很少有使用旧式函数声明的充分理由。)【参考方案3】:
C 标准说void
是不能完成的不完整类型(与其他可以完成的不完整类型不同)。这意味着您不能将sizeof
运算符应用于void
,但您可以有一个指向不完整类型的指针。
【讨论】:
Сonsideextern void x;
。 1) 如果x
可以在“C 之外”完成(例如在asm 中),那么为什么&x
无效? 2)x
上是否有有效操作?
@pmor 如果完成发生在“C 之外”,这意味着编译器不知道它。不是&x
是无效的,void x
是无效的,以及随后的所有内容。至于2),应该有,例如将两个void x
赋值给void y
,但不可能,因为编译器不知道x 和y 的大小。
我的意思是“&x
无效在这种情况下(即如果x
被声明为extern void x;
)”。
Clang 和 GCC 都接受 extern const void x; const void* p = &x;
下的 -std=c11 -pedantic -Wall -Wextra
。此代码有效吗?如果不是,他们为什么 Clang 和 GCC 决定接受它?以上是关于void是C中的数据类型吗?的主要内容,如果未能解决你的问题,请参考以下文章
C 语言数据类型本质 ( void 关键字作用 | 数据类型封装 | 作为 参数 或 返回值 代表无 | void* 指针赋值与被赋值 | void 类型变量不存在 )