1. 指针基础补充
1.1 指针的大小
- 指针的大小:
- 无论什么类型的指针,在同一平台上的大小总是固定的。
- 在 32 位平台上,所有的指针(地址)都是 32 位(4 字节)。
- 在 64 位平台上,所有的指针(地址)都是 64 位(8 字节)。
- 示例:c
#include <stdio.h> int main() { char b = 'b'; int *a = NULL; char *b_ptr = &b; float *c = NULL; printf("sizeof(a) = %zu\n", sizeof(a)); // 输出 8 (在 64 位平台上) printf("sizeof(b_ptr) = %zu\n", sizeof(b_ptr)); // 输出 8 (在 64 位平台上) printf("sizeof(c) = %zu\n", sizeof(c)); // 输出 8 (在 64 位平台上) return 0; }
1.2 const 修饰的指针变量
- 常量指针:
- 声明指针变量时可以使用
const关键字来修饰指针所指向的内容。 const可以放在不同的位置,表示不同的含义:const放在类型名称前:指针所指向的内容不可修改。const放在指针符号前:指针本身不可修改。
- 声明指针变量时可以使用
- 示例:c
#include <stdio.h> int main() { const int a = 10; // 常量 int b = 20; // 变量 // 常量指针:指针所指向的内容不可修改 const int *p1 = &a; // p1 = &b; // 错误:不能将非常量的地址赋给常量指针 // *p1 = 30; // 错误:不能通过常量指针修改内容 // 指针常量:指针本身不可修改 int *const p2 = &b; // p2 = &a; // 错误:不能改变指针常量的指向 *p2 = 30; // 正确:可以通过指针常量修改内容 // 常量指针常量:指针和指针所指向的内容都不可修改 const int *const p3 = &a; // p3 = &b; // 错误:不能改变指针常量的指向 // *p3 = 30; // 错误:不能通过常量指针修改内容 return 0; }
2. 指针和数组
2.1 数组名
- 数组名字是数组的首元素地址:
- 数组名本质上是一个指向数组第一个元素的指针。
- 数组元素指针:
- 一个变量有地址,一个数组包含若干元素,每个数组元素也有相应的地址。
- 指针变量也可以保存数组元素的地址,只要一个指针变量保存了数组元素的地址,我们就称之为数组元素指针。
- 示例:c
#include <stdio.h> int main() { int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; printf("a = %p\n", (void *)a); // 输出数组首地址 printf("&a[0] = %p\n", (void *)&a[0]); // 输出数组首地址 return 0; }
2.2 数组名不能参与加减计算
- 数组名的限制:
- 数组名是一个常量指针,它不能参与加减运算。
- 例如,
a + 1是非法的,但&a[0] + 1是合法的。
- 示例:c
#include <stdio.h> int main() { int a[] = {1, 2, 3, 4, 5, 6, 7}; char c[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; int *pa = a; char *pc = c; printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); pa++; pc++; // a++; // 错误:数组名不能参与加减运算 // c++; // 错误:数组名不能参与加减运算 printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); pa += 2; pc += 2; // a += 2; // 错误:数组名不能参与加减运算 // c += 2; // 错误:数组名不能参与加减运算 printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); printf("*(pa + 1) = %d\n", *(pa + 1)); // 输出 5 printf("*pa = %d\n", *pa); // 输出 4 printf("*(pa - 1) = %d\n", *(pa - 1)); // 输出 3 printf("\n"); printf("*(pc + 1) = %c\n", *(pc + 1)); // 输出 e printf("*pc = %c\n", *pc); // 输出 d printf("*(pc - 1) = %c\n", *(pc - 1)); // 输出 c return 0; }
2.3 通过指针遍历数组
- 遍历数组:
- 使用指针遍历数组是一种常见的方法,可以方便地访问和修改数组元素。
- 示例:c
#include <stdio.h> int main() { int a[] = {1, 2, 3, 4, 5, 6, 7}; char c[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; int *pa = a; char *pc = c; printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); pa++; pc++; // a++; // 错误:数组名不能参与加减运算 // c++; // 错误:数组名不能参与加减运算 printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); pa += 2; pc += 2; // a += 2; // 错误:数组名不能参与加减运算 // c += 2; // 错误:数组名不能参与加减运算 printf("pa = %p\n", (void *)pa); printf("pc = %p\n", (void *)pc); printf("\n"); printf("*(pa + 1) = %d\n", *(pa + 1)); // 输出 5 printf("*pa = %d\n", *pa); // 输出 4 printf("*(pa - 1) = %d\n", *(pa - 1)); // 输出 3 printf("\n"); printf("*(pc + 1) = %c\n", *(pc + 1)); // 输出 e printf("*pc = %c\n", *pc); // 输出 d printf("*(pc - 1) = %c\n", *(pc - 1)); // 输出 c return 0; }
总结
- 指针基础补充:
- 指针的大小:在 32 位平台上为 4 字节,在 64 位平台上为 8 字节。
const修饰的指针变量:常量指针、指针常量和常量指针常量的不同用法。
- 指针和数组:
- 数组名:数组名是数组的首元素地址。
- 数组元素指针:指针变量可以保存数组元素的地址。
- 数组名不能参与加减计算:数组名是一个常量指针,不能参与加减运算。
- 通过指针遍历数组:使用指针遍历数组是一种常见且有效的方法。
