内存指针与字符串
指针的内存表示
指针是C语言的核心特性之一,其本质是存储内存地址的变量。
- 指针的大小取决于机器的字长(而非指向的类型)
- 32位机器:指针占4字节
- 64位机器:指针占8字节
- 指针的类型信息仅在编译时使用,运行时指针仅仅是一个地址值
NULL指针通常用地址0表示,在大多数系统上访问会触发段错误(segmentation fault)
指针运算
指针运算与数组紧密关联:
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // p 指向 arr[0]
p + 1; // 地址增加 sizeof(int) 字节(通常为4)
*(p + 2) = 30; // 等价于 arr[2] = 30
int *q = &arr[4];
int diff = q - p; // diff = 4(指针差值为元素个数,而非字节数)关键点:
- 指针加1并非地址加1,而是加上其所指向类型的大小
- 指针减法的结果是元素个数(而非字节数)
- 数组名在大多数表达式中隐式转换为指向首元素的指针
字符串的存储
C语言中的字符串以null-terminated(以 \0 结尾)的方式存储:
"Hello" 的内存布局:
H | e | l | l | o | \0
- 字符串字面量存储在只读数据段(如
.rodata段) - 字符数组
char s[] = "Hello";在栈上分配可修改的副本 - 指针
char *s = "Hello";指向只读区域,不能修改其内容
指针数组 vs 二维数组
char *strs[] = {"Hello", "World", "CSAPP"};
// strs[0] 是 char*,指向字符串 "Hello"
// 每个字符串长度可以不同
char strs2[3][6] = {"Hello", "World", "CSAPP"};
// 每行固定宽度6字节,所有字符串必须等宽存储
// 未使用的字节用0填充指针数组更灵活(每个字符串长度可以不同),但需要额外的指针存储空间;二维数组更紧凑,但灵活性差。
相关笔记
链接到
- 上一个知识点:2.7 整型乘法
- 下一个知识点:2.9 十进制与二进制小数转换