指针基础概念
指针本质上是一个变量,其值为另一个变量的内存地址。指针提供了直接访问内存的能力,使得程序可以高效地操作数据。
指针的定义与初始化
指针的定义格式为:数据类型 *指针变量名;
1 2 3
| int *p; char *cp; float *fp;
|
指针初始化时应该指向一个明确的地址:
1 2
| int a = 10; int *p = &a;
|
指针的解引用
1 2 3
| int a = 10; int *p = &a; printf("%d", *p);
|
指针的大小
指针的大小取决于系统架构:
32位系统:4字节
64位系统:8字节
指针运算
指针与整数加减
指针加减整数时,移动的字节数取决于指针指向的类型大小:
1 2 3
| int arr[5] = {1,2,3,4,5}; int *p = arr; p = p + 1;
|
指针与指针相减
同类型指针相减,结果是它们之间相隔的元素个数:
1 2 3 4
| int arr[5] = {0}; int *p1 = &arr[0]; int *p2 = &arr[3]; printf("%td", p2 - p1);
|
指针关系运算
指针可以比较大小(地址高低):
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++); printf("%d", (*p)++); printf("%d", *++p);
|
指针与一维数组
数组名在大多数情况下会退化为指向数组首元素的指针
数组名的本质
1 2 3 4
| int arr[5] = {1,2,3,4,5};
arr == &arr[0]; *arr == arr[0];
|
通过指针访问数组元素
有四种等价方式访问数组元素:
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
| int *p = arr; for(int i=0; i<5; i++) { printf("%d ", *p++); }
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;
|
通过指针访问二维数组
1 2 3 4 5 6 7 8 9 10 11 12
| for(int i=0; i<3; i++) { for(int j=0; j<4; j++) { printf("%d ", *(*(p + i) + j)); } }
int *ptr = &a[0][0]; for(int i=0; i<12; i++) { printf("%d ", ptr[i]); }
|
数组指针
数组指针是指向数组的指针,与指针数组完全不同
数组指针的定义
数组指针的初始化
1 2
| int arr[5] = {1,2,3,4,5}; int (*arr_ptr)[5] = &arr;
|
数组指针与二维数组
1 2 3 4 5 6 7 8 9
| int matrix[3][4] = {0}; int (*ptr)[4] = matrix;
for(int i=0; i<3; i++) { for(int j=0; j<4; j++) { printf("%d ", ptr[i][j]); } }
|