1.基本内容
什么是指针
- 在计算机中所有数据都存储在内存单元中,而每个内存单元都有一个对应的地址, 只要通过这个地址就能找到对应单元中存储的数据.
- 由于通过地址能找到所需的变量单元,所以我们说该地址指向了该变量单元。将地址形象化的称为“指针”
- 内存单元的指针(地址)和内存单元的内容是两个不同的概念。
什么是指针变量
在C语言中,允许用一个变量来存放其它变量的地址, 这种专门用于存储其它变量地址的变量, 我们称之为指针变量。
1 | char ch = 'a'; |
*表示这是一个指针变量
1 | int *p; |
- 多个指针变量可以指向同一个地址。
对指针变量的理解
指针变量本身的作用是储存一个用户定义的变量的地址,但是其本身作为一个额外的变量,也有自己的地址,且这个地址不等于其储存的变量的地址;
例:
1 | int main() |
取地址运算符(&)与解引用运算符(*)
取地址运算符:&x,其作用为返回操作对象的地址
解引用运算符:
*x,其作用是返回x中存储的地址内存储的值例:
int a,*p1;p1=&a;则此时*p1代表的就是变量a的内容,而不是a的地址这也就是为什么使用
printf("%d",*p);时是用p而不是p了,因为 p才是代表a的值,p则存储的变量a的地址综上:除开定义时,其余时间*p等同a,p等同&a
在定义时,
int *p1=&a;也是合法的且作用与上相同,个人理解为是一种指针格式的“声明”(?)这也解释了当某个函数参数定义为为int *a时实际使用时传入的也是&的取地址变量了(个人理解)
2.一些用法
二级指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量。也称为“二级指针”。
1
2
3
4
5
6char c = 'a';
char *cp;
cp = &c;
char **cp2;
cp2 = &cp;
printf("c = %c", **cp2);// c=a
指针访问数组元素
在指针指向数组元素时,允许以下运算:
- 加一个整数(用+或+=),如p+1
- 减一个整数(用-或-=),如p-1
- 自加运算,如p++,++p
- 自减运算,如p–,—p
如果指针变量p已指向数组中的一个元素,则p+1
指向同一数组中的下一个元素,p-1指向同 一数组中的上一个元素。【*(p+1)】(p+N)在地址上的变化为
p内存放的地址+数组元素类型长度*N- 其对p所有的基本运算均符合上述规律
指针与字符串
定义字符串除了使用字符数组存放之外,还可以通过字符串指针的方式指向字符串。
1 | // 数组名保存的是数组第0个元素的地址, 指针也可以保存第0个元素的地址 |
使用注意事项
此方法不可修改字符串内容
1
2
3
4//使用字符数组来保存的字符串是保存栈里的,保存栈里面东西是可读可写,所有可以修改字符串中的的字符
//使用字符指针来保存字符串,它保存的是字符串常量地址,常量区是只读的,所以我们不可以修改字符串中的字符
char *str = "lnj";
*(str+2) = 'y'; // 错误不能够直接接收键盘输入
1
2
3
4// 错误的原因是:str是一个野指针,他并没有指向某一块内存空间
// 所以不允许这样写如果给str分配内存空间是可以这样用 的
char *str;
scanf("%s", str);
指向函数的指针
函数在内存中占据空间,因此也有起始地址。
格式:返回值类型 (*指针变量名)(形参);
1 |
|
函数指针有以下几点特点:
当把一个函数名(注意是名字,不带输入参数)作为一个值使用时,该函数会自动转换成指针,指向该函数的内存地址,因此在对指针初始化时取地址符可选:
1
2p=sum;
p=∑//都正确当使用指针调用函数时,解引用也是可选的:
1
2printf("%d",(*p)(1,2));
printf("%d",p(1,2));//都输出3
当函数指针作形参时:
1 |
|
调用函数时直接传入函数名即可。
同理的,也可以不声明参数为指针(因为会自动转变为指针)
1 | void tran(double a(double a1),double b(double b1),double x) |
通过形参影响实参
我们都知道,形参值的改变不能改变对应实参的值,把数据从被调用函数返回到调用函数的唯一途径时通过return。但如果通过传送地址给被调用函数,再在被调用函数中改变地址中存储的值,也就使通过形参改变对应实参的值成为了可能。
例如:交换值
1 | void swap(int *x, int *y) |
但如果swap函数定义成如下,又会怎么样呢
1 | void swap(int *x, int *y) |
如果这样定义函数,则程序的流程为:①调用swap函数时,x内保存的为a的地址,y内保存的为b的地址;②在swap函数中,x内保存的地址改变为b的地址,y内保存的地址改变为为a的地址;③swap函数调用结束,x,y的内存被释放;④此时a、b变量自身的地址并没有任何改变,改变的只用形参x、y所保存的地址,因此无法起到交换作用
二维数组地址详解+数组指针(重要!!!!!)
结构体指针
详见数据结构_链表 | 小董的BLOG (gitee.io)和结构体复习 | 小董的BLOG (gitee.io)
2022.11.20:我是按照自己的理解写的,所以思路那些可能会有点奇怪,我感觉自己写的也不是很精练。。凑合看看吧