C、C++ 和 C# 中的 void 是啥意思?
Posted
技术标签:
【中文标题】C、C++ 和 C# 中的 void 是啥意思?【英文标题】:What does void mean in C, C++, and C#?C、C++ 和 C# 中的 void 是什么意思? 【发布时间】:2010-11-05 19:04:41 【问题描述】:希望了解有关“void”一词的来源以及为什么将其称为 void 的基本知识。这个问题的目的是帮助那些没有 C 经验的人,突然开始研究基于 C 的代码库。
【问题讨论】:
这个问题混合了 3 种语言......这个遗留问题应该分成 3 个不同的问题。 【参考方案1】:意思是“没有价值”。您使用void
表示函数不返回值或它没有参数或两者兼而有之。与英语中单词 void 的典型用法非常一致。
【讨论】:
【参考方案2】:在 C# 中,您可以使用 void 关键字来指示方法不返回值:
public void DoSomeWork()
// Some work
【讨论】:
大多数人没有意识到 void 映射到 System.Void 结构-msdn.microsoft.com/en-us/library/system.void.aspx【参考方案3】:Void 仅用于方法签名。对于返回类型,这意味着该方法不会向调用代码返回任何内容。对于参数,这意味着没有参数传递给方法。
例如,
void MethodThatReturnsAndTakesVoid(void)
// Method body
在C#中我们可以省略参数的void,可以将上面的代码写成:
void MethodThatReturnsAndTakesVoid()
// Method body
Void 不应与 null 混淆。 Null 表示地址在堆栈上的变量,而该地址在堆上的值为空。
【讨论】:
【参考方案4】:表示函数中没有返回值。
有些语言有两种子例程:过程和函数。过程只是一个操作序列,而函数是一个返回结果的操作序列。
在 C 及其衍生物中,两者之间的区别并不明确。一切基本上都是一个函数。 void
关键字表明它不是“实际”函数,因为它不返回值。
【讨论】:
【参考方案5】:void 表示您不会从函数或方法返回任何值。
【讨论】:
【参考方案6】:基本上它的意思是“没有”或“没有类型”
void 的使用有 3 种基本方式:
函数参数:int myFunc(void)
-- 该函数什么都不带。
函数返回值:void myFunc(int)
-- 函数不返回任何内容
通用数据指针:void* data
-- 'data' 是指向未知类型数据的指针,不能被解引用
注意:函数参数中的 void
在 C++ 中是可选的,因此 int myFunc()
与 int myFunc(void)
完全相同,在 C# 中完全省略了它。它始终是返回值所必需的。
【讨论】:
参数列表中的void在C++中是可选的,见***.com/questions/416345/… 我会使用“no type”而不是“no size” @Earwicker 和 kjetijor,这两个都是我辩论过的好点,但我失眠的头脑需要帮助;)谢谢。 不同意,但 void 的另一个用途是在“强制转换为 void”技巧中抑制未使用值的警告。这有点牵强,因为它与编译器解释事物的方式并不真正对应,但您可以将其解释为“我使用这个值什么都不做”。 在 C++ 中,参数列表中的 void 是可选的。但是,在 C 中,它不是可选的:foo() 表示它接受任意数量的任何类型的参数,而 foo(void) 表示它接受零个参数。【参考方案7】:Void 表示所有三种语言的函数的返回类型都不需要值。
【讨论】:
【参考方案8】:void有两种使用方式:
void foo(void);
或
void *bar(void*);
第一个表示没有参数被传递或没有参数被返回。
第二个告诉编译器没有与数据关联的类型,这意味着在将其转换为已知类型之前,您无法使用指向的数据。
例如,当您的接口调用无法提前知道参数的函数时,您会看到void*
被大量使用。
例如,在Linux kernel 中,当推迟工作时,您将设置一个稍后运行的函数,方法是给它一个指向要运行的函数的指针和一个指向要传递给功能:
struct _deferred_work
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
deferred_work;
然后一个内核线程遍历一个延迟工作列表,当它到达这个节点时它有效地执行:
bar(somedata);
然后在 bar 你有:
void bar(void* mydata)
int *data = mydata;
/* Do something with data */;
【讨论】:
【参考方案9】:void的三种使用案例:
函数签名。 void foo(int bar)
不返回值。 int bar(void)
不接受任何参数,但这通常用空参数列表表示:int bar()
。此处void关键字的用法与其英文含义相对应。
通用***类型指针void *
,指向未指定的数据,无法取消引用。这里void的含义与void的其他含义不同:universal type vs. no type。
在诸如(void) new Foo(this)
之类的强制转换中表示有意丢弃返回值。这里的关键字用法也符合它的英文含义。
@Gerald 已涵盖案例 1 和案例 2,但案例 3 尚未解决。
【讨论】:
【参考方案10】:Void 相当于 Visual Basic 的 Sub。
【讨论】:
仅作为返回类型。我可以想到 void 的另外三种用途:void arguments(函数不接受任何内容)、void pointers(未指定指针类型)和 void casts(丢弃值)。【参考方案11】:如果您要向初学者解释这个概念,使用类比可能会有所帮助。在所有这些情况下使用 void 的含义类似于一本书中的一页,其中包含以下词语:“此页故意留白”。这是为了区分编译器应该标记为错误的内容与故意留空的类型,因为这是您想要的行为。
它总是出现在您通常希望看到类型出现的代码中,例如返回类型或指针类型。这就是为什么在 C# 中,void 映射到一个实际的 CLR 类型 System.Void,因为它本身就是一个类型。
一些编程语言从未发展出 void 的概念,就像一些人类文化从未发明过数字零的概念一样。 Void 代表编程语言的进步,就像零的概念代表人类语言一样。
【讨论】:
只是关于你最后一句话的注释 - 请记住,这仅适用于静态类型语言。动态类型语言不需要 void,因为它们的方法可能根本不返回任何东西——“void”暗示着没有返回任何东西。 更正我的上一条评论 - 我的意思是说最后一段(不是句子)。【参考方案12】:我一直认为它的意思是缺席。以下是 C 语言中与 absent
的这种用法相匹配的四种情况R f(void)
- 函数参数不存在
void f(P)
- 返回值不存在
void *p
- 所指向的类型是不存在
(void) p
- 值的使用不存在
其他 C 后代将它用于其他事情。 D 编程语言将它用于初始化器不存在
的情况T t = void;
- 初始化值不存在
【讨论】:
(void)p
是做什么的?我不太明白你所说的“没有使用价值”是什么意思。
@Yashas 如果有人也对(void) var;
声明感到困惑,我在***.com/q/21045615 找到了详细答案。
也许更新Rust(如果相关)? - 作为新的竞争者。【参考方案13】:
将 void 视为“空结构”。让我解释一下。
每个函数都接受一系列参数,其中每个参数都有一个类型。实际上,我们可以将参数打包成一个结构体,结构体槽位对应参数。这使得每个函数都只有一个参数。类似地,函数产生一个结果,它有一个类型。它可以是布尔值,也可以是浮点数,也可以是包含任意其他类型值集的结构。如果我们想要一个具有多个返回值的语言,很容易坚持将它们打包成一个结构。事实上,我们总是可以坚持一个函数返回一个结构。现在每个函数都只接受一个参数,并且只产生一个值。
现在,当我需要一个产生“无”值的函数时会发生什么? 好吧,考虑一下当我形成一个具有 3 个插槽的结构时得到的结果: 持有 3 个值。当我有 2 个插槽时,它包含两个值。当它 有一个槽,一个值。当它的槽位为零时,它持有......呃, 零值或“无”值”。所以,我可以想到一个返回 void 的函数 作为返回一个不包含值的结构。你甚至可以决定“无效” 只是空结构所表示的类型的同义词, 而不是语言中的关键字(也许它只是一个预定义的类型:)
同样,我可以将不需要值的函数视为接受空结构,例如“void”。
我什至可以通过这种方式实现我的编程语言。传递一个空值 占用零字节,因此传递 void 值只是传递的一种特殊情况 其他任意大小的值。这使得编译器很容易处理 “无效”的结果或论点。你可能想要一个语言功能 可以丢弃函数结果;在 C 中,如果您调用非 void 结果 函数 foo 在以下语句中: 富(...); 编译器知道 foo 会产生结果并简单地忽略它。 如果 void 是一个值,那么它可以完美地工作,现在是“程序”(它们是 只是具有 void 结果的函数的形容词)只是微不足道的特殊 一般函数的情况。
Void* 有点好笑。我不认为 C 设计者在 以上方式;他们刚刚创建了一个关键字。该关键字在有人可用时可用 需要一个指向任意类型的点,因此 void* 作为 C 中的成语。 如果您将 void 解释为空结构,它实际上工作得很好。 void* 指针是该空结构所在位置的地址 被放了。
对于其他类型 T,从 void* 到 T* 的转换,也适用于这个视角。 指针转换是一种完整的作弊方法,适用于大多数常见架构,以利用以下事实:如果复合类型 T 在其存储布局中具有子类型 S 的元素物理放置在 T 的开头,则将 S* 转换为 T* 和反之亦然,使用相同的物理机器地址往往会解决问题,因为大多数机器指针都有一个单一的表示。将类型 S 替换为 void 类型会产生完全相同的效果,因此可以与 void* 进行强制转换。
PARLANSE 编程语言非常接近地实现了上述想法。 我们在它的设计上搞砸了,并没有密切关注“无效”作为回报 类型,因此具有过程的语言关键字。它大多只是一个简单的 语法发生了变化,但这是您一旦获得就无法解决的事情之一 一种语言的大型工作代码。
【讨论】:
【参考方案14】:Void 是一个不完整的类型,根据定义,它不能是左值。这意味着它不能被赋值。
所以它也不能保持任何价值。
【讨论】:
以上是关于C、C++ 和 C# 中的 void 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章