return 是 C 语言中一个至关重要的关键字,它主要有两个核心功能:

- 从函数中退出:立即终止当前函数的执行,并将程序控制权交还给调用该函数的地方。
- 返回值:将一个值(可以是变量、常量、表达式的结果等)从函数带回给调用者。
return 的基本用法
a) 无返回值的函数 (void 函数)
如果一个函数被声明为 void 类型,意味着它不返回任何值,这种情况下,return 语句只能用于提前退出函数,后面不能跟任何值。
#include <stdio.h>
void print_message() {
printf("函数开始执行...\n");
// 执行一些操作
printf("准备提前退出函数,\n");
return; // 正确,仅用于退出
// 下面的代码永远不会被执行
printf("这行不会打印,\n");
}
int main() {
print_message();
printf("main 函数继续执行,\n");
return 0;
}
b) 有返回值的函数
如果函数被声明为某种数据类型(如 int, float, char* 等),那么它必须通过 return 语句返回一个与声明类型匹配的值。
#include <stdio.h>
// 一个返回整数的函数
int add(int a, int b) {
return a + b; // 返回 a + b 的结果
}
int main() {
int result = add(5, 3);
printf("5 + 3 = %d\n", result); // 输出: 5 + 3 = 8
return 0;
}
return "OK"; 的具体含义
return "OK"; 是一个常见的用法,尤其在以下场景:
- *函数返回类型是 `charchar*` 是指向字符(字符串)的指针。
- 字符串字面量:在 C 语言中,像
"OK"这样的字符串字面量(也叫字符串常量)会被存储在程序的只读数据段中。 - 返回字符串的地址:
return "OK";实际上是返回了这个字符串"OK"在内存中的首地址。
return "OK"; 的完整含义是:“将指向字符串常量 'OK' 的内存地址返回给调用者。”

示例:一个检查函数
这是一个非常经典的模式,函数执行某个操作,成功则返回 "OK",失败则返回 "ERROR" 或其他信息。
#include <stdio.h>
// 模拟一个检查用户登录的函数
// 成功则返回 "OK",失败则返回 "ERROR"
char* check_login(const char* username, const char* password) {
// 假设正确的用户名和密码是 "admin" 和 "123456"
if (strcmp(username, "admin") == 0 && strcmp(password, "123456") == 0) {
return "OK"; // 返回指向 "OK" 字符串的指针
} else {
return "ERROR"; // 返回指向 "ERROR" 字符串的指针
}
}
int main() {
const char* status1 = check_login("admin", "123456");
printf("登录状态: %s\n", status1); // 输出: 登录状态: OK
const char* status2 = check_login("user", "wrongpass");
printf("登录状态: %s\n", status2); // 输出: 登录状态: ERROR
return 0;
}
代码解析:
char* check_login(...): 函数返回一个char*类型的指针。return "OK";:check_login函数不创建新的字符串,它只是返回了程序内部已经存在的"OK"字符串的地址,这样做非常高效,因为它避免了在内存中动态分配和复制字符串的开销。printf("%s\n", status1);:printf函数接收到一个char*指针,它会从这个地址开始打印字符,直到遇到字符串结束符\0为止。
重要注意事项(陷阱)
a) 不要返回局部变量的地址!
这是一个在 C 语言中非常常见的致命错误,如果函数内部定义了一个局部数组或变量,并在 return 时返回它的地址,结果是未定义行为。
错误示例:
#include <stdio.h>
#include <string.h>
char* get_greeting() {
char message[50] = "Hello, World!"; // message 是一个局部数组
return message; // 危险!message 在函数结束时会被销毁
}
int main() {
char* greeting = get_greeting();
// get_greeting 函数的栈帧已经被销毁,message 的内存可能已被覆盖或回收
printf("收到的信息: %s\n", greeting); // 输出可能是乱码,程序可能崩溃
return 0;
}
为什么会出错?
局部变量存储在栈上,当 get_greeting() 函数执行完毕,它的栈帧会被销毁,message 数组占用的内存就被释放了,虽然 greeting 指针仍然保存着那个地址,但那块内存已经不再属于你的程序,任何访问它的行为都是危险的。

b) 如何正确返回字符串?
如果你需要在函数内部创建并返回一个字符串,你有两种安全的方式:
-
使用
static关键字:将局部变量声明为static,这样它就不会存储在栈上,而是存储在静态数据区,生命周期与程序相同。char* get_greeting_safe() { static char message[50] = "Hello, World!"; // static 变量 return message; }缺点:这个函数不是“可重入”的,因为下一次调用会覆盖上一次返回的字符串内容。
-
动态内存分配 (
malloc):在堆上为字符串分配内存,调用者负责在使用后free掉它。#include <stdio.h> #include <stdlib.h> #include <string.h> char* create_greeting() { char* message = (char*)malloc(50 * sizeof(char)); if (message != NULL) { strcpy(message, "Hello from the heap!"); } return message; } int main() { char* greeting = create_greeting(); if (greeting != NULL) { printf("收到的信息: %s\n", greeting); free(greeting); // 记得释放内存! } return 0; }优点:灵活,每个调用者都拥有自己独立的字符串。 缺点:调用者必须记得
free,否则会导致内存泄漏。
| 用法 | 解释 | 适用场景 | 注意事项 |
|---|---|---|---|
return; |
无返回值,仅退出函数 | void 函数中提前结束 |
不能带返回值 |
return value; |
返回一个值(整数、浮点数等) | 计算并返回一个结果 | value 的类型必须与函数返回类型匹配 |
return "OK"; |
返回一个指向字符串常量的指针 | 函数需要返回一个固定的状态信息(如 "OK", "ERROR") | 绝对不能返回局部变量的地址(除非是 static) |
return "OK"; 是一种简洁高效的返回状态信息的方式,因为它利用了程序中已经存在的字符串常量,但关键在于要理解它返回的是地址,并且要避免返回生命周期短暂的局部变量的地址。
