C语言数组与指针的关系(数组与指针作为函数参数)

指针作为函数参数

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;
}

思考:为什么下列交换方式是失败的
swapswap函数中,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
在这里可以看到,数组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数组内的值已经被改掉了
可以看到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列的地址,取 " * "变成了值

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值