内存地址、存储单元、指针等计算机基础概念
前言从大一一直困惑到研三的这几个概念今天静下心来总算是搞明白了,太开心太开心!!!!这里总结一下,分享给大家。1.内存地址计算机在执行程序时是由CPU从内存中读取指令,数据等,那么是怎么读取的呢?换句话说,是怎么找到的呢?就像快递员是怎么找到你的呢?答案当然是“地址”(address)了,你有居住地址,数据也有自己的地址,这个地址就是“内存地址”,如下一段程序:#include<s...
前言
从大一一直困惑到研三的这几个概念今天静下心来总算是搞明白了,太开心太开心!!!!
这里总结一下,分享给大家。
1.内存地址
计算机在执行程序时是由CPU从内存中读取指令,数据等,那么是怎么读取的呢?换句话说,是怎么找到的呢?就像快递员是怎么找到你的呢?答案当然是“地址”(address)了,你有居住地址,数据也有自己的地址,这个地址就是“内存地址”,如下一段程序:
#include<stdio.h>
int main()
{
int a = 10;
int b = 46465465;
printf("%p\n", &a);
system("pause");
return 0;
}
运行结果为:
如图,这个十六进制数就是变量a的地址,转变成十进制为:
那么这个地址是怎么分配的呢,接下来就要涉及到存储单元的概念了。
2.存储单元
存储单元一般应具有存储数据和读写数据的功能,以8位二进制作为一个存储单元,也就是一个字节。每个单元有一个地址,是一个整数编码,可以表示为二进制整数。程序中的变量和主存储器的存储单元相对应。变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。存储地址一般用十六进制数表示,意思就是每个存储单元都有自己唯一独立的数字作为表示,而每一个存储器地址中又存放着一组二进制(或十六进制)表示的数,通常称为该地址的内容,例如00001111、11010010等。
有了这个概念,这里就可以解释一下计算机的位数与所支持最大内存之间的关系,比如说32位的系统,32位系统的“32”位是指cpu的地址总线是32根,其最多能有2^32次方个地址,每个地址都有其独立唯一的编号,如下图:
4G = 2^32 乘以 8(bit),每8(bit)是一个字节,也是一个存储单元,都有其唯一独立的地址,那么32位系统一共能表示232次方个地址,每个地址是8bit,232乘以8等于2^35次方(bit),正好是4G的内存,那么64位系统最多支持多大内存呢?答案是2的32次方G,不过这么大是基本不可能的,当今计算机的寻址能力根本达不到,不过128G还是可以达到的。
这里有个链接,里面举了地址、数据以及其二进制表示对应于门牌号的例子,很贴切,可以体会一下。
3.指针
说完了计算机里的地址和在其中的数据,自然而然的引出指针的概念。
现在几乎任何需要速度的需求或者面向硬件的编程都会用C++编写,这么难为什么还要用?当然不是纯粹为了挑战未登峰,而是因为C++/C快啊,它们能直接对计算机里的地址进行操作,你说快不快?那么如何对地址进行操作呢,C语言的创造者给出的答案是指针,这个让我又爱又恨的东西。
C语言中函数的参数传递分为按值传递和按引用传递,按值传递是拷贝一个数据进入函数进行处理,那么按引用传递就是把数据的地址直接传递给函数。
下面用例子说明:
#include<stdio.h>
void newval(int *);
int main()
{
int a = 10;
printf("before a value:%d\n", a);
printf("before a address%u\n", &a);
newval(&a);
printf("after a value:%d\n", a);
printf("after a address:%u\n", &a);
system("pause");
return 0;
}
void newval(int *xnum)
{
*xnum = *xnum + 1;
}
结果为:
有结果可以看出,变量a的地址没变,但是其地址指向的变量却变了。
再一个例子:
#include<stdio.h>
int main()
{
int a = 'e';
printf("before a value:%d\n", a);
printf("before a address%u\n", &a);
printf("before a value:%d\n", a+1);
printf("after a address:%u\n", &a+1);
printf("after a address:%d\n", *&a);
system("pause");
return 0;
}
&a+1的意思就是取a的地址,然后在其地址的编号后加一个“a”数据类型大小的空间,结果为:
注意到地址数值增加了4,也就是一个int数据结构的大小,即四个字节,同理,如果是char数据结构,那么就是增加一个字节。
理解了指针之后,就可以理解在把地址传入函数以后,就可以通过修改地址也就是指针指向的值来对调用函数的值进行操作,这个就叫做引用传递。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)