深入理解指针(一)

1.内存和地址

1.1内存

在讲内存和地址之前,我们想有个生活中的案例:

假设有一栋宿舍楼,把你放在楼里,楼上有100个房间,但是房间没有编号,你的一个朋友来找你玩儿,如果想找到你,就得安一个房子去找,这样效率很低。但是我们如果根据楼层和楼层的房间情况,应每个房间边上号有的房间号,如果你的朋友得到房间号,就可以快速地找房间找到你。

生活中每一个房间有的房间号就能提高效率,能快速的找到房间。

如果把上面的例子对照到计算中又是怎么样的呢?我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中。那我们买电脑的时候,电脑上有内存是8GB/16GB/32GB的。但这些内存空间如何高效的管理呢?

其实也是把内存划分为一个个的内存单元,每个内存单元的大小取一个字节。

计算机中常见的单位:

  1. bit - 比特位                         1byte = 8bit 
  2. byte - 字节                          1KB=1024byte
  3. KB                                      1MB=1024KB
  4. MB                                      1GB=1024MB
  5. GB                                       1TB=1024GB
  6. TB                                        1PB=1024TB
  7. PB

每个内存单元相当于一个学生宿舍的一个人。自己的空间里面能放八个比特位,就好比同学们住的八人间,每个人是一个比特位。

每个内衣寸单元也都有一个编号。这个编号就相当于宿舍房间的门牌号。有了这个内存单元的编号,CPU就可以快速找到一个内存空间。

内存
0XFFFFFFFF1个字节
0XFFFFFFFE1个字节
1个字节
1个字节
0X000000011个字节
0X000000001个字节

                                     生活中我们把门牌号也叫地址在计算机中,我                                       们把内存单元的编号也称为地址。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一个字节
一个字节
0x006FFD73a
0x006FFD72a
0x006FFD71a
0x006FFD70a
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指向的是整型类型的对象。  

0x0012ff4010int类型
int a=10;a
int* pa=&a;
0x0012ff40int*类型
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个字节)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值