C语言常用关键字、函数与类型详解
本文档将介绍C语言中的几个常用关键字、函数和类型,包括存储类、字符串转换、网络地址处理、信号处理以及多线程管理。具体内容涵盖 static
关键字、atoi
、inet_addr
、signal
、信号编号(signum
)以及 pthread_t
类型。
1. 存储类关键字
1.1 static
关键字
功能:static
关键字在C语言中用于控制变量和函数的作用域、存储持续性以及链接性。根据变量或函数的声明位置不同,static
具有不同的作用。
1.1.1 静态变量(Static Variables)
在函数内部声明的静态变量: 当
static
用于函数内部的变量时,该变量具有静态存储持续性,意味着变量在程序的整个运行期间都存在,并且其值在多次函数调用之间保持不变。#include <stdio.h> void counter() { static int count = 0; // 静态变量 count++; printf("Count: %d\n", count); } int main() { counter(); // 输出: Count: 1 counter(); // 输出: Count: 2 counter(); // 输出: Count: 3 return 0; }
在上述例子中,
count
变量在每次调用counter
函数时不会被重新初始化,而是保留其上一次的值。在文件作用域声明的静态变量: 当
static
用于文件作用域(即函数外部)时,变量的链接性被限制为内部链接,意味着该变量只能在声明它的文件内访问,不能被其他文件访问。// file1.c static int sharedVar = 10; // 仅在file1.c中可见 void printVar() { printf("sharedVar: %d\n", sharedVar); }
// file2.c extern int sharedVar; // 错误:sharedVar在file1.c中是静态的,无法在file2.c中访问
1.1.2 静态函数(Static Functions)
当 static
用于函数声明时,该函数的链接性被限制为内部链接,即该函数只能在声明它的文件内调用,不能被其他文件访问。这在模块化编程中非常有用,可以隐藏内部实现细节。
// file1.c
static void helperFunction() {
// 仅在file1.c中可见
}
void publicFunction() {
helperFunction(); // 可以调用
}
// file2.c
void publicFunction();
int main() {
publicFunction(); // 正确,可以调用
helperFunction(); // 错误:helperFunction在file1.c中是静态的,无法在file2.c中访问
return 0;
}
1.1.3 总结
static
关键字在C语言中扮演着重要角色,通过控制变量和函数的生命周期、作用域及链接性,帮助程序员实现更好的模块化、数据隐藏和资源管理。理解并正确使用 static
是编写高效、可维护C程序的基础之一。
2. 字符串与整数转换
2.1 atoi
函数
功能:atoi
(ASCII to Integer)用于将一个表示整数的字符串转换为对应的整数值。
头文件:<stdlib.h>
原型:
int atoi(const char *str);
用法示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "12345";
int num = atoi(str);
printf("转换后的整数值为: %d\n", num); // 输出: 12345
return 0;
}
注意事项:
atoi
不进行错误检查,如果字符串不完全是有效的整数表示,结果可能未定义。推荐使用strtol
进行更安全的转换。
3. 网络地址处理
3.1 inet_addr
函数
功能:inet_addr
用于将一个点分十进制格式的 IPv4 地址(如 "192.168.1.1")转换为一个 unsigned long
类型的网络地址(网络字节序)。
头文件:<arpa/inet.h>
原型:
unsigned long inet_addr(const char *cp);
用法示例:
#include <stdio.h>
#include <arpa/inet.h>
int main() {
const char *ip_str = "192.168.1.1";
unsigned long ip_addr = inet_addr(ip_str);
if (ip_addr == INADDR_NONE) {
printf("IP地址转换失败\n");
} else {
printf("转换后的网络地址: %lu\n", ip_addr);
}
return 0;
}
注意事项:
inet_addr
仅支持 IPv4 地址,对于 IPv6 地址需使用inet_pton
。- 返回值为
INADDR_NONE
表示转换失败。
4. 信号处理
4.1 signal
函数
功能:signal
用于设置信号处理程序,允许程序捕获和处理特定的信号(如程序终止、非法操作等)。
头文件:<signal.h>
原型:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
用法示例:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void handle_sigint(int sig) {
printf("捕获到信号 %d(SIGINT),程序即将终止。\n", sig);
exit(0);
}
int main() {
// 设置信号处理程序
signal(SIGINT, handle_sigint);
printf("程序运行中,按 Ctrl+C 来触发 SIGINT 信号...\n");
while(1); // 无限循环等待信号
return 0;
}
4.2 信号编号(signum
)
定义:signum
指定信号的类型,常见的信号及其说明如下:
- SIGINT:用户按下 Ctrl+C 时发送,表示程序被中断。
- SIGTERM:请求程序终止。
- SIGSEGV:非法内存访问,通常导致段错误。
- SIGFPE:浮点运算错误(例如除零)。
- SIGILL:非法指令。
- SIGABRT:异常终止信号,通常由程序本身发送。
- SIGKILL:强制终止程序(无法捕获或忽略)。
- SIGUSR1, SIGUSR2:用户自定义信号。
信号处理示例:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void handle_signal(int signum) {
switch(signum) {
case SIGINT:
printf("接收到 SIGINT 信号(中断信号)。\n");
break;
case SIGTERM:
printf("接收到 SIGTERM 信号(终止信号)。\n");
break;
case SIGSEGV:
printf("接收到 SIGSEGV 信号(段错误)。\n");
break;
default:
printf("接收到信号: %d\n", signum);
}
exit(0);
}
int main() {
// 设置信号处理程序
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
signal(SIGSEGV, handle_signal);
printf("程序运行中,等待信号...\n");
while(1); // 无限循环等待信号
return 0;
}
5. 多线程管理
5.1 pthread_t
类型
定义:pthread_t
是 POSIX 线程库(pthreads)中的一个数据类型,用于表示线程的标识符。它用于在多线程程序中唯一标识一个线程。
头文件:<pthread.h>
基本用法:
创建线程:
#include <stdio.h> #include <pthread.h> void* thread_function(void* arg) { printf("新线程正在运行...\n"); return NULL; } int main() { pthread_t thread; if(pthread_create(&thread, NULL, thread_function, NULL)) { fprintf(stderr, "创建线程失败\n"); return 1; } pthread_join(thread, NULL); // 等待线程结束 return 0; }
线程标识: 每个线程都有一个唯一的
pthread_t
标识符,可以用于后续的线程管理操作,如等待线程结束、取消线程等。
5.2 线程管理
常用函数:
pthread_create
:创建新线程。pthread_join
:等待指定线程结束。pthread_cancel
:取消指定线程。pthread_exit
:终止调用线程。
线程管理示例:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* worker(void* arg) {
int id = *(int*)arg;
printf("线程 %d 开始工作。\n", id);
sleep(2); // 模拟工作
printf("线程 %d 完成工作。\n", id);
return NULL;
}
int main() {
pthread_t threads[3];
int thread_ids[3] = {1, 2, 3};
// 创建线程
for(int i = 0; i < 3; i++) {
if(pthread_create(&threads[i], NULL, worker, &thread_ids[i])) {
fprintf(stderr, "无法创建线程 %d\n", i+1);
return 1;
}
}
// 等待所有线程结束
for(int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}
printf("所有线程已完成。\n");
return 0;
}
注意事项:
- 使用
pthread_t
进行线程管理时,应确保线程标识符的唯一性和正确性。 - 线程间共享资源时,需要使用同步机制(如互斥锁)以避免竞态条件。
6. 总结
本文档介绍了C语言中几个重要的关键字、函数和类型,包括:
static
关键字:用于控制变量和函数的作用域、存储持续性及链接性,帮助实现模块化和数据隐藏。atoi
:用于字符串与整数之间的转换。inet_addr
:用于将字符串形式的IPv4地址转换为网络字节序的地址。signal
和signum
:用于信号处理,允许程序捕获和响应各种系统信号。pthread_t
:POSIX线程标识符,用于多线程编程中的线程管理。
理解并正确使用这些关键字、函数和类型,可以显著提高C程序在存储管理、字符串处理、网络编程、信号响应以及多线程管理等方面的能力。