指针
1. 运算符&
获得变量的地址,printf("%p",&i)
2. 指针变量
指针:就是保存地址的变量
int i; int *p=&i;//这里*是声明,*p即声明p是一个指针变量,p保存i的地址,p指向i的地址
而后续的*可以理解为运算符,*p对p做运算找到p所指位置的内容,因此*p代表了i的值,对*p修改,就是通过*p找到i的位置对i的值修改
函数调用时,通过指针能保存带回的结果,因此传入参数就是需要保存带回的结果的变量
3. 指针应用
场景一:调用swap函数,交换a、b的值
两种实现方式:
(1)直接交换a,b的地址,如
swap(int &pa,int &pb){
交换pa和pb的值
}
swap(a,b);
(2)通过指针直接修改a,b的值
swap(int *pa,int *pb){
交换*pa和*pb的值
}
swap(&a,&b);
场景二a:函数的返回值只有一个,因此当函数返回多个值,某些值只能通过指针返回
场景二b:函数返回运算的状态,结果通过指针返回
4. 野指针
野指针是指向位置随机的、不正确的指针,系统无法对其进行操作,野指针指向的位置是随机的, 危害也是随机的,不一定会产生错误。
一种情况是,创建指针时没有对指针进行初始化,导致指针指向一个随机的位置,此时该指针就是一个野指针。后续我们对该指针进行操作时,比如说赋值,是将值写入该指针指向的那个随机位置,如果那个位置不能写,程序就会发生崩溃。
另一种情况是,释放指针指向的内存之后,指针没有置空,此时指针会指向“垃圾”内存
避免野指针
- 在创建指针时必须进行初始化;
- 在释放指针指向的内存之后必须将指针置空;
5. 数组与指针
函数参数表里的数组其实是个指针,void f(int a[])与void f(int *a)等价
数组变量是特殊的指针,因为数组变量本身表达地址(就是a[0]的地址),因此
- int a[10];int *p=a;//无需用&取地址
- 但数组的单元表达的是变量,需要用&取地址
- a==&a[0]
- []可以对数组做也可以对指针做: p[0]<==>a[0]
- *可以对指针做也可以对数组做:*a<==>a[0]
- 数组变量是const的指针,因此不能被赋值:int a[] <==>int * const a=…
#include<stdio.h>
int main(){
int a[10];
int *p=a;
printf("%d\n%d\n%d\n%d\n%d",a,&a[0],p[0],a[0],*a);
//运行结果a=&a[0],p[0]=a[0]=*a
}
6. 指针与const
(1)指针是const p是const int *const p=&i;
一旦得到了某个变量的地址,不能再指向其他变量:
- 指针变量p是const,不能修改p的值,即指针p指向的位置是固定的
(2)所指是const *p是const const int *p=&i;
表示不能通过这个指针去修改那个变量(并不能使那个变量成为const):
- *p是const,无法通过*p=26去给i赋值为26
- 但i并不是const,因此仍能通过i=26给i赋值
- p也不是const,因此也可以修改p的值,让p指向其他变量
区分(1)、(2)通过判断const在*前面还是后面
转换:总是可以吧一个非const的值转换成const
保护变量:void fun(const int *x){}//无法在fun函数f里对传入的变量进行修改
保护数组值:int sum(const int a[]){}//无法在sum函数里对传入的数组进行修改
7. 指针的运算
p-q:二者之间能存放多少个数,并不是二者的地址差
*P++:表示取出p所指位置的内容,再把p移到一下一位置,同理*++P,取出下一位置的内容
当不知道i是什么类型时,需要取出他的地址,可以用void *p=&i;
8. 动态内存分配
int *p=malloc(number*sizeof(int));//动态申请一片空间(借)
free(p);//有借又还,free释放必须是malloc分配的初始地址
常见问题:
- 申请了没free
- free过了再free
- 地址变了,直接free
9. 指针数组
char *str[10];//实际上标准写法是const char *str[10],意思是10个指针构成的数组
因此我们不能对指针数组所指向的内容修改(const),但可以通过malloc函数为每一个指针变量重新申请一片空间,此时指针指向的内存空间是才是有效的
- str[i]=%s:存储在 str[i] 指向内存位置的字符串内容
- str[i]=%p:str[i] 指针指向的内存地址
- &str[i]=%p:str[i] 指针本身的地址
- *str[i]=%c:str[i] 指向的第一个字符