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 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的“class”是啥意思啊?讲下其作用及用法。麻烦了

C中的“void (*f)(void)”是啥意思

C++ 中的 :: 是啥意思? [复制]

空虚是啥意思? [复制]

C中的'static void *'是啥意思? [复制]

c#中委托的作用是啥?