void 是 C 语言中的一个关键字,它的字面意思是“空的”或“无返回值”,在函数的上下文中,void 主要有两个用途:

(图片来源网络,侵删)
- 声明一个没有返回值的函数。
- 声明一个不接受任何参数的函数。
下面我们分别对这两种用途进行深入探讨。
void 作为函数的返回类型
这是 void 最常见的用法,当一个函数执行完毕后,不需要向调用它的代码返回任何值时,我们就使用 void 作为其返回类型。
a. 基本概念
- 有返回值的函数:
int add(int a, int b),这个函数计算两个整数的和,并通过return语句将结果(一个整数)返回给调用者,调用者可以接收这个返回值,int sum = add(3, 5);。 void函数:void print_hello(),这个函数的功能是在屏幕上打印 "Hello, world!",它执行一个动作,但不需要返回任何计算结果。
b. 语法
return_type function_name(parameter_list) {
// 函数体
// ...
// return_type 是 void,这里可以写 return; (可选) 或者不写 return
}
当 return_type 是 void 时,函数体内部可以选择使用 return; 语句来立即终止函数的执行,并返回到调用点,但因为没有要返回的值,return 后面不能跟任何表达式。
c. 示例
#include <stdio.h>
// 这是一个 void 函数,它只负责打印信息,不返回任何值
void print_greeting(const char* name) {
printf("你好, %s! 欢迎来到 C 语言世界,\n", name);
// 执行到这里函数会自然结束并返回
}
// 另一个 void 函数,使用 return 提前退出
void check_age(int age) {
if (age < 0) {
printf("错误:年龄不能为负数,\n");
return; // 提前结束函数,不再执行下面的 printf
}
printf("你的年龄是: %d\n", age);
}
int main() {
// 调用 void 函数
print_greeting("张三");
print_greeting("李四");
printf("---\n");
check_age(25);
check_age(-5); // 会触发提前 return
// 尝试接收 void 函数的返回值 (这是错误的!)
// int result = print_greeting("王五"); // 编译器会报错
return 0;
}
关键点:

(图片来源网络,侵删)
void函数不能将它的结果赋值给一个变量,因为它没有结果。void函数不能在表达式中使用,if (print_greeting("..."))是错误的。
void 作为函数的参数列表
当一个函数不需要接收任何参数时,我们可以在参数列表中使用 void 来明确地表示这一点。
a. 基本概念
在 C 语言中,一个空的参数列表 在不同的标准下有不同的含义:
- 在 C89/ANSI C 标准中, 表示函数可以接受任意数量的任意类型的参数(这被称为“K&R 风格”或“未指定参数列表”)。
- 在 C99 及之后的标准中, 明确表示函数不接受任何参数。
为了代码的清晰和可移植性,最佳实践是当你想表达“无参数”时,显式地使用 void。
b. 语法
return_type function_name(void) {
// 函数体
}
c. 示例
#include <stdio.h>
#include <stdlib.h> // 用于 rand() 和 srand()
#include <time.h> // 用于 time()
// 这个函数不接受任何参数,但会返回一个随机整数
int generate_random_number(void) {
// 注意:为了让 rand() 每次运行结果不同,通常需要先调用 srand()
// srand(time(NULL)); // 通常在 main 函数中调用一次即可
return rand() % 100; // 返回 0 到 99 之间的随机数
}
// 一个典型的 void 函数,既无返回值,也无参数
void system_status(void) {
printf("系统正在运行...\n");
printf("所有服务正常,\n");
}
int main() {
// 初始化随机数种子
srand(time(NULL));
system_status(); // 调用无参数的函数
int my_random_number = generate_random_number(); // 调用无参数但有返回值的函数
printf("生成的随机数是: %d\n", my_random_number);
// 尝试向一个 void 参数的函数传递参数 (这是错误的!)
// system_status(123); // 编译器会报错,因为函数不接受参数
return 0;
}
关键点:

(图片来源网络,侵删)
void在参数列表中明确地告诉程序员和编译器:“这个函数不需要任何参数”。- 这防止了意外的参数传递,增强了代码的类型安全性。
void 指针 (void *)
虽然不直接是 void function 的一部分,但 void 指针是 void 关键字的另一个极其重要的用途,值得了解。
void * 是一种通用的指针类型,它可以指向任何类型的数据。
a. 特点
- 通用性:
void *可以被赋值为任何类型的指针,无需强制类型转换。 - 间接性:
void *指针不能直接解引用(即不能使用 操作符来访问它指向的值),因为它编译器不知道这个内存单元里存储的是什么类型的数据。 - 类型转换:在使用
void *指针之前,必须先将其强制转换为目标类型的指针。
b. 示例
#include <stdio.h>
#include <string.h>
// 一个通用的内存拷贝函数,使用 void* 指针
void my_memcpy(void* dest, const void* src, size_t n) {
// 将 void* 转换为 char*,因为 char 的大小是 1 字节,
// 这样可以逐字节地拷贝内存
char* d = (char*)dest;
const char* s = (const char*)src;
for (size_t i = 0; i < n; i++) {
d[i] = s[i];
}
}
int main() {
int a = 10;
int b;
// my_memcpy 接收 void* 指针,可以处理任何类型的数据
my_memcpy(&b, &a, sizeof(int));
printf("拷贝后的整数值: %d\n", b); // 输出: 拷贝后的整数值: 10
char str1[] = "Hello";
char str2[50];
my_memcpy(str2, str1, strlen(str1) + 1); // +1 用于拷贝字符串结束符 '\0'
printf("拷贝后的字符串: %s\n", str2); // 输出: 拷贝后的字符串: Hello
return 0;
}
像 C 标准库中的 memcpy, memset, malloc 等函数都广泛使用了 void * 指针,这使得它们能够以非常通用的方式操作内存。
| 用法 | 含义 | 示例 | 关键点 |
|---|---|---|---|
void function() |
函数无返回值,无参数 | void do_nothing(void) {} |
明确表示函数无参,是现代 C 的最佳实践。 |
void function(...) |
函数无返回值,有参数 | void print(int n) {} |
函数执行一个操作,但不返回值给调用者。 |
int function(void) |
函数有返回值,无参数 | int get_version(void) { return 1; } |
void 在参数列表中明确表示无参。 |
void * |
通用指针 | void* p = &some_variable; |
可以指向任何类型,但使用前必须强制转换。 |
理解 void 在函数中的这两种核心用法,是写出清晰、健壮且符合现代 C 语言规范的代码的基础。
- 用
void作为返回类型,表示“不返回任何东西”。 - 用
void作为参数列表,表示“不接受任何东西”。
