冰冰学习笔记:指针 指针 指针(1)

想必学习C语言的小伙伴们都知道,指针是非常难得知识点,一提到指针就头疼,确实,指针就是难搞。今天我先梳理一下我所学习得指针知识,记录一下我的学习笔记,毕竟我也是个初学者。

1、什么是指针?

指针是内存中一个最小单元的编号,也就是地址,平时我们口语中所说的指针,通常指的就是指针变量,而指针变量就是用来存放内存地址的变量。

也就是说你存储了一个变量,存到哪里了?怎么找到呢?

内存空间开辟出一个个空间用来存储这些变量,并且对变量进行编号,犹如你家的门牌号码一样, 要想找到你,就得找到你的地址,而内存的地址也是这样,找到这个变量就得通过存储的地址来寻找。

此时,我们创建了一个整形变量a=10;并且把它存放在了内存中。

那它的地址是什么?怎么取出来?

现在引入一个操作符:“&”

不是逻辑与而是取地址操作符

&a:就意味着取出a的地址,也就是a存储的位置编号。

取出来了a的地址,必须要有东西接收它呀。

所以就需要指针变量来接收变量的地址。也就是说通过&(取地址操作符)取出变量的内存的起始地址,并且把地址存放到一个变量中,这个变量就是我们所说的指针变量。

p就是指针变量,用来存放a的地址。并且,存放在指针中的值都被当成地址处理。

一个小的单元是一个字节。

拿到了存放a地址的指针变量p,对p进行解引用便可以通过地址找到a存放的内容

解引用操作符 “ * ”,*p就是对p进行解引用。

 

 地址有多大呢?

这里直接给出结论:

32 位的机器上,地址是 32 0 或者 1 组成二进制序列,那地址就得用 4 个字节的空间来存储,所以
一个指针变量的大小就应该是4 个字节。
64 位机器上,如果有 64 个地址线,那一个指针变量的大小是 8 个字节,才能存放一个地址。

 2、指针和指针类型

 变量有不同的类型,什么整形,浮点型,字符类型……那指针是否又有类型呢?

有的

 

我们知道,a是整形变量 &a存放到p中,p是一个指针变量,它存放的是整形的地址,所以应该是整形指针变量。

下面给出指针的类型

 也就是说指针的定义方式是:类型+*

char*  用来存放char类型的变量地址。

int*  用来存放int类型的变量地址。

………

 指针类型决定了指针解引用权限有多大,决定了指针走一步,能走多远(步长)。

int指针解引用访问4个字节

char指针解引用访问1个字节

float指针解引用访问4个字节

double指针解引用访问8个字节

我们了解完指针变量以及指针的类型之后,就看看指针的其他用法。

3、指针用法

指针+-整数

 这段代码中我们看到,int*和char*类型的指针变量+1后变化的大小不同,int*类型向后移动了4个字节,char*类型向后移动了1个字节。所以指针的类型决定了指针向前向后走一步的大小。

同样,在解引用操作中char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

野指针

野指针是啥?

野指针就是指针指向的位置是不可知的,随机的,不正确的,没有明确的限制的。

形成野指针的原因:

1、指针未初始化

 

2、指针越界访问

指针越界访问, 指针指向的范围超出了数组arr的范围时,p就是野指针。

3、指针指向的空间释放

 如何避免野指针?

1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放及时将其赋值为 NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

若当前不知道p应该初始化为什么地址的时候,直接初始化为NULL

指针-指针

指针-指针得到的是指针和指针之间的元素个数,但是相减具有前提即两个指针指向同一个空间。

最简单的例子就是书写strlen函数

切忌:指针加指针无意义

 指针用法

用指针打印数组内容:

 

 指针的关系运算

指针变量p所存放的是arr数组最后元素的后一块空间的地址,每次与数组第一个元素的地址进行比较。如果p>第一元素的地址,则进入循环。

进入循环后p先向前移动一个地址,找到arr数组的最后一个元素,然后解引用将其赋值为0。

循环往复,最终将数组元素全部初始化为0。

再看下一段代码:

这段代码的意思是:p储存为数组最后一个元素的地址,与数组第一个元素的地址进行比较。如果p>=第一个元素的地址。则进入循环。

然后解引用并且赋值为0。

循环往复,最终所有的元素都变成了0。

但是

这样虽然好理解,却不建议这样写。因为这有可能在编译器上无法编译,因为它不符合标准规定。

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。

4、指针和数组

 数组名就是首元素的地址

 所以访问数组元素也可以这也写

 看下面一个等式:

arr[2] <==> *(arr+2) <==> *(p+2) <==> *(2+p) <==> *(2+arr) == 2[arr]
2[arr] <==> *(2+arr)

 是否成立呢?答案是成立的。

编译器在执行arr[2]时会将其转化为*(arr+2),而arr为数组首元素地址,存放到p里面,所以p等价于arr,加法具有交换律,所以*(arr+2)=*(2+arr),所以可以写成2[arr]。

本质是因为 [ ] 是一个操作符,2和arr是两个操作数。

5、二级指针

二级指针:存放指针变量地址的指针

 

 

 二级指针解引用**pa来访问a

指针数组

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bingbing~bang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值