目录
二级指针:char* *pp =&p; int** pp = &p; //存放一级指针地址
一.指针的基本认识
1.什么是指针?
指针是存储变量内存地址的变量。通过指针可以直接操作内存中的数据
int a = 10; // 定义一个整型变量
int *p = &a; // 定义指针p,指向a的地址
2.指针的操作符
1.取地址操作符&:
int a;&a //取出a的地址
2.解引用操作符*:
int *p = &a //取出a的地址并存储到指针变量p中
int a ; int* p = &a; *p = 0;
上面代码中*p就使用了解引用操作符,*p 的意思就是通过p中存放的地址,找到指向的空间,*p其实就是a变量了,所以*p=0,这个操作符是把a改成了0.
int x = 5;
int *ptr = &x; // ptr保存x的地址
printf("%d", *ptr); // 输出5(通过指针访问x的值)
对于:
Int a = 10;
Int* p = &a;
这里p左边写的是int*,*是在说明p是指针变量,前面的int是在说明p指向的是整形(int)类型的对象
二、指针与内存
1.内存地址
每个变量在内存中占据一块空间,地址用十六进制表示(如
0x7ffd42a1c4
)。指针的大小与系统位数相关(32位系统为4字节,64位系统为8字节)。
2.指针的类型意义
指针类型决定了解引用时的操作范围(如
int*
每次操作4字节)。指针类型影响指针运算的步长(如
ptr+1
实际移动的字节数由类型决定)。
三.指针运算
1.指针 + - 整数
2.指针 - 指针:
得到的是指针和指针之间的元素个数的绝对值,注意没有指针+指针
int arr[3] = {10, 20, 30};
int *p = arr; // p指向arr[0]
p++; // p现在指向arr[1]
printf("%d", *p); // 输出20
3.指针的关系运算
if (p1 < p2) { ... } // 判断地址位置
四.常见错误
1.野指针:指针指向的位置是不可知的
野指针的成因:
1.指针未初始化
2.指针越界访问
3.指针指向的空间释放
int *p; // 未初始化,指向随机地址
*p = 5; // 危险操作!
2.内存泄漏
int *p = malloc(100);
// 使用后未free(p)
3.指针越界访问
int arr[3] = {1, 2, 3};
int *p = arr;
printf("%d", p[3]); // 越界访问
五.指针分类
一级指针:char*p; int*p;
二级指针:char* *pp =&p; int** pp = &p; //存放一级指针地址
//多级指针(指针的指针) int a = 10; int *p = &a; int **pp = &p; // 二级指针 printf("%d", **pp); // 输出10
数组指针-----》指向的是数组
Int arr[5];
Int (*p)[5]=&arr;
函数指针----》指向的是函数
char* test(int n , char* s)
char* (*pf)(int , char*)=test; //pf是函数指针变量
void sayHello() { printf("Hello!"); } int main() { void (*funcPtr)() = sayHello; // 定义函数指针 funcPtr(); // 调用函数 return 0; }
指针数组------》存放指针的数组
char*arr[5];
Int* arr[5];
函数指针数组
Char* (* pfArr[4])(int , char*);
六.代码示例
// 指针与动态内存
int *createArray(int size) {
int *arr = (int*)malloc(size * sizeof(int));
for (int i=0; i<size; i++) arr[i] = i+1;
return arr;
}
// 函数指针的典型应用(回调)
void process(int (*callback)(int), int x) {
int result = callback(x);
printf("Result: %d", result);
}