C语言中的指针-数组名作为函数参数指针-学习笔记-28

数组名和指针

我们先来捋一遍数组名和指针。数组名是该数组的首元素起始地址,说白了,也是一个地址,但这个地址是不变的,是固定的是一个常量,数组名后面附加角标,叫可以表示该数组中的某一个元素的值。指针是指向某一变量或数组的地址,和数组名一样,都是地址,但指针的内容是可以改变的,指针前加*号就可以表示这个地址所指向的数据的值。

所以,我们现在知道了,数组和指针都表示的是一个地址。

数组名作为函数参数

我们照旧从一个例子出发,来理解这个概念,我们输入5个数到一个数组中,并且将数组中的5个数从大到小存储在数组中,接着依次输出这5个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
int main(){
void arr(int num[]);
int array[5];
for(int i=0;i<5;i++){
scanf("%d",&array[i]);
}
arr(array);
for(int i=0;i<5;i++){
printf("%d\t",array[i]);
}
return 0;
}
void arr(int num[]){
int big;
for(int i=0;i<5;i++){
for(int k=0;k<4;k++){
if(num[k]<num[k+1]){
big=num[k+1];
num[k+1]=num[k];
num[k]=big;
}
}
}
}

我们在讲函数参数的时候说过,数组名可以作为函数的形参和实参,对于变量,形参改变,实参是不会改变的,因为形参和实参存储在不同的存储单元中,为什么数组名作为函数参数的时候,形参改变,实参的数组会改变呢?

学习了指针之后,我们就很清楚这个概念了,因为实参传递给形参的不是具体的数值,而是实参的内存地址,我们在形参中改变的也不是内存地址,而是实参这个地址中的数据,所以形参改变了,实参也就随着改变了。对于上面的例子,下面这四个值其实都是一个内存:

*array=array[0]=num[0]=*num

所以,我们在函数中调用时,虽然没有返回值,但是真实的改变了数组的内容,也就是元素的值。

在上面的例子中,我们用来排序的函数头换成指针其实也是一样的:

void arr(int num[]) 和 void arr(int *num) 完全相同

并且在编译器执行时,也会把函数参数中的数组名改成上面指针的形式执行。

arr[3]=*(arr+3)=array[3]

上面的三个其实也是完全相同的,因为大家的地址都是相同的,表示的都是这个地址下的第三个元素的值!

注意
实参的数组名:实际是一个指针常量,存储的是地址,值不能改变。
形参的数组名:实际是一个指针变量,存储的是地址,值可以改变

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main(){
void arr(int num[]);
int array[5]={1,2,3,4,5};
printf("array[3]=%d\n",array[3]);
arr(array);
return 0;
}
void arr(int num[]){
num=num+3; //如果是实参的数组,则不能这么移动指针。
printf("*num=%d\n",*num); //这里把 num 的指针向后移动了3位,实际为 array[3]
}

熟悉例题-1

将数组中的所有元素收尾对调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
int main(){
void exchange(int num[],int n);
int array[10]={6,5,3443,23,45,1,66,22,31,7};
for(int i=0;i<10;i++){
printf("%d\t",array[i]);
}
exchange(array,10);
printf("\n");
for(int i=0;i<10;i++){
printf("%d\t",array[i]);
}
printf("\n");
return 0;
}

void exchange(int num[],int n){
int temp;
n=n-1;
for(int i=0;i<n;i++,n--){
temp=num[i];
num[i]=num[n];
num[n]=temp;
}
}

总结

我们如果想通过函数改变一个实参数组的值,那么有一下几种方式:

  1. 形参和实参都用数组名,数组名表示的是地址,根据地址修改实际的值。
  2. 实参数组名,形参用指针变量,因为数组名就是一个指针常量,所以把常量的值传递给变量,然后根据地址修改实际的值。数组名可以直接传递给指针变量的函数参数的
  3. 形参实参都用指针变量,在数组初始化之后,将数组的首元素地址传递给一个指针变量,使用函数的时候,传递该指针变量去函数的形参。
  4. 实参为指针变量,形参为数组名,也就是指针变量和数组名之间是可以进行虚实结合的数据传递的。

以上无论哪一种方法,都是进行地址的传递,只是形式不同罢了。

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!