各位小伙伴们好久不见 (●'◡'●)
文章还存在很多不足,请各位大佬,于晏,彦祖,亦菲们多多提供建议。小罗一定会提供更好的文章
在讲内存和地址之前,我想先举一个生活案例:
当你处在一栋没有标明房间号码的公寓楼前 ,假设让你去找房间1003,你会找的到吗?我想是很困难的,所以我们需要房间号码牌。拥有了号码牌,你可以简单随意的就可以找到目标房间。这样也可以极大的提高我们的效率,在计算机中也存在类似的想法。
1.内存和地址补充一下课外知识:
内存(Memory)是计算机的重要部件,也称内存储器和主存储器,它用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存性能的强弱影响计算机整体发挥的水平。只要计算机开始运行,操作系统就会把需要运算的数据从内存调到CPU中进行运算,当运算完成,CPU将结果传送出来。
内存的运行决定计算机整体运行快慢。
我们平常使用的程序,如:Windows操作系统、打字软件、游戏软件等。一般安装在硬盘等外存上,但仅此是不能使用其功能,必须把它们调入内存中运行,才能真正使用其功能。
我们平时输入一段文字或玩一个游戏,其实是在内存中进行。好比在一个书房,存放书籍的书架和书柜相当于电脑的外存,我们工作的办公桌相当于内存。
通常,我们把要永久保存、大量数据存储在外存上,把一些临时或少量的数据和程序放在内存上。当然,内存的好坏会直接影响电脑的运行速度。
内存是暂时存储程序以及数据的地方。当我们使用WPS处理文稿时,当你在键盘上敲入字符时,它被存入内存中。当你选择存盘时,内存中的数据才会被存入硬(磁)盘。
如果把上面的例子对照到计算机中,会是怎么样呢?
1 Byte = 8 bit
1 KB = 1024 Byte
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB
ps: 是不是有点吃惊,1 MB 竟然不是 1000 KB,不用担心小伙伴们,我当时也是很天真的认为如此。但现在大家有印象就好,也可以拿这个简单的冷知识去 ”坑一坑“ 好朋友。(●'◡'●)
内存单元的编号其实就是地址。
其中每个内存单元可以存放八个bit,就好比在学校的寝室里,寝室有寝室号(地址),一个寝室(内存单元)可以住8个人(bit)。
这样计算机可以通过地址可以快速找到数据的位置(内存空间)。
而在C语言中 地址又被称为指针。
2. 指针变量和地址
2.1 取地址操作符(&)
0x000000DB822FFA34
0x000000DB822FFA35
0x000000DB822FFA36
0x000000DB822FFA37
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;// 此步骤表明将a的地址取出 放入变量p中
//详细解读
// 指针变量p 的类型是 (int*)
// 而(int) 表明变量指向的对象是int类型 (*)表明p 是指针变量
//&是取地址操作符 p 是指针变量 指针变量p中存储的是变量a的地址
//无论你赋什么值 给指针变量 它都会当作地址处理
printf("%p\n", p);
//编号 == 指针 == 地址
}
虽然&a得到的是a的第一个地址,但a是int类型占四个字节,所有我们可以顺着思路往下推,就能得到a的所有字节的地址。
2.2 指针变量和解引用操作符(*)
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;
//那么存储现在知道怎么做了,那要使用的话怎么办呢?
*p;// (*)解引用操作符 作用:通过找p中储存的地址, 从而找到原地址(a)对应的值
*p = 0; // 这里就是p通过(*) 解引用找到地址, 并且修改a内容 变为0
// ps: 不知有没有小伙伴想到
// (&) 可以取地址 (*) 可以解地址 ,那有没有可能他们两个放在一起时就可以互相抵消呢?
// 答案是可以的 以此处为例: *p 实际上就是 *&a 那么结果就是a 所对应的值
//而 众多的指针类型 你或许会认为他们所占的空间不太相同 但实际上他们所占字节是完全相同的
//原因就与地址线的数量有关
//在32位环境下 指针变量大小所占字节都是 4个字节
//在64位环境下 指针变量大小所占字节都是 8个字节(下图会简单解释原因)
//指针变量大小 于它类型无关
//指针类型决定了指针进行解引用操作符的时候访问几个字节,也就是决定了指针有多大权限!
return 0;
}
我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表示0,1【电脉冲有无】,那么⼀根线,就能表⽰2种含义,2根线就能表示4种含 义,依次类推。32根地址线,就能表示2^32种含 义,每⼀种含义都代表⼀个地址。那么32位地址线 就对应32个bit位 , 32bit = 4Byte。这就是为什么在32位环境下,指针变量类型的大小都是4个字节。
int a = 0;
int* pa = &a;
char* pc = &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);
//指针类型决定了指针 +1 , -1 向后走几个字节
// int* +1 ---> 向后走4个字节
// char* +1 ---> 向后走1个字节
//结论:指针的类型决定了指针向前或者向后走⼀步有多大(距离)
指针类型的作用在解应用的时候,就体现出来了,char*类型解引用时只能访问一个字节,而int*类型解引用可以访问4个字节。
3.2 void*指针


4. const修饰指针
学习之前我们先简单来看一下const的意思,这样能更好的帮助我们去理解const在c语言中的作用
4.1 const修饰变量
4.2 const修饰指针变量
情况1 const 在 * 右边
情况2 const 在 * 左边
情况3 * 两边都有const 这表明 所有都不可以被修改
到此我的c语言指针科普,先告一段落,欲知后事如何,且听下回分解。
再次感谢小伙伴们的 点赞,支持和评论。
文章还有众多不足,请大家多多指正。
在下一定当全力以赴。