在学习指针之前,先让我们了解一下内存
内存 存储器:存储数据器件
- 外存:
- 外存又叫外部存储器,长期存放数据,掉电不丢失数据
- 常见的外存设备:硬盘、flash、ROM、U盘、光盘、磁带
- 内存:
- 内存又叫内部存储器,暂时存放数据,掉电数据丢失
- 常见的内存设备:RAM、DDR
- 物理内存:实实在在存在的存储设备
- 虚拟内存:操作系统虚拟出来的内存
一个地址
。这些车厢装着不同的货物,就像我们的内存要存着各式各样的数据 文章图片
是不是这样就好理解一些了呢
再比如我们生活中,平时在电脑上看的视频、听的音乐和文章,其实都是内存中每个 “车厢” 里面的数据,这些数据最终还是由二进制 0/1 演变而成
虽然视频、文章和音乐等这些信息在我们眼中是不同的,但对于计算机来说它们在内存中都是以二进制的形式来表示的
因为我们要知道去哪存或取数据,所以内存中每个字节都有对应的编号,就像火车上的车厢编号一样。而这个内存中每个字节的编号就是我们常说的内存地址,是按一个字节接着一个字节的次序进行编址。如下图所示:
文章图片
关于内存字节
- 1个内存地址只存1个字节(Byte)
- 1个字节等于8位二进制,每一位二进制的0或1,叫:比特(bit)
- 比特是最小单位,字节是比特的集合,也是一个单位
- char占
一个字节
,分配一个地址 - int占
四个字节
,分配四个地址 - …
#include
int main ()
{
printf("sizeof(char)=%u\n",sizeof(char));
// 1
printf("sizeof(int)=%u\n",sizeof(int));
// 4
return 0;
}
地址总线 再让我们聊一聊地址总线
- 地址总线(Address
Bus)是一种计算机总线,是CPU或有DMA能力的单元,用来沟通这些单元想要访问(读取/写入)计算机内存组件/地方的物理地址。 - 数据总线的宽度,随可寻址的内存组件大小而变,决定有多少的内存可以被访问。
地址总线是一个从CPU到内存的内部信道,其主要进行数据地址的传输
。每个存储单元都有一个固定地址,地址总线的宽度决定了CPU的最大寻址能力。例如:如果地址总线包括n个电线,那么处理器的寻址能力可高达2^n个独立单位。- 每条地址线一般只有一根导线,每根地址线输出高低电平两种状态,配合其他信号线完成寻址(选中)操作
但我们结合上电脑的配置就可能会好一点;比如现在的电脑基本都是64位的,但在以前32位居多,那像这里说到的64和32,可能还有其他小型计算机的16等这些数字是什么意思呢??
这些数字正是我们所说的地址总线,但是32位电脑是32根地址总线,而64位电脑则不到64根地址总线啦。。。(这主要还是根据电脑的内部来决定的),而地址总线也就是帮我们寻找地址时所要用的
我们将32位平台为例介绍:
- 在32位平台中,每一个进程拥有
4G
的空间(2^32) - 系统为内存的
每一个字节
分配一个32位
的地址编号(4个字节)
指针的实质就是
内存“地址”
,可以说是指针就是地址
,其实指针就是保存地址的变量(不是普通变量)文章图片
对于其他变量来说,就是普通的数值;而对于指针变量来说就表示内存地址编号
指针变量的定义 1、定义步骤(定义的时候)
- *修饰指针变量p
- 保存谁的地址,你先定义谁
- 从上往下整体替换
int *p;
定义一个指针变量p,保存数组 int arr[5]首地址:
int (*p)[5];
定义一个指针变量p,保存函数的入口地址:
int fun(int a, int b);
int (*p)(int a, int b);
定义一个指针变量p,保存结构体变量的地址:
struct stu lucy;
struct stu *p;
定义一个指针变量p,保存指针变量 int *p的地址
int **p
2、指针变量的详解
- 在32位平台任何类型的指针变量,都是4字节
- 在64位平台任何类型的指针变量,都是8字节
#include
void test()
{
printf("%lu\n",sizeof(char *));
// 8
printf("%lu\n",sizeof(short *));
// 8
printf("%lu\n",sizeof(int *));
// 8
printf("%lu\n",sizeof(long *));
// 8
printf("%lu\n",sizeof(float *));
// 8
printf("%lu\n",sizeof(double *));
// 8
printf("%lu\n",sizeof(bool *));
// 8
}
int main()
{
test();
return 0;
}
文章图片
普通变量、指针变量、普通变量和指针变量建立关系
- p的值就是num的地址;
- p保存了num的地址(p保存了 …的地址);
- p指向了num(p指向了 …)
#include
void test()
{
int num = 10;
int *p;
// 建立关系
p = #
// p指向num
// %p 打印地址编号
printf("p = %p\n", p);
// 000000000062FDE4
printf("&num = %p\n", &num);
// 000000000062FDE4
}
int main()
{
test();
return 0;
}
在使用的时候,*p表示取p所保存的地址编号对应空间的内容
p等价于#*p等价num
【ARM(IMX6U)|C语言指针学习】
文章图片
- *q == p == &num
- **q == *p == num
推荐阅读
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- 【C】题目|【C语言】题集 of ⑥
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 单片机|自学单片机好找工作吗(会单片机能找什么工作?)
- 单片机|keil把源代码生成lib的方法
- c语言|一文搞懂栈(stack)、堆(heap)、单片机裸机内存管理malloc
- 爬虫|若想拿下爬虫大单,怎能不会逆向爬虫,价值过万的逆向爬虫教程限时分享