pointer

指针基础概念

指针本质上是一个变量,其值为另一个变量的内存地址。指针提供了直接访问内存的能力,使得程序可以高效地操作数据。

指针的定义与初始化

指针的定义格式为:数据类型 *指针变量名;

1
2
3
int *p;      // 定义一个指向整型的指针
char *cp; // 定义一个指向字符的指针
float *fp; // 定义一个指向浮点数的指针

指针初始化时应该指向一个明确的地址:

1
2
int a = 10;
int *p = &a; // p指向变量a的地址

指针的解引用

1
2
3
int a = 10;
int *p = &a;
printf("%d", *p); // 输出10,即a的值

指针的大小

指针的大小取决于系统架构:
32位系统:4字节
64位系统:8字节


指针运算

指针与整数加减

指针加减整数时,移动的字节数取决于指针指向的类型大小:

1
2
3
int arr[5] = {1,2,3,4,5};
int *p = arr; // 指向arr[0]
p = p + 1; // 现在指向arr[1],实际地址增加了sizeof(int)字节

指针与指针相减

同类型指针相减,结果是它们之间相隔的元素个数:

1
2
3
4
int arr[5] = {0};
int *p1 = &arr[0];
int *p2 = &arr[3];
printf("%td", p2 - p1); // 输出3

指针关系运算

指针可以比较大小(地址高低):

1
2
3
if(p1 < p2) {
printf("p1指向的地址低于p2");
}

指针的自增自减

1
2
3
4
5
int arr[3] = {10,20,30};
int *p = arr;
printf("%d", *p++); // 输出10,然后p指向arr[1]
printf("%d", (*p)++); // 输出20,然后将arr[1]的值改为21
printf("%d", *++p); // p先指向arr[2],然后输出30

指针与一维数组

数组名在大多数情况下会退化为指向数组首元素的指针

数组名的本质

1
2
3
4
int arr[5] = {1,2,3,4,5};
// 以下表达式等价
arr == &arr[0]; // true
*arr == arr[0]; // true

通过指针访问数组元素

有四种等价方式访问数组元素:

1
2
3
4
5
int arr[5] = {1,2,3,4,5};
int *p = arr;

// 以下四种方式等价
arr[i] == *(arr + i) == p[i] == *(p + i)

指针遍历数组的两种方式

1
2
3
4
5
6
7
8
9
10
// 方式1:指针自增,改变指针指向
int *p = arr;
for(int i=0; i<5; i++) {
printf("%d ", *p++);
}

// 方式2:指针不变,通过偏移访问
for(int i=0; i<5; i++) {
printf("%d ", *(p + i));
}

指针与二维数组

二维数组可以看作”数组的数组”,其指针操作更为复杂

二维数组的地址表示

对于一个二维数组int a[3][4]:

表达式 含义
a 数组首地址,也是第0行的首地址务
a+i / &a[i] 第i行的起始地址
*(a+i) / a[i] 第i行第0列元素的地址上
*(a+i)+j / a[i]+j / &a[i][j] 第i行第j列元素的地址
((a+i)+j) / *(a[i]+j) / a[i][j] 第i行第j列元素的值

二维数组的地址表示

1
2
int a[3][4];
int (*p)[4] = a; // p是指向含有4个元素的一维数组的指针

通过指针访问二维数组

1
2
3
4
5
6
7
8
9
10
11
12
// 方式1:使用数组指针
for(int i=0; i<3; i++) {
for(int j=0; j<4; j++) {
printf("%d ", *(*(p + i) + j));
}
}

// 方式2:将二维数组视为一维数组
int *ptr = &a[0][0];
for(int i=0; i<12; i++) {
printf("%d ", ptr[i]);
}

数组指针

数组指针是指向数组的指针,与指针数组完全不同

数组指针的定义

1
int (*arr_ptr)[5]; // 指向包含5个int元素的数组的指针

数组指针的初始化

1
2
int arr[5] = {1,2,3,4,5};
int (*arr_ptr)[5] = &arr; // 注意&arr的类型是int(*)[5]

数组指针与二维数组

1
2
3
4
5
6
7
8
9
int matrix[3][4] = {0};
int (*ptr)[4] = matrix; // ptr指向matrix的第一行

// 通过数组指针访问二维数组
for(int i=0; i<3; i++) {
for(int j=0; j<4; j++) {
printf("%d ", ptr[i][j]);
}
}

pointer
https://chrisy0618.github.io/2025/04/22/pointer/
作者
Chris.Y
发布于
2025年4月22日
许可协议