C++中指针、地址、内存与字节的关系

        想必大家在刚开始学习C++时,经常会听到指针、地址、内存与字节的概念,但对于初学者,一个指针就理解的磕磕盼盼,很难分清上面几个概念的区别。下面给各位C++小萌新分享一下我对这几个概念的理解,可能不够专业,但一定能够帮助你对这几个概念的理解。 

1、字节

 大家在学刚学习C++时,一定见过这样的图表

数据类型占用空间
short(短整型)2字节
int(整型)4字节
long(长整型)4字节
long long (长长整型)8字节
float  (单精度)4字节
double (双精度)8字节
char (字符型)1字节
bool    (逻辑型)1字节

这里几字节到底代表什么?就以最常见的int型(4字节)来举例

        我们知道1字节=8bit,而计算机本身只能识别1与0且这种1与0就存储在bit中,那它是如何存储整数1314这种数据呢?实际上,1bit里面只能存储单个1或0并没有多大的意义,但是4字节共有32bit,这时候0与1的组合种类达到2^32种,其中每一种组合都代表一个数字,显而易见最多能代表的数字范围为-2^31~2^31-1。

        所以,整数1314这串数字在计算机中的表达相当于一连串的文件袋,1字节的意义就相当于一个箱子,而整数1314的文件袋比较多需要四个箱子才能装得下,有的数据如字符"A"文件袋就比较少只需要一个箱子即可。

2、内存

        这个就很简单了,箱子统称为内存,箱子的多少代表内存的大小。内存与字节的关系就相当于质量与kg的关系。

 3、地址

        上面说到1字节相当于一个箱子,一个大小为1KB的内存空间里有2^10个箱子,这么多箱子它在内存空间里是有序还是无序的?想必大家即使没学过计算机基本知识也能知道这么多箱子必然是有序的。那么如何实现有序呢?最简单的就是我们给每个箱子都编号,这编号是啥?其实这编号就是我们所说的地址,它能准确的告诉计算机某个箱子的位置。

        这时候一些小伙伴可能就要问了,为啥我返回某个int型变量的地址,它只返回一个地址,按理来说int型变量的存储需要四个箱子,所以计算机应该告诉我这四个箱子的编号,即返回四个地址。当你有这样的问题时,就代表你离理解它的距离很接近了。确实真正存储int型变量的箱子为四个,但我们约定俗成,规定返回int型变量地址时只需要返回四个箱子中第一个箱子的编号即首地址即可。 

        所以我们所说的地址有两个内容,首先是对于字节即箱子,地址是箱子的编号,即一个地址与1字节一一对应。其次是对于变量,我们所说的变量地址,实际上是存储变量所需n个箱子中第一个箱子的编号,即n个字节的首地址。

4、指针

        终于说到让无数C++学子魂牵梦绕的指针。指针到底是啥?我们首先来创建个指针然后将其直接打印。

	int num=1314;
	int *p=#
	cout<<"num地址:"<<&num<<endl;
	cout<<"指针p: "<<p<<endl;

 从打印结果我们发现p=&num,于是我们得出结论,指针就是地址。得出这样的结论只能说对了一半,我们接着实验继续往后看。

	int num=1314;
	int *p=&num;
	cout<<"num地址:"<<&num<<endl;
	cout<<"指针p: "<<p<<endl;
	cout<<"解指针p: "<<*p<<endl;

 通过解指针p我们很容易获得指针指向的变量num的值1314。如果指针只是一个地址,那我们能否都通过设置另外一种类型指针p2,将地址设为与p相同,最后通过解指针p2获得num的值呢?

	int num=1314;
	int *p=&num;
	cout<<"num地址:"<<&num<<endl;
	cout<<"指针p: "<<p<<endl;
	cout<<"解指针p: "<<*p<<endl;
	double *p2;
	p2=(double*)p;
	cout<<"指针p2: "<<p2<<endl;
	cout<<"解指针p2: "<<*p2<<endl;

         通过结果我们可知,即使p与p2的地址相同,p2解出来的结果却明显不是我们想要的。由此可知指针并不是单纯的一个地址,即使显示出来为一个地址。实际上指针还有一个隐藏属性偏移量,偏移量是啥?偏移量实际上就是就是告诉系统解指针的时候要往后数多少个箱子。int* p是往后数四个箱子,而double* p2是往后数8个箱子。那么偏移量由什么来确定呢?很显然其是由定义指针时的数据类型存储所需要的箱子数决定的。在解指针获得变量的值时,需要根据地址与偏移量再解释成对应的数据类型。

        我们再创建个指针int* p3,将p2中地址赋值给它,再解指针时看能不能正确获得num的值。

	int num=1314;
	int *p=&num;
	cout<<"num地址:"<<&num<<endl;
	cout<<"指针p: "<<p<<endl;
	cout<<"解指针p: "<<*p<<endl;
	double *p2;
	p2=(double*)p;
	cout<<"指针p2: "<<p2<<endl;
	cout<<"解指针p2: "<<*p2<<endl;
	int* p3;
	p3=(int*)p2;
	cout<<"指针p3: "<<p3<<endl;
	cout<<"解指针p3: "<<*p3<<endl;

 从结果来看p3可以正确获得num的值。

        归纳一下,指针是地址与偏移量两种属性的结合体。其中地址与变量地址相同,偏移量由定义指针时的数据类型决定,偏移量大小为对应数据类型存储所需字节数多少。在解指针获得指针所指向变量的值时,先根据指针的地址属性确定首地址,再根据指针的偏移量属性确定往后读取多少个字节,最后系统根据指针类型解释成对应类型的数据。

如有错误的地方欢迎指正交流。

  • 34
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值