第6节-指针

目录

1.指针是什么

1.1.内存

1.2.编译器中解释地址

 1.3.地址的使用

2.指针和指针类型

2.1.指针+-整数

2.2.指针的解引用

2.3.例子

3.野指针

3.1.野指针成因

3.2.如何规避野指针

4.指针运算

4.1.指针 +-  整数

4.2.指针 - 指针

4.2.1.指针 - 指针

4.2.2.例子(※)

4.3.指针的关系运算

5.指针和数组

6.二级指针

7.指针数组


1.指针是什么

指针理解的2个要点:
1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中说的指针通常指的是指针变量

1.1.内存

内存

注:

1.内存被划分为一个个小的内存单元

2.一个基本的内存单元的大小是一个字节

3.内存单元的编号被称为是一个地址,地址也称为指针。(内存单元编号=地址=指针)

4.编号的产生:现在有32位机器和64位机器,以32位机器为例

32位机器有32跟地址线(物理电线),物理电线通电,通电后会有高电平和低电平,转化为数字就是1/0。 32跟地址线会产生不同的32位数字,如下

00000000000000000000000000000000

00000000000000000000000000000001

......

11111111111111111111111111111110

11111111111111111111111111111111

将这些编号作为内存单元的编号,即地址,也就是指针

5.这32根地址线可以产生2^{32}个32位数字,一个32位数字作为一个地址可以产生2^{32}

个地址 ,一个地址管理一个字节,2^{32}个地址可以管理2^{32}个字节空间,2^{32}转化为十进制数为4294967296

4294967296 byte(字节)=4194304 KB= 4096 MB=4 GB

6.32位数字作为地址需要32个bit(比特)空间来存储,而32个bit空间是4个字节,所以存一个地址需要4个字节空间,一个指针变量就是存储该地址,因此一个指针变量占4个字节。如下图(同理若在64位机器下一个指针变量就需要8个字节来存储)

1.2.编译器中解释地址

 注:

1.内存中第一列显示的是地址,第二列是内存数据布局,第三列是以ASCII的形式解析第二列内存中的数据(不一定准确)

2.第二列中0a 00 00 00就是变量a所占的四个字节,其中每相邻的两位各占一个字节,

10的二进制数为:00000000 00000000 00000000 00001010

10转换为16进制数为:00 00 00 0a

内存里就是将该16进制数倒着放进去了(内存中存的是2进制数,只不过显示时显示十六进制)

当我们把显示列数改为1时,就更容易理解了,如下图

 1.3.地址的使用

1.打印地址

 2.存储地址

 注:

1.这里的*pa就是指针变量(通常口头上叫做指针)

2.当a是四个字节的时候&a其实拿到的是这四个字节中第一个字节的地址

3.int* pa其中,*代表pa是一个指针变量,前面的int代表该指针变量指向的变量的数据类型


2.指针和指针类型

2.1.指针+-整数

注:

1.虽然指针类型不一样,但是他们都是申请四个字节空间,里面存的地址是一样的

2.指针类型的意义决定了指针向前或者向后走一步,走多大距离(单位是字节)

整型指针向后走一步走了4个字节

字符指针向后走一步走了1个字节

2.2.指针的解引用

注:

1.虽然不同的指针类型都是创建4个(8个)空间来存储指针变量的,但是其本质是有差别的

2.指针类型的意义决定了在解引用时一次能访问几个字节(指针的权限)

char* 决定解引用能访问 1个字节

int* 决定解引用能访问 4个字节

float* 决定解引用能访问 4个字节

double* 决定解引用能访问 8个字节

2.3.例子

描述:

创建一个整型数组,10个元素

1.初始化数组的内容是1-10

2.倒着打印数组内容


3.野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

3.1.野指针成因

1. 指针未初始化

注:对指针变量p没有初始化,所以p没有指向任何固定对象

2. 指针越界访问

注:当i=10时,指针变量p会越界访问到数组后面的一个整型空间,此时指针变量p变成一个野指针

3. 指针指向的空间释放 

 注:这里指针变量p指向了a空间,但是函数调用完后,a地址的使用权限被收回去了,再通过p来访问该地址,该地址已经不属于这个程序了,此时p称为野指针。

3.2.如何规避野指针

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

1. 指针初始化

2. 小心指针越界(不要出现下面越界的访问)

3. 指针指向空间释放及时置NULL

 4. 避免返回局部变量的地址

5. 指针使用之前检查有效性

注:

1.指针为空,我们不去使用它,指针不为空,我们再去使用它。

2.空指针是不允许去访问的


4.指针运算

\bullet指针  +-   整数
\bullet指针 -  指针
\bullet指针的关系运算

4.1.指针 +-  整数

4.2.指针 - 指针

4.2.1.指针 - 指针

 注:

1.两个地址相减的绝对值得到的是这两个地址间元素的个数

2.指针 - 指针 的前提是两个指针指向同一块空间,下面代码是错误的。

	int a = 10;
	char c = 'w';
	&a - &c;    //err

4.2.2.例子(※)

描述:

用指针 - 指针的方法模拟strlen函数

4.3.指针的关系运算

for(vp = &values[N_VALUES]; vp > &values[0];)
{
    *--vp = 0; 
}
代码简化 , 这将代码修改如下
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--) 
{
    *vp = 0; 
}

注:指针只是访问数组外元素,这不是越界


5.指针和数组

数组和指针本身是两种事物

联系就是:可以通过指针来访问数组


6.二级指针

知识点一:

注:

1.int** ppa中两个*中后面的*是单独的,表示ppa是一个指针,前面的*和int是一组,因为ppa指向的是pa,而pa的数据类型是int*,所以这里应该是int*(ppa指向谁,*的前面就写谁的数据类型)(int*** pppa同理)

知识点二:

注:对ppa进行一次解引用指向指针变量pa,再进行解引用就指向了变量a


7.指针数组

存放指针的数组

 注:

1.指针数组不完全初始化,其他指针默认为空指针NULL(0和NULL是完全一样的)

2.arr3是一个数组,有五个元素,每个元素是一个整形指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

随风张幔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值