Linux C 编程核心函数详解
Linux C 编程核心函数详解
1. fork - 进程管理
函数介绍及归类
- 类别: 系统调用 (System Call)
- 头文件:
#include - 作用: 创建一个当前进程的副本(子进程)。这是 Linux 下创建新进程的主要方式。
函数原型
#include
pid_t fork(void);
功能
fork() 调用一次,返回两次。它会创建一个与调用进程(父进程)几乎完全相同的子进程。子进程会从 fork() 返回后的下一条指令开始执行。
参数
无参数。
返回值
- 在父进程中: 返回新创建的子进程的进程 ID (PID),这是一个正整数。
- 在子进程中: 返回 0。
- 失败时: 在父进程中返回 -1,并设置全局变量
errno来指示错误原因(如系统资源不足)。
相似函数或关联函数
vfork(): 类似于fork(),但在子进程调用exec或_exit之前,父进程会被阻塞。通常用于紧接着调用exec的场景,效率可能稍高。wait(),waitpid(): 父进程用来等待子进程结束。getpid(): 获取当前进程的 PID。getppid(): 获取当前进程的父进程 PID。
示例代码 (C89)
#include /* printf, perror */
#include /* fork, getpid, getppid */
#include /* pid_t */
#include /* wait */
int main() {
pid_t pid;
int status;
/* 调用 fork 创建子进程 */
pid = fork();
if (pid `
* **作用:** 创建一个新进程,但与 `fork` 不同,它在子进程调用 `exec` 或 `_exit` 之前,共享父进程的地址空间,并且父进程会被阻塞。
#### 函数原型
```c
#include
pid_t vfork(void);
功能
vfork() 也调用一次,返回两次。它创建一个新进程,但这个新进程(子进程)在调用 exec 系列函数或 _exit 之前,与父进程共享内存(包括栈、数据段等)。在此期间,父进程是被挂起的。这使得 vfork 在紧接着调用 exec 时非常高效,因为它避免了复制父进程的页表。
参数
无参数。
返回值
- 在父进程中: 返回新创建的子进程的 PID。
- 在子进程中: 返回 0。
- 失败时: 在父进程中返回 -1,并设置
errno。
相似函数或关联函数
fork(): 更通用,子进程独立于父进程。exec()系列函数 (execl,execv,execle,execve,execlp,execvp): 用新程序替换当前进程的镜像。
示例代码 (C89)
#include /* printf, perror */
#include /* vfork, getpid, getppid, _exit */
#include /* pid_t */
int main() {
pid_t pid;
int shared_var = 10; /* 父子进程共享的变量 */
printf("Before vfork, shared_var = %d\n", shared_var);
/* 调用 vfork 创建子进程 */
pid = vfork();
if (pid `
* **作用:** 执行一个 shell 命令字符串。它内部通常通过调用 `fork`、`exec` 和 `wait` 来实现。
#### 函数原型
```c
#include
int system(const char *command);
功能
system() 函数将 command 字符串传递给系统的命令处理器(通常是 shell,如 /bin/sh)来执行。它是一个方便的函数,可以让你在 C 程序中执行外部命令。
参数
command: 指向以空字符结尾的字符串,该字符串包含了要执行的命令及其参数。
返回值
- 成功: 返回命令执行后的退出状态。这个状态可以通过
WIFEXITED,WEXITSTATUS等宏来解析(类似wait)。 command为 NULL: 如果系统有命令处理器可用,则返回非零值;否则返回 0。这可以用来检查system是否可用。- 失败或错误: 返回 -1,并设置
errno(例如,无法创建子进程)。 - 命令本身执行失败: 返回由命令处理器报告的状态(通常是命令的退出码)。
相似函数或关联函数
fork(),exec()系列,wait():system内部就是用这些函数实现的,提供了更底层和灵活的控制。popen(),pclose(): 可以执行命令并获取其输出(通过管道)。
示例代码 (C89)
#include /* printf, perror */
#include /* system */
int main() {
int result;
/* 检查 system 是否可用 */
if (system(NULL) == 0) {
printf("Command processor is not available.\n");
return 1;
}
printf("Command processor is available.\n");
/* 执行一个简单的命令 */
printf("\n--- Executing 'echo Hello from system call' ---\n");
result = system("echo Hello from system call");
if (result == -1) {
perror("system call failed");
return 1;
} else {
printf("Command 'echo ...' finished with status %d\n", result);
/* 注意:直接的 result 值可能包含更多信息,需要用 wait 宏解析 */
/* 为简化,这里只打印原始值 */
}
/* 执行一个列出文件的命令 */
printf("\n--- Executing 'ls -l' ---\n");
result = system("ls -l");
if (result == -1) {
perror("system call failed");
} else {
printf("Command 'ls -l' finished with status %d\n", result);
}
/* 执行一个会失败的命令 */
printf("\n--- Executing 'nonexistentcommand' ---\n");
result = system("nonexistentcommand");
if (result == -1) {
perror("system call failed (this might be due to fork/exec failure)");
} else {
printf("Command 'nonexistentcommand' finished with status %d\n", result);
/* 这里的 status 通常表示命令未找到 */
}
printf("\nMain program ending.\n");
return 0;
}
4. strlen - 字符串处理
函数介绍及归类
- 类别: 标准库函数 (Standard Library Function)
- 头文件:
#include - 作用: 计算 C 风格字符串(以
\0结尾)的长度。
函数原型
#include
size_t strlen(const char *str);
功能
strlen() 函数遍历字符串 str,从第一个字符开始计数,直到遇到终止符 \0(不包括 \0),然后返回计数的字符数。
参数
str: 指向以\0结尾的字符串。
返回值
返回字符串 str 中字符的个数(不包括结尾的 \0 字符)。返回类型 size_t 是一个无符号整数类型。
相似函数或关联函数
sizeof: 这是一个运算符,不是函数。对于字符数组,sizeof返回整个数组的大小(包括\0),而strlen返回实际内容的长度。strnlen(): (C99/C11) 类似strlen,但会限制搜索长度,防止读取超出指定范围的内存。
示例代码 (C89)
#include /* printf */
#include /* strlen */
int main() {
char str1[] = "Hello"; /* 编译器自动添加 \0 */
char str2[20] = "World"; /* 数组大小为 20,但内容只有 6 个字符(包括 \0) */
const char *str3 = "This is a longer string.";
char str4[] = {'N', 'o', ' ', 'N', 'u', 'l', 'l'}; /* 危险!没有 \0 */
size_t len1, len2, len3;
len1 = strlen(str1);
len2 = strlen(str2);
len3 = strlen(str3);
printf("String 1: \"%s\"\n", str1);
printf("Length of str1 (strlen): %u\n", (unsigned int)len1);
printf("Size of str1 array (sizeof): %u\n", (unsigned int)sizeof(str1)); /* 包括 \0 */
printf("\nString 2: \"%s\"\n", str2);
printf("Length of str2 (strlen): %u\n", (unsigned int)len2);
printf("Size of str2 array (sizeof): %u\n", (unsigned int)sizeof(str2)); /* 包括 \0 */
printf("\nString 3: \"%s\"\n", str3);
printf("Length of str3 (strlen): %u\n", (unsigned int)len3);
printf("\n--- Important Note ---\n");
printf("String 4 is not null-terminated. Calling strlen on it leads to undefined behavior.\n");
printf("It might crash or run forever. Uncommenting the next lines is dangerous.\n");
/* 危险!不要对没有 \0 的字符串调用 strlen */
/* printf("Length of str4 (UNDEFINED BEHAVIOR!): %u\n", (unsigned int)strlen(str4)); */
return 0;
}
5. strchr - 字符串处理
函数介绍及归类
- 类别: 标准库函数 (Standard Library Function)
- 头文件:
#include - 作用: 在字符串中查找第一次出现的指定字符。
函数原型
#include
char *strchr(const char *str, int c);
功能
strchr() 函数在字符串 str 中从左到右搜索字符 c(转换为 char 类型进行比较)。搜索包括终止符 \0。
参数
str: 指向要搜索的以\0结尾的字符串。c: 要搜索的字符,以int类型传递,但在比较时会转换为unsigned char。
返回值
- 找到: 返回指向字符串
str中第一次出现字符c的指针。 - 未找到: 返回
NULL。
相似函数或关联函数
strrchr(): 查找字符在字符串中最后一次出现的位置。strstr(): 查找一个子字符串在另一个字符串中第一次出现的位置。strpbrk(): 查找字符串中第一个匹配指定字符集中任意字符的位置。
示例代码 (C89)
#include /* printf */
#include /* strchr */
int main() {
const char *str = "This is a sample string.";
char target_char = 's';
char *result_ptr;
printf("String to search: \"%s\"\n", str);
printf("Character to find: '%c'\n", target_char);
/* 查找第一次出现 's' 的位置 */
result_ptr = strchr(str, (int)target_char);
if (result_ptr != NULL) {
printf("First occurrence of '%c' found at position: %ld\n",
target_char, (long)(result_ptr - str)); /* 计算偏移量 */
printf("Substring from first '%c': \"%s\"\n", target_char, result_ptr);
/* 查找下一个 's' */
printf("\n--- Searching for next occurrence ---\n");
result_ptr = strchr(result_ptr + 1, (int)target_char); /* 从下一个位置开始搜索 */
if (result_ptr != NULL) {
printf("Second occurrence of '%c' found at position: %ld\n",
target_char, (long)(result_ptr - str));
printf("Substring from second '%c': \"%s\"\n", target_char, result_ptr);
} else {
printf("No more occurrences of '%c' found.\n", target_char);
}
} else {
printf("Character '%c' not found in the string.\n", target_char);
}
/* 查找字符串结尾符 '\0' */
printf("\n--- Searching for null terminator ---\n");
result_ptr = strchr(str, '\0');
if (result_ptr != NULL) {
printf("Null terminator '\\0' found at position: %ld\n", (long)(result_ptr - str));
printf("Pointer points to: '%c' (ASCII value %d)\n", *result_ptr, (int)*result_ptr);
}
/* 查找一个不存在的字符 */
printf("\n--- Searching for a character that doesn't exist ---\n");
result_ptr = strchr(str, 'z');
if (result_ptr != NULL) {
printf("Character 'z' found? This is unexpected.\n");
} else {
printf("Character 'z' not found, as expected. strchr returned NULL.\n");
}
return 0;
}