C语言指针知识点总结
目录
- 一、指针功能
- 二、基础概念
- 1. 地址
- 2. 指针
- 3. 指针变量
- 三、指针两大运算符
- 1. & 取地址运算符
- 2. * 取值(解引用)运算符
- 四、指针变量定义
- 野指针
- 空指针
- 指针类型含义
- 五、指针两种操作含义
- 六、指针算术运算
- 七、函数参数:值传递与地址传递
- 1. 值传递
- 2. 地址传递(指针传参)
- 八、一维数组与指针关系
- 数组名特性
- 一维数组作为函数形参的写法(三种等价形式)
一、指针功能
- 让程序代码更加简洁高效
- 能够直接访问内存空间
二、基础概念
1. 地址
- 计算机为区分内存中不同存储空间,对内存进行编号,存储空间对应的编号就是地址。
- 内存按照字节进行编址。
- 寻址范围:
0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF
2. 指针
指针本质上可以理解为地址;指针带有类型属性,类型决定了它指向空间占用字节大小。
3. 指针变量
- 专门用来存放指针(地址)的变量称为指针变量,日常也会直接简称为指针。
三、指针两大运算符
1. & 取地址运算符
- 仅左值支持
&操作,常量、表达式等右值无法进行取地址。 &变量运算结果:该变量在内存中存储空间的首地址。- 类型转换规则:类型升级,例如
int→int *。
示例:
intnum=0;#// 获取变量num内存首地址2. * 取值(解引用)运算符
- 只有指针类型的数据可以执行
*操作,普通变量不能直接解引用。 *指针运算结果:从指针保存的首地址开始,读取对应类型长度的数据。- 类型转换规则:类型降级,例如
int *→int。 - 若
*指针放在等号左侧充当左值,代表向指针指向的内存空间写入数据。
四、指针变量定义
语法格式:数据类型 *变量名;
int*p;char*p;float*p;double*p;int*p,*q;- 在64位系统中,所有指针变量统一占用8字节,和指针指向的数据类型无关。
野指针
未经初始化、或者指向已经被释放内存空间的指针。
规范:禁止使用未初始化的野指针。
空指针
- 指向内存地址
0x0位置的指针,使用NULL表示。
int*p=NULL;0x0地址对应的内存空间为只读,禁止对空指针解引用*p,否则程序直接崩溃。
指针类型含义
指针的数据类型决定指针指向何种类型内存空间:
int *p:指向int类型空间char *p:指向char类型空间float *p:指向float类型空间double *p:指向double类型空间
五、指针两种操作含义
假设有指针变量p:
p:代表操作指针变量本身,修改它可以改变指针指向的地址。*p:代表操作指针指向的内存空间,修改它只会修改地址内存储的值,不会改变指针指向。
示例区分:
inta=100;intb=200;int*p=&a;int*q=&b;p=&b;// 修改指针p本身,p指向变量bp=q;// 修改指针p本身,让p和q指向同一空间*p=b;// 修改p指向空间内的数据,指针指向不变*p=*q;// 修改p指向空间内的数据,指针指向不变六、指针算术运算
支持:+、-、++、--
p++:向内存高地址偏移,偏移长度 = 指针指向数据类型的字节大小p--:向内存低地址偏移,偏移长度 = 指针指向数据类型的字节大小*p++等价于*p , p++;先取值,再移动指针- 两个同类型指针可以相减:计算得到两个地址之间相隔多少个对应类型元素。
注意:指针不支持相加运算
七、函数参数:值传递与地址传递
1. 值传递
实参将数值副本传递给形参;形参发生修改,不会影响外部实参。
适用场景:函数只需要读取外部变量数值,不需要修改变量。
2. 地址传递(指针传参)
实参把变量地址传递给指针形参;函数内通过解引用可以直接修改外部实参的值。
适用场景:
- 函数内部需要修改函数外部变量
- 借助地址传递,实现一个函数返回多个结果
八、一维数组与指针关系
inta[5]={1,2,3,4,5};int*p=NULL;p=&a[0];p=a;// 数组名a等价于数组首元素地址等价关系:a[n] == *(a+n) == *(p+n) == p[n]
数组名特性
- 数组名是指向数组首元素的指针常量,不能被直接赋值修改。
- 绝大多数场景数组名可看作对应类型指针(如
int数组名看作int *),两种例外:sizeof(数组名):此时数组名代表整个数组,不视作指针&数组名:取出整个数组的地址,不视作普通元素指针
- C语言中
[]本质是指针语法糖,p[n]等价于*(p+n)。
一维数组作为函数形参的写法(三种等价形式)
intfun(intarray[],intlen);intfun(intarray[5]);intfun(int*parray,intlen);数组传入函数后,会隐式转化为指针,函数内部无法通过sizeof获取数组总大小,必须额外传入数组长度。