C语言-指针

指针概念

程序运行的数据都是存储在内存中的不同区域,因此访问某个变量的数据时就得先能找到对应的内存区域,然后取出数据,为了便于内存的操作,因此将内存以字节为单位进行存储区域的划分,并且给每个区域进行了编号——地址

指针:内存地址

指针变量拥有一块空间,空间内部可以存储一个内存地址(指向另一块空间),通过对指针变量进行解引用,进而访问所指向空间中的数据。

🔴类型

  • 指针自身是指针类型,有一块空间保存地址;

  • 指针变量保存的地址所指向的空间类型,描述了指向的空间可以有多大。

p指针指向的就是a空间的起始地址。

🔵指针的大小

  • 32位平台下,指针变量所占空间大小是4字节;

  • 64位平台下,指针变量所占空间大小是8字节;

在计算机中,CPU访问内存是通过地址总线,告诉内存要访问哪一块内存。

32位平台,CPU地址总线共有32根,以高低电平表示01组合共有2^32种,因此所能访问的地址范围就是0~2^32-1;

64位平台,CPU地址总线共有64根,以高低电平表示01组合共有2^64种,因此所能访问的地址范围就是0~2^64-1;

因此,指针变量的空间想要保存一个完整的地址,在32位平台下就需要32个比特位-4字节,64位平台下就需要64个比特位-8字节。

🔴指针指向空间的访问

通过对指针解引用进行访问。

🔵野指针

指针所指向的空间不能被正常访问。

危害:野指针的访问随时有可能

1.定义一个指针变量后,没有对这个指针变量进行初始化

定义一个指针变量,为指针开辟了内存空间,空间中如果不进行初始化,里边有什么数据是未知的。因此,这个指针变量所指向的位置也就是未知的,是大概率不能访问的。

2.指针的越界访问

在访问连续空间时,控制不当导致访问了不该访问的位置。

p指向了数组首元素, p+1指向了数组的第1个元素……

p是一个指针变量,保存的是地址,对p进行+1,就是p加上一个指向类型大小。

比如,int *p; p+1实际上就是对p所保存的地址+4,因为指向int类型大小为4字节。

注:这里的&arr[3]不算越界访问,因为这里只是获取了指定位置元素的地址,并没有访问这个地址所指向的空间的数据。但是*(p+3)是越界访问,因为访问了越界位置的数据。

有时候程序的越界访问并不会立即导致程序崩溃,因为是否发生内存访问错误取决于编译器对于越界访问的检测机制。编译器设置了一个 哨兵位作为越界检测位置(不一定就在正常空间的结束位置)。

3.指针所指向的空间被释放

a变量是在func函数中被定义的,所属的作用域就是在func函数中,函数一旦退出运行,则a变量的空间就会被释放掉。因此,一个函数如果返回的是一块局部变量的地址,是没有意义的,因为函数运行结束空间就会被释放掉。上面代码返回的就是野指针。

如果修改为:

这时,static修饰局部变量,修改了局部变量的生命周期,导致a变量的空间不会被释放,不会出现野指针。

🔴指针的运算

指针的加减并不是以字节为单位进行加减,而是以指向空间的类型大小为单位进行偏移或者加减。

关系运算:比大小。

示例:通过指针实现字符串逆置。
运行结果:dlrow olleh

🔵指针和数组

数组名不允许++,数组名是首元素的地址,可以看做一个数值常量,不允许被修改;同时,数组名数组名不仅代表数组首元素的地址,也代表数组,因此不能进行自增自减运算。

数组名是数组首元素的地址,可以当做指针使用,通过指针+-偏移后解引用进行访问;
同样 指针变量也可以当做一个数组名来使用,通过 下标进行访问。
指针在转换为数组访问的时候,[0]是从自己指向的位置进行计算的。

虽然实参看起来传递的是数组,但实际上是数组首元素的地址,因此,形参就是对应首元素地址的指针变量。形参不能通过sizeof获取到数组的大小,而是获取到了指针的大小,所以,通过数组传参时,通常会多加一个参数来传递数组中的元素个数,

🔴二级指针

表示的是一个指向指针变量空间的指针(有几个*就是几级指针)。

多级指针的大小本质上还是指针大小。

🔵指针数组

指针数组就是一个或多个指针数据的集合。

指针数组就是存储指针的数组,数组中的元素类型都是指针类型。

定义:int *arr[10];

  • [ ]的优先级比*高,因此arr先与[ ]结合,表示arr是个数组,数组中有10个元素;

  • arr[10]再与*结合,表示数组中的元素是指针类型;

  • 最后 *arr[10]再与int结合,表示数组中的元素是指针,指针指向的空间类型是int。

arr是个数组,数组中有10个int*类型的元素。
示例:编写一个函数交换两个int*类型的数据。

如果要通过传参的形式修改一个变量的数据,那就传递这个变量的地址——传址操作。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值