当用数组名作函数参数时,如果形参数组中各元素的值发生变化,实参数组元素的值随之变化。
如果已经定义一个函数,其原型为
void swap(int x,int y);
假设函数的作用是将两个形参(x,y)进行交换,现在有以下的函数调用:
swap (a[0],a[1]);
用数组元素做实参的情况,与用变量作实参的情况一样,是“值传递”方式,将a[0]和a[1]的值单向传递给x和y。当x和y的值改变时a[0]和a[1]的值并不改变。
例如:定义一个函数fun,fun函数的形参写成数组的形式:
void fun(int arr[],int n);
但在程序编译时是将arr按指针变量来处理的,相当于函数fun应写成:
void fun(int *arr,int n);
void fun(int arr[], int n)
{
int s = sizeof(arr);
printf("arr所占字节数为:%d\n", s);
}
int main()
{
int brr[10];
fun(brr, 10);
return 0;
}
运行结果:
【注意】
【例】定义一个数组名作形参的函数,通过调用这个函数改变实参数组的值
int fun(int arr[], int n)
{
//int s = sizeof(arr);
//printf("arr所占字节数为:%d\n", s);
int t;
t = arr[1];
arr[1] = arr[2];
arr[2] = t;
return arr[0];
}
int main()
{
int brr[10] = { 1,3,2,4,5,6,7,8,9,10 };
fun(brr, 10);
for (int i = 0; i < 10; i++)
{
printf("%d ", brr[i]);
}
return 0;
}
运行结果:
常用这种方法通过调用一个函数来改变实参数组的值。
(1)当实参类型是变量名时,要求形参的类型也是变量名,通过形参传递的信息是变量的值,通过函数调用不能改变实参变量的值。
【例】将数组a中n个整数按相反顺序存放,用一个函数inv来实现交换。实参用数组名a,形参可用数组名,也可用指针变量。
void inv(int x[], int n)//形参x是数组名
{
int temp;
int m = (n - 1) / 2;
for (int i = 0; i <= m; i++)
{
int j = n - 1 - i;
//把x[i]和x[j]交换
temp = x[i];
x[i] = x[j];
x[j] = temp;
}
return;
}
int main()
{
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
inv(a, 10);//调用inv函数进行交换
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
}
运行结果:
改写代码,将函数inv中得形参x改成指针变量:
void inv(int *x, int n)
{
int temp;//定义一个中间变量,用来交换两个变量得值
int m = (n - 1) / 2;
int* p;//定义一个指针变量p
p = x + m;//p指向a[m]元素的地址
int* i;//定义一个指针变量i
i = x;//i指向数组首元素的地址
int* j;//定义一个指针变量j
j = x + n - 1;//j指向数组最后一个元素的地址
for (i=x;i<=p;i++,j--)
{
//交换i和j所指向的数组元素的值
temp = *i;
*i = *j;
*j = temp;
}
return;
}
int main()
{
int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
inv(a, 10);
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
}
运行结果:
int fun(int x[],int n)
{
.
.
.
}
int main()
{
int a[10];
.
.
.
fun(a,10);
.
.
.
return 0;
}
void fun(int *x,int n)
{
.
.
.
}
int main()
{
int a[10];
.
.
.
fun(a,10);
.
.
.
return 0;
}
实参a为数组名,形参x为int *型的指针变量,调用函数开始后,形参x指向a[0],即x=&a[0],通过x值的改变,可以指向a数组的任一元素,如图所示:
void fun(int *x,int n)
{
.
.
.
}
int main()
{
int a[10];
int *p=a;
.
.
.
fun(a,10)
.
.
.
return 0;
}
实参p和形参x都是int*型指针变量。先使用实参指针变量p指向数组元素a[0],p的值是&a[0]。然后将p的值传给形参变量x,x的初始值也是&a[0],通过x的值的改变可以使x指向数组a的任一元素,如图所示:
void fun(int x[],int n)
{
.
.
.
}
int main()
{
int a[10];
int *p=a;
.
.
.
fun(p,10);
.
.
.
return 0;
}
void inv(int* x, int n)
{
int temp;
int m = (n - 1) / 2;
int* p;
p = x + m;
int* i;
i = x;
int* j;
j = x + n - 1;
for (i = x; i <= p; i++, j--)
{
temp = *i;
*i = *j;
*j = temp;
}
return;
}
int main()
{
int a[10];
int* p = a;//指针变量p指向a[0]
//输入数组a的元素
for (int i = 0; i < 10; i++, p++)
{
scanf("%d", p);
}
p = a;//将指针变量p重新指向a[0]
inv(p, 10);//调用inv函数,实参是变量p
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
运行结果:
上面的main函数中的指针变量p是有确定值的。如果在main函数中不设数组,只设指针变量,就会出错。假如把主函数修改如下:
void inv(int* x, int n)
{
int temp;
int m = (n - 1) / 2;
int* p;
p = x + m;
int* i;
i = x;
int* j;
j = x + n - 1;
for (i = x; i <= p; i++, j--)
{
temp = *i;
*i = *j;
*j = temp;
}
return;
}
int main()
{
int a[10];
int* p;
//输入数组a的元素
for (int i = 0; i < 10; i++)
{
scanf("%d", p+i);
}
inv(p, 10);//调用inv函数,实参是变量p
for (int i = 0; i < 10; i++)
{
printf("%d ", *(p+i));
}
return 0;
}
编译时会出错,原因是指针变量p没有确定值,谈不上指向哪个变量:
因此,下面这样的使用是不正确的:
void fun(int x[],int n)
{
.
.
.
}
int main()
{
int *p;
.
.
.
fun(p,10);
}
【注意】如果指针变量做实参,必须先使指针变量有确定的值,指向一个已经定义的对象。
【例】使用指针方法对10个整数按由大到小的顺序排列。
【思路】在主函数种定义数组a存放10个整数,定义int*型指针变量p指向a[0]。定义函数sort使数组a种的元素由大到小的顺序排列。在主函数中调用sort函数,用指针变量p作实参。sort函数的形参用数组名。用选择法进行排序。
//定义sort函数,x是形参数组名
void sort(int x[], int n)
{
int temp;
for (int i = 0; i < n-1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (x[j]>x[i])
{
temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
}
}
int main()
{
int a[10];
int* p = a;//指针变量p指向a[0]
//输入10个整数
for (int i = 0; i < 10; i++)
{
scanf("%d", p++);
}
p = a;//指针变量p重新指向a[0]
sort(p, 10);//调用sort函数
//输出排序后的10个数组元素
for (int i = 0; i < 10; i++)
{
printf("%d ", *p);
p++;
}
return 0;
}
运行结果:
如果sort函数中将x定义为指针变量,在函数中仍可以用x[i]和x[j]这样的形式表示数组元素,它就是x+i和x+j所指的数组元素。
因篇幅问题不能全部显示,请点此查看更多更全内容