指针作为函数参数
1.指针作为函数参数,可以修改函数外的值,而一般变量不行
如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a;
void f(int *p){
*p/=2;
}
int main()
{
a=10;
f(&a);
printf("%d",a);
return 0;
}
这个的运行结果是5,因为指针指向a的地址
2.交换
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int x,y;
void swap(int *a,int *b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}
int main()
{
scanf("%d%d",&x,&y);
swap(&x,&y);
printf("%d %d",x,y);
return 0;
}
思考:为什么下列交换方式是失败的
swap函数中,x,y只是指针变量,没有加*意味着没有交换指向变量a b的值
如上图红笔所示,交换xy不过是交换了函数中形参变量的值,形参的值不会影响实参,这对于任何变量都是成立的,所以
不能试图通过改变形参指针变量的值而使实参变量指针的值改变
数组作为函数参数
函数参数表中的数组即指针
先来看一段代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void f(int b[]){
printf("%p\n",&b[0]);
b[0]=90;
b[9]=9;
}
int main(){
int a[10]={1,0,3,10,7,8,9,89,6,100};
printf("%p\n",&a[0]);
f(a);
return 0;
}
上面这段代码是在f函数和主函数中分别输出数组a和b的首地址
运行结果
在这里可以看到,数组a和b的首地址是完全一样的,这与我们一开始所认识的普通变量作为函数参数不同,这里的a数组和b数组完全是同一个数组,换句话说,b就是指向a数组的一个指针,函数中的int b[]=int *b
在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针
用途
说了这么多,指针作为函数参数有什么用呢?
直接上代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void f(int b[]){
printf("%p\n",&b[0]);
b[0]=90;
b[9]=9;
}
int main(){
int a[10]={1,0,3,10,7,8,9,89,6,100};
printf("%p\n",&a[0]);
f(a);
for (int i=0;i<10;i++) printf("%d ",a[i]);
return 0;
}
我们在f内部改掉了数组b内的值,上文中提到过,b就是指向a数组的一个指针,指针变量相对于C++内其他变量最大的一个优势就是可以在函数里修改函数外的值
运行结果
可以看到a数组内的值已经被改掉了
当然这段代码也可以这么写
void f(int *b){
printf("%p\n",&b[0]);
b[0]=90;
b[9]=9;
}
运行结果和上述用数组作为函数变量完全一样(尤其注意,由于传入的数组实际上是指针,b[]中不用写入数字)
总结
数组变量是特殊的指针
数组本身表达地址,所以
1.int a[10]; int *p=a;//无需&取地址
2.数组的单元表达的是变量,要用&取地址
3.a==&a[0];
[]运算符可以对数组做,也可以对指针做
*运算符可以对指针做,也可以对数组做
特别注意:数组变量不能被赋值(数组变量属于常量指针)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
void f(int *b){
//printf("%p\n",&b[0]);
b[4]=90;
b[9]=9;
}
int main(){
int a[10]={1,0,3,10,7,8,9,89,6,100};
//printf("%p\n",&a[0]);
f(a);
*(a+1)=10;//以指针的方式写的代码也可以修改数组内的值
for (int i=0;i<10;i++) printf("%d ",a[i]);
return 0;
}
运行结果
这里记住 * 和[]作用是一样的
附三道云班课例题
这里的*p=a相当于p=a[0],p指向了a的第一行的第一列地址
*a 是列指针,*p也是列指针,p[1]相当于列往后移动一格
解析:定义了一个行指针,指向了a,指向了第0行的地址,p[1]是列指针,指向第2行第0列的地址,取 " * "变成了值