【考研C语言】指针

指针是C语言中的重要概念,它存储变量的地址,允许间接访问数据。指针变量的大小取决于其基类型,如在64位系统中通常为8字节。指针常用于函数参数传递,实现对原变量的修改,以及通过偏移访问数组元素。动态内存分配函数malloc返回的指针需转换类型并保存初始值以便释放。堆和栈的区别在于,栈空间在函数结束时自动释放,而堆空间需通过free手动管理,确保数据在函数间持久有效。
摘要由CSDN通过智能技术生成

指针的定义

内存区域中的每字节都对应一个编号,这个编号就是“地址”。如果在程序中定义了一个变量,那么在对程序进行编译时,系统就会给这个变量分配内存单元。按变量地址存取变量值的方式称为“直接访问”,如printf(“%d"i);scanf(”%d",&i);等;另一种存取变量值的方式称为“间接访问”,即将变量 的地址存放到另一个变量中。在 C 语言中,指针变量是一种特殊的变量,它用来存放变量地址。

指针变量存放的地址中存放的数据是什么类型,基类型就必须也是相同的类型。

image.png

指针与指针变量是两个概念,一个变量的地址称为该变量的“指针”。例如,地址 2000 是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),那么称它为“指针变量”。例如,左图中的 i_pointer 就是一个指针变量。

image.png

那么 i_pointer 本身占多大的内存空间呢? 本章中编写的程序都是 64 位应用程序,寻址范围为 64 位即 8 字节,所以对于本章来说 sizeof(i_pointer)=8。如果编写的程序是 32 位,那么寻址范围就是 4 字节 (考研中往往会强调程序是 32 位的程序)。

&:取地址运算符,叫做引用,通过该操作符我们可以获取一个变量的地址值。

  • :取值操作符,叫做解引用,通过该操作符我们可以得到一个地址对应的数据。

指针的传递使用场景

指针的使用场景就俩:传递和偏移

传递

C语言的函数调用是值传递,所以下面这样change函数是改变不了 i 的值

image.png

所以就需要用指针把变量的地址传过去

image.png

偏移

前面介绍了指针的传递。指针即地址,就像我们找到了一栋楼,这栋楼的楼号是 B,那么往前就是 A,往后就是 C,所以应用指针的另一个场景就是对其进行加减,但对指针进行乘除是没有意义的,就像家庭地址乘以 5 没有意义那样。在工作中,我们把对指针的加减称为指针的偏移,加就是向后偏移,减就是向前偏移。

数组变量中存放的都是数组中第一个元素的存储的地址。所以数组的传递会弱化为指针。
image.png

注意指针偏移中+1-1都是逻辑上的“1”,在内存中加减的单位是基类型的字节长度。下图中就可以看到p+1和p差了4个字节,也就是int的大小。
image.png

指针与动态内存申请

因为malloc返回的指针是无类型的,所以需要强制转换类型
image.png
如果要对指针进行偏移之后再free,那么提前准备一个变量来存放初始值

堆和栈的差异

如果想让子函数里面创造的数据返回给主函数,凭直觉可能这么写
image.png
image.png
image.png
打印出来的结果如下,第二次打印会出问题。
image.png
为什么第二次打印会有异常?原因是 print_stack()函数中的字符串存放在栈空间中,函数执行结束后,栈空间会被释放,字符数组 c 的原有空间已被分配给其他函数使用,因此在调用 print_stack()函数后,printf(“p=%sn”,p);中的p不能获取栈空间的数据。

如果要让子函数的数据返回主函数,那么就要用malloc
image.png
这样打印出来就是正常的。
image.png
之所以现在打印是正常的,是因为print_malloc()函数中的字符串存放在堆空间中,堆空间只有在执行free 操作后才会释放,否则在进程执行过程中会一直有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值