C语言入门:指针逆袭,看完这篇彻底搞定指针

一,先搞懂指针到底是什么(核心本质)

1.1 从内存说起

我们可以把内存想象成一排连续的小房间

  • 每个房间都有一个门牌号 → 这就是内存地址
  • 每个房间里存放东西 → 这就是变量的值

在 C 语言里:

  • 直接用变量名操作值 → 直接访问
  • 用地址找到变量再操作 → 间接访问

指针 = 存放内存地址的变量

记住一句话:

指针本身也是一个变量,它不存普通数值,只存地址

1.2 两个核心符号

  • & :取地址符 → 取出变量的内存地址
  • * :解引用符 → 通过地址找到对应的值

int a = 10;
int *p = &a;
  • a 是普通变量,存的是 10
  • p 是指针变量,存的是 a 的地址
  • *p 就代表 a 本身

二、指针基础必懂知识点(新手必看)

2.1 指针定义格式

类型 *指针变量名;
  • int *p → 指向 int 类型变量的指针
  • char *p → 指向 char 类型变量的指针
  • float *p → 指向 float 类型变量的指针

重点:指针的类型,决定了它指向什么类型的数据,以及步长多大

2.2 指针大小

很多新手会问:指针占多少字节?答案:和类型无关,只跟系统位数有关

  • 32 位系统:指针占 4 字节
  • 64 位系统:指针占 8 字节

不管是 int*char*double*,大小都一样。

三、指针和数组:一对好兄弟

这是面试必考,也是指针最常用的地方。

3.1 数组名本质

数组名本质上是一个常量指针,指向数组首元素地址。

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

下面两句话等价:

  • arr == &arr[0]
  • *(arr + i) == arr[i]

3.2 指针操作数组

int arr[5] = {10,20,30,40,50};
int *p = arr;

printf("%d ", *p);      // 10
printf("%d ", *(p+1));  // 20
printf("%d ", *(p+2));  // 30

指针 +1,不是地址 +1,而是跳过一个类型大小

四、指针进阶一:指针的指针(二级指针)

4.1 什么是二级指针?

一级指针存变量地址,二级指针存一级指针的地址

int a = 10;
int *p = &a;
int **pp = &p;
  • pp 是二级指针
  • *pp 拿到 p
  • **pp 拿到 a

4.2 什么时候用?

最经典场景:

  • 函数内部修改外部指针
  • 二维数组传参
  • 动态申请二维数组

五、指针进阶二:函数指针(重点)

5.1 函数也有地址

代码也是存在内存里的,函数也有入口地址。存放函数地址的指针,就是函数指针

定义格式:

返回值类型 (*指针名)(参数列表);

例如:

int add(int a,int b){
    return a+b;
}

// 定义函数指针
int (*p)(int,int) = add;

调用:

int ret = (*p)(10,20); // 等价 add(10,20)

5.2 函数指针有啥用?

  • 实现回调函数

六、指针进阶三:指针数组 & 数组指针

6.1 指针数组

本质是数组,里面每个元素都是指针。

int (*p)[10];
  • 存放多个地址
  • 常用于多字符串、二维表

6.2 数组指针

本质是指针,指向一个数组。

int (*p)[10];
  • 指向整个数组
  • 常用于二维数组传参

口诀:

  • [] 优先级高于 *
  • 带括号 (*p) 是指针
  • 不带括号是数组

七、指针进阶四:空指针、野指针、void*

7.1 空指针 NULL

运行

int *p = NULL;

表示指针不指向任何有效空间,用来做初始化、判断。

7.2 野指针(最坑!)

指向非法内存的指针,会导致程序崩溃。产生原因:

  • 指针未初始化
  • 指针指向空间已释放
  • 指针越界

规避方法:

  • 初始化指针
  • free 后置 NULL
  • 不越界访问

7.3 void* 无类型指针

  • 可以接收任意类型地址
  • 不能直接解引用
  • 常用于通用接口、内存操作函数(memcpy、malloc)

八、指针和内存:动态内存管理(必学)

指针真正的强大,在于配合动态内存

四个函数:

  • malloc:申请内存
  • calloc:申请并初始化为0
  • realloc:调整大小
  • free:释放内存

例子:

int *p = (int*)malloc(sizeof(int)*10);
if(p == NULL){
    perror("malloc fail");
    return 1;
}
// 使用...
free(p);
p = NULL;

记得:

有 malloc 必有 free,谁申请谁释放,free 后置空。

九、指针常见面试题

  1. 指针是什么?占多少字节?
  2. 数组名和指针区别?
  3. 野指针是什么?如何避免?
  4. 函数指针怎么用?
  5. 指针数组和数组指针区别?
  6. 动态内存注意事项?

十、总结:几句话吃透指针

  1. 指针就是地址,指针变量就是存地址的变量
  2. * 解引用找到目标,& 取地址
  3. 指针 + 1 = 跳过一个类型大小
  4. 数组名 ≈ 首元素地址
  5. 函数指针 = 函数入口地址,用来回调、解耦
  6. 动态内存 + 指针 = C 语言真正的灵活性
  7. 小心野指针,记得 free 和置空

指针没有那么玄学,记得多写、多画内存图、多调试。

一键三连!!!!!!!!!!!!!!!!!!!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值