代码示例:1.3.1 指针基础与 const 指针
全部示例均标注编译命令、适用环境与实测状态;完整验证记录见《03.5-代码编译运行验证记录》。
examples/ex1-pointer-basics.c · 地址、解引用与传址交换
/* ex1-pointer-basics.c —— 指针基础:地址、解引用与传址交换 * 适用环境:Linux / Windows(MinGW) 标准:C11 * 编译:gcc ex1-pointer-basics.c -o ex1 -std=c11 -Wall -Wextra -Wpedantic */ #include <stdio.h> /* 传值交换:函数内交换的是形参副本,main 中的变量不变(演示用) */ static void swap_by_value(int a, int b) { int tmp = a; a = b; b = tmp; printf("swap_by_value 内部:a=%d, b=%d\n", a, b); } /* 传址交换:通过指针直接修改 main 中的变量 */ static void swap_by_address(int *pa, int *pb) { if (pa == NULL || pb == NULL) { /* 使用前判空,杜绝野指针 */ fprintf(stderr, "swap_by_address: 收到空指针\n"); return; } int tmp = *pa; *pa = *pb; *pb = tmp; } int main(void) { int x = 10; int y = 20; int *px = &x; /* px 保存 x 的地址 */ printf("x 的值 = %d,x 的地址 = %p\n", x, (void *)&x); printf("px 保存的地址 = %p,*px 解引用 = %d\n", (void *)px, *px); printf("本平台 sizeof(int*) = %zu 字节\n", sizeof(px)); /* 64 位为 8,32 位为 4 */ swap_by_value(x, y); printf("传值交换后:x=%d, y=%d(main 中未交换)\n", x, y); swap_by_address(&x, &y); printf("传址交换后:x=%d, y=%d(main 中已交换)\n", x, y); return 0; }examples/ex2-const-pointers.c · const 指针三种写法
/* ex2-const-pointers.c —— const 指针三种写法的可改/不可改矩阵 * 适用环境:Linux / Windows(MinGW) 标准:C11 * 编译:gcc ex2-const-pointers.c -o ex2 -std=c11 -Wall -Wextra -Wpedantic * 练习:把三处注释掉的"非法"行逐一取消注释并重新编译,观察并解释报错。 */ #include <stdio.h> int main(void) { int a = 1; int b = 2; /* ① 常量指针:指向的数据不可改,指针本身可改(const 在 * 左侧) */ const int *p1 = &a; printf("p1 -> %d\n", *p1); p1 = &b; /* 合法:重新指向 b */ /* *p1 = 10; 非法:error: assignment of read-only location '*p1' */ printf("p1 重新指向后 -> %d\n", *p1); /* ② 指针常量:指针本身不可改,指向的数据可改(const 在 * 右侧) */ int *const p2 = &a; *p2 = 11; /* 合法:修改 a 的值 */ /* p2 = &b; 非法:error: assignment of read-only variable 'p2' */ printf("经 p2 修改后 a = %d\n", a); /* ③ 常量指针常量:都不可改(两侧都有 const) */ const int *const p3 = &a; printf("p3 -> %d\n", *p3); /* *p3 = 12; 非法:error: assignment of read-only location '*(const int *)p3' */ /* p3 = &b; 非法:error: assignment of read-only variable 'p3' */ return 0; }examples/ex3-null-checks.c · 空指针检查与 free 后置 NULL
/* ex3-null-checks.c —— 空指针检查与 free 后置 NULL 的好习惯 * 适用环境:Linux / Windows(MinGW) 标准:C11 * 编译:gcc ex3-null-checks.c -o ex3 -std=c11 -Wall -Wextra -Wpedantic * 背景:本章【纠错】指出——对野指针解引用是未定义行为,任何情况下都不应尝试。 * 本程序演示正确的防野指针习惯,而不是演示崩溃。 */ #include <stdio.h> #include <stdlib.h> int main(void) { int *p = NULL; /* 习惯 1:定义即初始化,杜绝野指针 */ if (p != NULL) { /* 习惯 2:使用前判空 */ printf("%d\n", *p); } else { printf("p 是空指针,跳过解引用\n"); } p = (int *)malloc(sizeof(int)); if (p == NULL) { /* 习惯 3:malloc 返回值必须检查 */ fprintf(stderr, "malloc 失败\n"); return 1; } *p = 42; printf("*p = %d\n", *p); free(p); p = NULL; /* 习惯 4:free 后置 NULL,避免悬挂指针/重复 free */ if (p != NULL) { /* 防御性检查:此处不会执行 */ free(p); } return 0; }