轻松拿下指针(1)

文章目录

一、内存和地址
二、指针变量和地址
三、指针变量的意义
四、总结

提示:以下是本篇文章正文内容,下面案例可供参考

一、内存和地址

1.1内存

说到内存,我们可以举一个很直观的例子:

假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩, 如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给每个房间编上号。也可以说给这个房间一个地址,有了这个房间地址就可以快速找到房间,达到目的。
那么如果对照到计算机的情况又是如何,我们知道计算机上(cpu)在处理数据的时候是要从内存中获取数据的,处理完数据之后就会返回内存。我们常常买电脑的时候,电脑上的内存是4GB/8GB/16GB等等那这些内存空间是如何高效的管理呢?

#内存的使用和管理:

1.内存划分为一个个内存单元,每个内存单元的大小是1个字节(8bit);

2.每个内存单位都有一个编号,有了这个内存单元的编号,cpu就可以快速找到一个内存空间;

3.c语言中给地址起了一个姓的名词:指针。

1.2编址

计算机内是有很多的硬件单元,而硬件单元是要互相协同工作的(相互之间能够进行数据传递)。但是硬件之间是相互独立的,那么我们就想到,用“线”,连起来,而cup和内存之间有大量的数据交互的,所以两者要必须用“线”连起来,我们就来了解一组线——“地址总线”。

如图,cpu访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,而因为内存中字节很多,所以需要给内存进行编制。我们可以简单理解,32位机器有32根地址总线,每根线只有两态,表⽰0,1【电脉冲有⽆】,那么 ⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰2^32种含义,每⼀种含义都代表⼀个地址。

二、指针变量和地址

2.1 取地址操作符(&)

  我们可以看到整型 a 有四个字节,每个字节都有一个地址,当我们把 a 的地址打印出来的结果就是“0x0075F948",也就是第一个字节的地址,当我们取地址a的时候,取到的地址是它第一个字节的地址,当我们知道第一个字节的地址时,自然也就能推断出第二第三第四个字节的地址。

2.2 指针变量和解引用操作符 "*"

  当我们通过取地址操作符‘&’拿到的地址是一个数值“0x0075F948",这个数值有时候也需要存储起来的,那我们把这样的地址值存放在哪里呢——‘指针变量’。

#include <stdio.h>
int main()
{
	int a = 20;
	//&a;//& 取地址操作符,拿到变量a的地址
	
	int* pa = &a;//pa是一个变量,这变量是用来存放地址(指针)的,pa叫做指针变量。

	return 0;
}

这里 pa 左边写的是 int* ,* 是在说明pa是指针变量,而前面的 int 是在说明pa指向的是整型(int)类型的对象。

那如果有一个 char 类型的 ‘b',’b‘的地址要存放在什么类型的指针变量中呢?答案就是 :

int main()
{
	 char b = 20;
	
	
	 char* pb = &b;
	return 0;
}

2.3 解引用操作符
我们将地址保存起来,未来是要使用的,那怎么使用呢?
C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针) 指向的对象,这⾥必须学习⼀个操作符叫解引用操作符(*)。比如:
int main()
{
	int a = 100;
	int* pa = &a;
	*pa = 0;
	return 0;
}

*pa的意思就是通过pa中存放的 a 的地址,找到了所指向的空间,*pa其实就是 a 变量了,所以*pa=0,就是把 a 改成了 0。

2.4 指针变量的大小

那么上述的指针pa有多长呢? 首先我们要弄清楚几个问题

1.指针变量是用来干什么的呢?(是用来存放地址的,地址的存放需要多大空间,那么指针变量的大小就是多大)

前⾯的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4 个字节才能存储。同理64位机器一个地址就是64个二进制位组成的二进制序列,存储起来就需要8个字节的空间,指针变量的大小就是8个字节。下面我们可以分别在x86环境(32位环境)和x64(64位环境)测试一下‘pa’的大小到底是多少:

所i我们可以得出:

32位平台下地址是32个bit位,指针变量大小是4个字节
64位平台下地址是64个bit位,指针变量大小是8个字节
注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

三、指针变量的意义

这里可能有的同学就会有疑问,指针类型有什么意思?既然指针变量的大小和类型无关,只要是指针变量,在同一个平台下,大小都是一样的,为什么还存在那么多指针类型呢?
3.1 指针的解引用

 #指针的类型决定了它解引用操作时候的一种属性

  大家可以对比一下这两幅代码,很直观得展现出代码1会将n的4个字节全部改为0,但是代码2只是将n的第一个字节改为0。为什么会出现这种情况?

  是因为如果我们对一个整型指针变量解引用时,一次会访问4个字节,而如果对一个字符型指针变量解引用时,一次只会访问1个字节

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

3.2 指针+-整数
int main()
{
	int a = 20;
	int* pa = &a;
	char* pc = &a;
	printf("&a = %p\n", &a);
	printf("pa = %p\n", pa); 
	printf("pc = %p\n", pc);

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

	return 0;
}

  我们可以看到,int*类型的指针变量+1跳过了4个字节,char*类型的指针+1跳过了一个字节。那既然指针可以+1,那也可以-1,所以指针的类型决定了指针向前或者后退一步的距离。

3.3 void*指针

void*——无具体类型的指针,这种类型的指针可以用来接受任意类型地址。但是不能直接进行指针的+-整数和解引用的运算。

int main()
{
	int a = 10;
	void* pa = &a;
	void* pc = &a;

	*pa = 10;
	*pc = 0;
	return 0;
}

   这里我们可以看到, void* 类型的指针可以接收不同类型的地址,但是无法直接进行指针运算。
⼀般 void* 类型的指针是使用在函数参数的部分,用来接收不同类型数据的地址,这样的设计可以
实现泛型编程的效果。

总结

以上就是对指针一个初步的认识,往后我们会更加深入地对指针进行学习了解。

希望对大家有帮助,谢谢大家!

  • 44
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值