1.内存和地址
1.1内存
在讲内存和地址之前,我们想有个生活中的案例:
假设有一栋宿舍楼,把你放在楼里,楼上有100个房间,但是房间没有编号,你的一个朋友来找你玩儿,如果想找到你,就得安一个房子去找,这样效率很低。但是我们如果根据楼层和楼层的房间情况,应每个房间边上号有的房间号,如果你的朋友得到房间号,就可以快速地找房间找到你。
生活中每一个房间有的房间号就能提高效率,能快速的找到房间。
如果把上面的例子对照到计算中又是怎么样的呢?我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中。那我们买电脑的时候,电脑上有内存是8GB/16GB/32GB的。但这些内存空间如何高效的管理呢?
其实也是把内存划分为一个个的内存单元,每个内存单元的大小取一个字节。
计算机中常见的单位:
- bit - 比特位 1byte = 8bit
- byte - 字节 1KB=1024byte
- KB 1MB=1024KB
- MB 1GB=1024MB
- GB 1TB=1024GB
- TB 1PB=1024TB
- PB
每个内存单元相当于一个学生宿舍的一个人。自己的空间里面能放八个比特位,就好比同学们住的八人间,每个人是一个比特位。
每个内衣寸单元也都有一个编号。这个编号就相当于宿舍房间的门牌号。有了这个内存单元的编号,CPU就可以快速找到一个内存空间。
内存 | |
0XFFFFFFFF | 1个字节 |
0XFFFFFFFE | 1个字节 |
1个字节 | |
1个字节 | |
0X00000001 | 1个字节 |
0X00000000 | 1个字节 |
生活中我们把门牌号也叫地址在计算机中,我 们把内存单元的编号也称为地址。C语言中给 地址起了新的名字叫指针。
所以我们可以理解为:
内存单元的编号==地址==指针
2.指针变量和地址
2.1取地址操作符(&)
比如上述代码就是创建了整型变量。a内存中申请四个字节用于存放整数0X11223344,其中每个字节都有地址(一个字节一个地址)。
0X表示16进制,即11223344是个16进制数。
1个字节是8个比特位,一个比特位可以存放一个二进制数,即一个字节可存放16个二进制数,进而我们可以推断出,一个字节可以存放两个16进制数,11223344有8个16进制数,int是4个字节,所以11223344正好被分成四份放在内存中。
那我们如何能得到a的地址呢?
这里就学习一个操作符(&)-取地址操作符
#include<stdio.h>
int main()
{
int a=10;
&a;
printf("%p\n",&a);
return 0;
}
内存 | |
0XFFFFFFFF | 一个字节 |
0XFFFFFFFE | 一个字节 |
一个字节 | |
0x006FFD73 | a |
0x006FFD72 | a |
0x006FFD71 | a |
0x006FFD70 | a |
0X00000001 | 一个字节 |
0X00000000 | 一个字节 |
按照我画图的例子,会打印处理:006FFD70
&a取出的是a所占字节中地址较小的字节的地址。
虽然仍型变量占用四个字节,我们只要知道第一个字节地址,顺藤摸瓜范围,问到四个字节的数据也是可行的。
2.2指针变量和解引用操作符
2.2.1指针变量
那我们通过取地址操作符拿到的地址是一个数值,比如0X006FFD70这个数值有时候也是需要存储起来,方便后期再使用的。那么我们把这样的地址存放在哪里呢?当然是指针变量中,比如:
#include<stdio.h>
int main()
{
int a=10;
int *pa=&a;//取出a的地址并存储到指针变量pa中
return0;
}
指针变量也是一种变量。这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址。
2.2.2如何拆解指针类型
我们看到的pa类型是int*,我们该怎么理解指针的类型呢?
int a=10;
int*pa=&a;
这里pa左边写的是int*,*是在说明pa是指针变量,而前面的int是在说明pa指向的是整型类型的对象。
0x0012ff40 | 10 | int类型 | |||||
int a=10; | a | ||||||
int* pa=&a; | |||||||
0x0012ff40 | int*类型 | ||||||
pa |
同理,如下
char ch='w';
char*pc=&ch;
2.2.3解引用操作符
我们将地址保存起来未来是要使用的,那怎么使用呢?
在现实生活中,我们使用地址要找到一个房间,在房间里可以拿去或者存放物品。
C语言中其实也是一样的,我们只要拿到地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象。
这里必须学习一个操作符叫解引用操作符(*)。
#include<stdio.h>
int main()
{
int a=100;
int* pa=&a;
*pa=0;
return 0;
}
*pa的意思就是通过pa中存放的地址,找到指向的空间,*pa其实就是a变量了;所以*pa=0这个操作符就是把a变量的值改成0了;
也有同学肯定在想,这里如果目的就是把a改成0的话,写成a=0不就完了,为啥非要使用指针呢?
其实这里是把a的修改交给了pa来操作,这样对a的修改就多了一种途径,写代码就会更加灵活。
2.3指针变量的大小
上图是x64,8字节
上图是x86,4字节
结论:
- 指针变量的大小是和类型无关的,只要指针类型的变量,在相同平台下,大小是相同的。
- 32位平台下地址是32bit位(即4个字节)
- 64位平台下地址是64bit位(即8个字节)