第十二章:高级主题
12.1 多级指针与 void
指针
多级指针
• 定义:指向指针的指针,用于动态管理多维数组或复杂数据结构。
• 声明与使用:
int a = 10;
int *p = &a; // 一级指针
int **pp = &p; // 二级指针
printf("%d", **pp); // 解引用两次 → 10
void
指针
• 泛型指针:可指向任意类型数据,但需强制类型转换后才能解引用。
• 示例:
int num = 42;
void *vp = #
printf("%d", *(int *)vp); // 输出:42
应用场景:
• 动态内存分配函数(如 malloc
)返回 void*
。
• 实现通用函数(如 qsort
)。
12.2 命令行参数(argc
, argv
)
main
函数参数:
int main(int argc, char *argv[]) {
// argc: 参数个数(含程序名)
// argv: 参数字符串数组
}
示例:打印所有命令行参数
for (int i = 0; i < argc; i++) {
printf("参数 %d: %s\n", i, argv[i]);
}
运行与输出:
./program hello world
参数 0: ./program
参数 1: hello
参数 2: world
注意事项:
• argv[argc]
为 NULL
,可用于遍历结束判断。
• 参数类型转换需手动处理(如 atoi(argv[1])
将字符串转整型)。
12.3 可变参数函数实现
实现方式:使用 <stdarg.h>
中的宏:
• va_list
:参数列表对象。
• va_start
:初始化参数列表。
• va_arg
:获取下一个参数。
• va_end
:清理参数列表。
示例:计算可变参数的平均值
#include <stdarg.h>
double average(int count, ...) {
va_list args;
va_start(args, count);
double sum = 0;
for (int i = 0; i < count; i++) {
sum += va_arg(args, double); // 依次读取参数
}
va_end(args);
return sum / count;
}
// 调用
double avg = average(3, 2.5, 3.5, 4.5); // 结果:3.5
限制:
• 参数类型和数量需在函数内显式管理,无编译时类型检查。
12.4 数据结构基础(链表实现)
链表节点定义:
typedef struct Node {
int data;
struct Node *next;
} Node;
创建链表:
Node *head = NULL;
// 插入节点(头插法)
void insert(int data) {
Node *newNode = malloc(sizeof(Node));
newNode->data = data;
newNode->next = head;
head = newNode;
}
遍历链表:
Node *current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
删除节点:
void delete(int data) {
Node **ptr = &head;
while (*ptr != NULL) {
if ((*ptr)->data == data) {
Node *temp = *ptr;
*ptr = temp->next;
free(temp);
return;
}
ptr = &(*ptr)->next;
}
}
12.5 简单算法实现(排序与查找)
冒泡排序:
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
二分查找:
int binarySearch(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
}
if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
线性查找:
int linearSearch(int arr[], int n, int target) {
for (int i = 0; i < n; i++) {
if (arr[i] == target) {
return i;
}
}
return -1;
}
总结
- 多级指针:灵活处理动态数据结构,但需谨慎避免内存泄漏。
- 命令行参数:增强程序交互性,适合工具类程序开发。
- 可变参数:提高函数灵活性,但牺牲类型安全性。
- 链表:动态内存管理的典型应用,需注意指针操作的正确性。
- 算法基础:排序和查找是编程核心能力,掌握基础算法后再探索优化策略。
进阶建议:
• 学习更多数据结构(栈、队列、树)。
• 理解递归在算法中的应用(如快速排序)。
• 掌握指针与内存管理的底层机制。