指针变量就是保存地址的变量
int i; int *p=&i; //*是一个单目运算符用来访问指针的值所表示的地址上的变量 //可以做左值也可以做右值,也就是说它可以放在=的左边我们来赋值 也可以放在=右边我们来读它的值
我们把这个i的地址交给了指针p,p保存的是i的地址,这个时候我们就说p指向了 i。
普通变量的值是实际的值,指针变量的值是具有实际值的变量的地址。
通过指针我们访问到了i
作为参数的指针
void f(int *p) //在被调用的时候得到了某个变量的地址 int i; int *p=&i; f(p); //在函数里通过指针可以访问到外面的i //访问意味着读或者写
我们来试一下这件事情
我们仍然认为发生的是值的传递,p(&i)这个地址值被传进了函数,所以这仍然是值的传递,因为传进来的是地址,通过这个地址在函数内部我们可以以这种方式去访问到外面的i变量,p是i的地址,所以*p就代表了i,这样子我们就可以去修改这个i,做上图这个*p=123这个操作实际上就是对i做。
指针的运算符 & *
二者互相反作用
*&point->*(&point)->*(point 的地址)->得到那个地址上的变量->point
&*point->&(*point)->&(point)->得到point的地址,也就是point->point
二、指针使用
指针应用场景1
函数返回多个值,某些之就只能通过指针返回
传入的参数实际上是需要保存带回的结果的变量
举个栗子
#includevoid minmax(int a[],int len,int *min,int *max);//len为数组元素个数 int main() { int a[]={1,2,3,4,5,6,7,8,9,12,18,55,88}; int min,max; minmax(a,sizeof(a)/sizeof(a[0]),&min,&max); printf("min=%d,max=%d",min,max); return 0; } void minmax(int a[],int len,int *min,int *max) { int i; *min=*max=a[0]; for(i=1;i a[i]) *min=a[i]; if(*max
这就是指针应用的一种非常常见的场景:我的函数的结果不止一个,那么我通过指针把我要接收的结果的变量的地址传进去,让函数在里面帮我把这些变量处理好,把值传回来,虽然这两个是参数从主函数main里传进去的,但它们的作用是把结果带出来
指针应用场景2
函数返回运算的状态,结果通过指针返回
常用的套路是让函数返回特殊的不属于有效范围内的值来表示出错:比如说-1或0
但是当任何数值都是有效的可能结果时,就得分开返回了
举个栗子
#includeint divide(int a,int b,int *result);//定义一个除法函数 int main() { int a,b; scanf("%d%d",&a,&b); int c; if(divide(a,b,&c)) { printf("%d/%d=%dn",a,b,c); } return 0; } int divide(int a,int b,int *result) { int flag=1; if(b==0)//除数为0则除法没意义 flag=0; else *result=a/b; return flag; }
相除的结果通过指针来传出,除法成功flag返回1,
若除数为0则除法没意义 函数则返回0 if(divide())无操作
指针最常见的错误
即定义了一个指针未初始化 便开始使用
int *p; *p=12;//达咩!
这就是传说中的野指针,没有对象的;
三、指针与数组如果我们通过函数的参数把一个数组传到函数里去,那么传入函数的数组成了什么?
如果我们传一个普通变量 那么函数接收到的是一个值,如果传一个指针 那么参数接收到的也是一个值,只不过这个值是地址。
那么传一个数组呢?
我们继续使用刚刚的minmax函数
#includevoid minmax(int a[],int len,int *min,int *max); int main() { int a[]={1,2,3,4,5,6,7,8,9,12,18,55,88}; int min,max; printf("in main sizeof(a)=%dn",sizeof(a));//在main函数中sizeof(a)的值 minmax(a,sizeof(a)/sizeof(a[0]),&min,&max); printf("min=%d,max=%d",min,max); return 0; } void minmax(int a[],int len,int *min,int *max) { int i; printf("in minmax sizeof(a)=%dn",sizeof(a));//传入函数后在函数中sizeof(a)的值 *min=*max=a[0]; for(i=1;i a[i]) *min=a[i]; if(*max
不过发生了一点微妙的变化
可以看出在main函数和在minmax函数中 sizeof(a)发生了变化
在minmax函数中sizeof(a)的值是4,刚好和一个指针的大小是一样的
我们再来试一下
#includevoid minmax(int a[],int len,int *min,int *max); int main() { int a[]={1,2,3,4,5,6,7,8,9,12,18,55,88}; int min,max; printf("in main sizeof(a)=%dn",sizeof(a)); printf("in main a=%pn",a);// look here**** minmax(a,sizeof(a)/sizeof(a[0]),&min,&max); printf("min=%d,max=%d",min,max); return 0; } void minmax(int a[],int len,int *min,int *max) { int i; printf("in minmax sizeof(a)=%dn",sizeof(a)); printf("in minmax a=%pn",a);//look here**** *min=*max=a[0]; for(i=1;i a[i]) *min=a[i]; if(*max
这次我们看在main里和minmax里a的地址
每一位都是一模一样的,这说明在minmax里面这个a数组其实就是main里面的a数组 不只是一模一样。它们压根就是同一个
我们继续实验一下
void minmax(int a[],int len,int *min,int *max)
{
a[0]=10000;//在minmax函数里令a[0]=10000;
所以实际上函数参数中的a[]就是个指针,样子看上去像一个数组一样
所以即使在void minmax(int a[],int len,int *min,int *max)将参数 int a[]改为int *a编译还是能通过运行还是正确
所以函数参数表中的数组,实际上是指针
//所以下面两种形式是等价的; int minmax(int *a) int minmax(int a[])
数组变量是特殊的指针
数组变量本身就表达地址
//所以a的地址==&a[0] int a[10]; int *p=a;//不需要用&取地址 //但是数组中的元素表达的是单个变量 需要用&取地址 //[]y运算符可以对数组做 也可以对指针做 int *p=a; //p[0]<==>a[0] //*运算符也可以对数组做 *a=25;//a[0]==25



