前言
如果想要在函数中传递一个一维数组作为参数,必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,也可以传递一个多维数组作为形式参数。
三种数组传参方式
方式一
形式参数是一个指针(您可以在下一章中学习到有关指针的知识):
void myFunction(int *param)
{
.
.
.
}
方式 2
形式参数是一个已定义大小的数组:
void myFunction(int param[10])
{
.
.
.
}
方式 3
形式参数是一个未定义大小的数组:
void myFunction(int param[])
{
.
.
.
}
示例
现在,让我们来看下面这个函数,它把数组作为参数,同时还传递了另一个参数,根据所传的参数,会返回数组中元素的平均值:
double getAverage(int arr[], int size)
{
int i;
double avg;
double sum;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = sum / size;
return avg;
}
现在,让我们调用上面的函数,如下所示:
实例
#include <stdio.h>
/* 函数声明 */
double getAverage(int arr[], int size);
int main ()
{
/* 带有 5 个元素的整型数组 */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
/* 传递一个指向数组的指针作为参数 */
avg = getAverage( balance, 5 ) ;
/* 输出返回值 */
printf( "平均值是: %f ", avg );
return 0;
}
double getAverage(int arr[], int size)
{
int i;
double avg;
double sum=0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = sum / size;
return avg;
}
当上面的代码被编译和执行时,它会产生下列结果:
平均值是: 214.400000
可以看到,就函数而言,数组的长度是无关紧要的,因为 C 不会对形式参数执行边界检查。
利用数组传参求平均数
#include<stdio.h>
double outputs(float arr2[],int size); //声明一个求平均数的函数
int main()
{
int k;
printf("你想求几个数的平均数:");
scanf("%d",&k);
int arr1[k]; // 创建一个存放k个数的一维数组
for(int n = 0;n < k;n++) // 使用 for 循环依次向数组添加元素
{
printf("请输入第%d个数:",n+1);
scanf("%f",&arr1[n]);
}
printf("平均数为:%.4f\n",outputs(arr1,k)); // 向平均数函数赋值并输出结果(保留4位小数)
}
double outputs(float arr2[],int size) // 定义平均数函数并传值
{
double sum = 0;
for(int i = 0;i < size;i++) // 使用 for 循环求和
{
sum += arr2[i];
}
return sum/size; // 返回平均值
}
数组传参注意事项
数组用作函数入参时,最好带上其长度。
1、sizeof数组入参的结果是数组元素类型指针的大小
void getSize(int a[]){
int i;
i=sizeof(a);//这里的i在linux中是4,在Windows中也是4,是int *的大小,不管你传入的a有几个元素
int b;
b=sizeof(a)/sizeof(a[0]);//逻辑没错,a的大小除以元素的大小得到长度,可是sizeof(a)并不是数组占的空间,而是指针,也就是i
}
int main(){
int a[]={1,2,3,4,5};
getSize(a);
}
2、处理
void getSize(int a[],int size){
//int i;
//i=sizeof(a);//这里的i在linux中是4,在Windows中也是4,是int *的大小,不管你传入的a有几个元素
//int b;
//b=sizeof(a)/sizeof(a[0]);//逻辑没错,a的大小除以元素的大小得到长度,可是sizeof(a)并不是数组占的空间,而是指针,也就是i
int k = size;//已经保存入参大小
//遍历或者其他操作
…………
}
int main(){
int a[]={1,2,3,4,5};
int size = sizeof(a)/sizeof(a[0]);//此时a并不是入参,sizeof可以得到开发人员想要的结果
getSize(a,size);
}
二维数组传递给函数
如果我们想将二维数组作为实参传递给某个函数,如下代码是有问题的:
double * MatrixMultiple(double a[][], double b[][]);
原因可以简单理解为:编译器并没有那么高级,在二维以上的数组一定要规定一个最高维数:
double * MatrixMultiple(double a[][2], double b[][3]); /* 这才是正确的 */
列举 C 语言传递二维数组的方法。
方法1: 第一维的长度可以不指定,但必须指定第二维的长度:
void print_a(int a[][5], int n, int m)
方法2: 指向一个有5个元素一维数组的指针:
void print_b(int (*a)[5], int n, int m)
方法3: 利用数组是顺序存储的特性,通过降维来访问原数组!
void print_c(int *a, int n, int m)
如果知道二维数组的长度,当然选择第一或者第二种方式,但是长度不确定时,只能传入数组大小来遍历元素啦。
#include <stdio.h>
/*********************************
* 方法1: 第一维的长度可以不指定
* 但必须指定第二维的长度
*********************************/
void print_a(int a[][5], int n, int m){
int i, j;
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
/*****************************************
* 方法2: 指向一个有5个元素一维数组的指针
*****************************************/
void print_b(int (*a)[5], int n, int m) {
int i, j;
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
/***********************************
* 方法3: 利用数组是顺序存储的特性,
* 通过降维来访问原数组!
***********************************/
void print_c(int *a, int n, int m) {
int i, j;
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++)
printf("%d ", *(a + i*m + j));
printf("\n");
}
}
int main(void)
{
int a[5][5] = {{1, 2}, {3, 4, 5}, {6}, {7}, {0, 8}};
printf("\n方法1:\n");
print_a(a, 5, 5);
printf("\n方法2:\n");
print_b(a, 5, 5);
printf("\n方法3:\n");
print_c(&a[0][0], 5, 5);
// getch();
return 0;
}