C语言:指针1
- 一.内存和地址
- 1.1内存是什么
- 1.2计算机存储单位
- 1.3地址 = 指针
- 二.计算机编址原理
- 三.指针变量和地址
- 3.1取地址操作符 &
- 3.2指针变量
- 3.3指针类型拆解
- 3.4解引用操作符 *
- 四.指针变量的大小
- 五.指针变量类型的意义
- 5.1解引用权限
- 5.2指针 +- 整数(步长)
- 5.3void* 泛型指针
- 六.指针三大运算
- 6.1指针 +- 整数
- 6.2指针 - 指针
- 6.3指针关系运算
- 七.本文总结(必背)
接下来为 C 语言指针系列第一篇,从零拆解内存编址、指针本质、指针类型意义与核心运算,适合新手小白入门到进阶系统学习。
前言:
指针是 C 语言的灵魂,也是很多初学者的难点。只有真正理解内存 — 地址 — 指针的关系,才能写出高效、灵活的 C 代码。
本文从最基础的内存与地址讲起,带你一步步吃透指针核心概念。
一.内存和地址
1.1内存是什么
例如生活中宿舍楼给房间编号,就能快速找到目标;计算机管理内存也是同样逻辑。
- CPU 处理数据时,必须从内存读取数据,处理完再写回内存。
- 内存被划分为一个个内存单元,每个内存单元大小 = 1 字节(Byte)。
1.2计算机存储单位
1Byte=8bit1KB=1024Byte1MB=1024KB1GB=1024MB1TB=1024GB1PB=1024TB1.3地址 = 指针
每个内存单元都有唯一编号,那这个编号就是:
内存单元编号 == 地址 == 指针
有了地址,CPU 就能快速定位内存空间。
二.计算机编址原理
大概了解一下即可,没有深究的必要
CPU 与内存通过地址总线通信(原理):
32 位机器:32 根地址总线 → 可表示 2^32 个地址 → 地址占4字节
64 位机器:64根地址总线 → 可表示 2^64 个地址 → 地址占8字节
三.指针变量和地址
3.1取地址操作符 &
创建变量 = 向内存申请空间。
用&可以取出变量的起始地址(低地址字节)
如下所示:
#include<stdio.h>intmain(){inta=10;printf("%p\n",&a);//打印变量a的地址return0;}运行结果:
3.2指针变量
那么地址是一个数值,需要专门变量存放,这种变量叫指针变量。
inta=10;int*pa=&a;//pa是指针变量,存储a的地址3.3指针类型拆解
根据上面给的int* pa我们对它进行拆解:
int*pa 类型 指针变量名*:说明这是指针变量int:说明指针指向int 类型数据
同理:char*、double*、float*
3.4解引用操作符 *
通过指针找到并操作目标变量,使用解引用*。
如下所示:
#include<stdio.h>intmain(){inta=100;int*pa=&a;*pa=0;//等价于a = 0;printf("%d\n",a);return0;}运行结果:
由此我们可以得知,*pa就是a本身。
四.指针变量的大小
结论:指针大小只与平台有关,与类型无关!
32 位平台:所有指针都是 4 字节
64 位平台:所有指针都是 8 字节
如下所示:
#include<stdio.h>intmain(){printf("%zd\n",sizeof(char*));printf("%zd\n",sizeof(short*));printf("%zd\n",sizeof(int*));printf("%zd\n",sizeof(double*));return0;}运行结果:
这是在 x64 环境下运行的结果,如果换成 x86 环境下运行结果又会有所不同,如下图所示:
五.指针变量类型的意义
类型不影响大小,但决定两件事:
- 解引用能操作多少字节
- 指针 ±1 能走多远
5.1解引用权限
举例:int*解引用操作4个字节
#include<stdio.h>intmain(){inta=0x11223344;int*pa=&a;*pa=0;//4字节全改为0return0;}同理,char*解引用只操作一个字节(只改第一个字节)
5.2指针 ± 整数(步长)
char*+1-->>跳过1字节int*+1-->>跳过4字节double*+1-->>跳过8字节指针 +-1 = 跳过一个指向类型的大小
5.3void* 泛型指针
- 可以接收任意类型地址,无警告
- 不能直接解引用
- 不能直接 ± 整数
void*泛型指针常用于函数参数,实现泛型编程
void*pa=&a;//合理//*pa = 10;//不合理,非法间接寻址六.指针三大运算
6.1指针 ± 整数
遍历数组最常用方式:
#include<stdio.h>intmain(){intarr[10]={1,2,3,4,5,6,7,8,9,10};int*p=arr;for(inti=0;i<10;i++){printf("%d ",*(p+i));}return0;}6.2指针 - 指针
必须指向同一块内存,结果为中间元素个数。
手写 strlen(函数):
intmy_strlen(char*s){char*p=s;while(*p)p++;returnp-s;}6.3指针关系运算
指针可以比较大小(<><=>===!=),常用于遍历。
如下所示:
while(p<arr+10){printf("%d ",*p++);}七.本文总结(必背)
- 内存编号 = 地址 = 指针
&取地址,*解引用- 32 位指针 4 字节,64 位指针 8 字节
- 指针类型决定:
解引用权限+ 步长 - 指针三大运算:± 整数、- 指针、关系比较
如果你觉得本篇对你有帮助,欢迎点赞、收藏、关注,我会持续更新 C 语言硬核干货!