内存和地址
在讲解内存之前,举个生活中里案例,方便大家理解:
假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩,如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给每个房间编上号,有了房间号,如果你的朋友得到房间号,就可以快速的找房间,找到你
其实这里的内存就相当对于宿舍,一个字节空间可以存放八个比特位,就像同学住在八人间,每个人都是一个比特位,每个内存单元也有一个编号,就相当于宿舍门牌号(也叫做地址)
内存单元的编号 == 地址 == 指针
其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。
计算机中常⻅的单位(补充):
⼀个⽐特位可以存储⼀个2进制的位1或者0
1Byte = 8bit
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
1 指针变量和地址
1,取地址操作符(&)
从图片的最右侧可以看到内存地址,上述的代码就是创建了整型变量a,内存中申请4个字节,⽤于存放整数10,其中每个字节都有地址,上图中4个字节的地址分别是
那如何取地址,就要用到去地址操作符&,
可以看到打印出0133FB04,这里其实&a取出的是a所占四个字节的大小地址。
2,指针变量
那我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:0x006FFD70,这个数值有时候也是需要存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?答案是:指针变量中。
#include<stdio.h>
int main()
{
int a = 20;
int *p = &a;//取出a的地址存储在指针变量p中
printf("%p\n", &a);
return 0;
}
我们看到p的类型是 int*,这里*是在说明pa的指针变量,而前面的int是在说明p指向的类型是int类型的对象
用这样一个图方便大家理解
3,解引用操作符
地址就是要找到⼀个房间,在房间⾥可以拿去或者存放物品。
C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象,下来学习一下解引用操作符(*)
*pa的意思就是通过p中存放的地址,找到指向的空间,p其实就是a变量了;所以pa= 0,这个操作符是把a改成了5.至于为什么要繁琐操作这一步,慢慢大家学习就理解了,这里先了解就可以了
2 指针变量的大小
32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char *));
printf("%zd\n", sizeof(short *));
printf("%zd\n", sizeof(int *));
printf("%zd\n", sizeof(double *));
return 0;
}
同一段代码在不同的环境下输出的值不一样
结论:
• 32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。
3 指针的解引⽤
#include <stdio.h>
int main()
{
int n = 0x11223344;
int *pi = &n;
*pi = 0;
return 0;
}
//第二个代码
#include <stdio.h>
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
*pc = 0;
return 0;
}
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。