指针详解(1)

目录

1. 指针是什么?

2. 指针和指针类型

指针类型的意义1:

指针类型的意义2:

注意:

3.野指针

野指针成因

1)指针未初始化

2)指针越界访问

​编辑 3)指针指向的空间释放

​编辑如何规避野指针

1. 指针是什么?

指针理解的2个要点:

1. 指针是内存中一个最小单元的编号,也就是地址

2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

总结:指针就是地址,口语中说的指针通常指的是指针变量。

指针变量:

我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个 变量就是指针变量

#include<stdio.h>
int main()
{
	int a = 10;//a是整型变量,占用4个字节的空间

	int* pa = &a;
	//pa是指针变量,用来存放地址
	//本质上,指针就是地址
	//口语中说的指针,其实就是指针变量,指针变量是用来存放地址的变量
	//指针变量里面存放的是地址,而通过这个地址,就可以找到一个内存单元
	return 0;
}

对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电 平(低电压)就是(1或者0);

那么32根地址线产生的地址就会是:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

...

11111111   11111111   11111111   11111111

这里就有2的32次方个地址。

每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB)4G的空闲进行编址。

这里我们就明白:

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

那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。

总结: 指针变量是用来存放地址的,地址是唯一标示一块地址空间的。

            指针的大小在32位平台是4个字节,在64位平台是8个字节。

2. 指针和指针类型

这里我们在讨论一下:

指针的类型我们都知道,变量有不同的类型,整形,浮点型等。

那指针有没有类型呢? 准确的说:有的。

指针类型的意义1:

当指针类型是int*时,对pa解引用时,可以访问4个字节

 当指针类型是char*时,对pc解引用时,可以访问1个字节

#include<stdio.h>
int main()
{
	//0 1 2  3  4   5 6 7 8 9  a    b c d e f
	//0 1 10 11 100  ……        1010   
    //0001 0001 0010 0010 0011 0011 0100 0100
	int a = 0x11223344;//十六进制,2个十六进制位代表一个字节
	                   //一个十六进制位可以翻译成4个二进制位
	                   //8个二进制位代表一个字节
	//int* pa = &a;
	//*pa = 0;

	char* pc = &a;//编译器会报警告
	//如果不想编译器报警告,可以将&a强制类型转换
	//char* pc = (char*)&a;
	//问:pc有没有能力存下a的地址?
	//答:有,因为pc也是指针变量,占用4个字节,a的地址也是4个字节
	*pc = 0;
	//结论:指针类型决定指针在被解引用的时候访问了几个字节
	//如果是int*的指针,解引用访问4个字节
	//如果是char*的指针,解引用访问1个字节
	//如果是double*的指针,解引用访问8个字节

	return 0;
}

指针类型的意义2:

 

#include<stdio.h>
int main()
{
	int a = 0x11223344;
	int* pa = &a;
	char* pc = (char*)&a;

	printf("pa=%p\n", pa);
	printf("pa+1=%p\n", pa + 1);

	printf("pc=%p\n", pc);
	printf("pc+1=%p\n", pc + 1);

	//结论2:指针的类型决定了指针+或-1操作的时候,跳过几个字节;决定了指针的步长。
	//int* 的指针 + 1——跳过4个字节;
	//char* 的指针 + 1——跳过1个字节;
	//double* 的指针 + 1——跳过8个字节。
    //加减不仅可以是,还可以是任意的整数,比如int*的指针类型+2,表示跳过了8个字节
    //当我们希望指针访问内存空间时,一个字节一个字节的访问时,我们可以使用char*指针
    //同理,当希望4个字节4个字节的访问时,可以使用int*的指针
    //可以通过类型转换,转换成我们需要的指针

	return 0;
}

指针 + - 整数

 总结:指针的类型决定了指针向前或者向后走一步有多大(距离)。

指针的解引用

总结: 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。

比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

注意:

分析:

 

 所以,两个指针类型不能混用。

#include<stdio.h>
int main()
{
	int a = 0;

	int* pi = &a;//pi解引用访问4个字节,pi+1跳过4个字节
	float* pf = &a;//pf解引用访问也是4个字节,pf+1也是跳过4个字节
	//问:int*和flaot*是不是就可以通用?
	//答:不是。因为站在pi的角度,它认为它指向的内存里面放的是整型的数据
	//             站在pf的角度,它认为它指向的内存里面放的是浮点型的数据
	//*pi = 100;
	*pf = 100.0;
	return 0;
}

3.野指针

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

野指针成因

1)指针未初始化

2)指针越界访问

 当指针指向的范围超出数组arr的范围时,p就是野指针

 3)指针指向的空间释放

如何规避野指针

1)指针初始化(当不知道给指针初始化为什么时,可以给它赋NULL(0)

那如果想给*p2赋值,该如何写呢? 

 如果p2真的不是空指针,说明它已经有明确的指向了,这时候我们可以使用它了。

 2)小心指针越界  

3)指针指向空间释放即使置NULL

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值