C语言日记 22 数组作为函数参数

例5-5 求三个数的平均值。(和普通变量用法一样)

源程序:

#include <iostream>
using namespace std;
int main()
{
    float fun(float a, float b, float c);//函数声明
    static float a[5] = { 87.5, 90, 100 };
    //定义一个 float 型数组并初始化
    float ave;
    ave = fun(a[0], a[1], a[2]);//调用 fun()函数
    cout << ave << endl;
}
float fun(float a, float b, float c)//函数定义
{
    float sum, aver;
    sum = a + b + c;
    aver = sum / 3.0;
    return(aver);
}

#include <iostream>
using namespace std;
int main()
{
	float fun(float a, float b, float c);//函数声明
	static float a[5] = { 87.5, 90, 100 };
	//定义一个 float 型数组并初始化
	float ave;
	ave = fun(a[0], a[1], a[2]);//调用 fun()函数
	cout << ave << endl;
}
float fun(float a, float b, float c)//函数定义
{
	float sum, aver;
	sum = a + b + c;
	aver = sum / 3.0;
	return(aver);
}

结果:
 

其实这里无论是不写static还是不把范围写的那么大,把a[5]改为a[3],都不影响结果。

只是我们平时为了保险起见,习惯性地这么写,有时候自然会避免一些没必要的麻烦

同时,前面的"sum = a + b + c;  aver = sum / 3.0;"也可以一步到位简写为“aver =( a + b + c) / 3.0;”。

实践实例如下:

#include <iostream>
using namespace std;
int main()
{
	float fun(float a, float b, float c);//函数声明
	float a[3] = { 87.5, 90, 100 };
	//定义一个 float 型数组并初始化
	float ave;
	ave = fun(a[0], a[1], a[2]);//调用 fun()函数
	cout << ave << endl;
}
float fun(float a, float b, float c)//函数定义
{
	float  aver;
	aver =( a + b + c) / 3.0;
	return(aver);
}

结果: 

 例5-6 求三个数的平均值。

#include <iostream>
using namespace std;
int main()
{
    float fun2(float x[3]);//函数声明
    float a[3] = { 87.5,90,100 }; //定义数组并初始化*/
    float ave;
    ave = fun2(a);//调用函数并将数组名作为参数*/
    cout << ave << endl;
}
    float fun2(float x[3])    //函数定义,形式参数为数组*/

    {
        float sum, aver;
        sum = x[0] + x[1] + x[2];
        aver = sum / 3.0;
        return(aver);
    }

#include <iostream>
using namespace std;
int main()
{
	float fun2(float x[3]);//函数声明
	float a[3] = { 87.5,90,100 }; //定义数组并初始化*/
	float ave;
	ave = fun2(a);//调用函数并将数组名作为参数*/
	cout << ave << endl;
}
	float fun2(float x[3])	//函数定义,形式参数为数组*/

	{
		float sum, aver;
		sum = x[0] + x[1] + x[2];
		aver = sum / 3.0;
		return(aver);
	}

 传递过程如下(描述过程参考(仿照)P87介绍例5-6 前面的一段文字):

结果同上:

书P87:

数组的首地址重合,后面的元素按照各自在内存中的存储顺序进行对用相同的数据存储地址

因此实参数组的元素个数不应该少于形参数

哦?这一点好像存疑(有待考证):

当实参数组的元素个数少于形参数:

#include <iostream>
using namespace std;
int main()
{
	float fun2(float x[3]);//函数声明
	float a[3] = { 87.5,90 }; //定义数组并初始化*/
	float ave;
	ave = fun2(a);//调用函数并将数组名作为参数*/
	cout << ave << endl;
}
float fun2(float x[3])	//函数定义,形式参数为数组*/

{
	float sum, aver;
	sum = x[0] + x[1] + x[2];
	aver = sum / 3.0;
	return(aver);
}

 如果只是删除一个数字,那么最终结果相当于把a[2]看为0处理求三个数的平均数。

也就是说,这样不会有事,程序还是不会出错。

#include <iostream>
using namespace std;
int main()
{
	float fun2(float x[3]);//函数声明
	float a[2] = { 87.5,90 }; //定义数组并初始化*/
	float ave;
	ave = fun2(a);//调用函数并将数组名作为参数*/
	cout << ave << endl;
}
float fun2(float x[3])	//函数定义,形式参数为数组*/

{
	float sum, aver;
	sum = x[0] + x[1] + x[2];
	aver = sum / 3.0;
	return(aver);
}

 但是如果我们把实参的具体元素个数改为a[2],那么这个结果就看起来有点奇怪了:

根据杨欢同学所说:

很可能大概率的情况为:

因为此时实参的内存空间只有2位

此时系统就会给第三位形参赋上一个随机值,这时候跳出什么结果都不稀奇。

而当实参数组的元素个数多于形参数时:

#include <iostream>
using namespace std;
int main()
{
	float fun2(float x[3]);//函数声明
	float a[5] = { 5,6,7,8,9}; //定义数组并初始化*/
	float ave;
	ave = fun2(a);//调用函数并将数组名作为参数*/
	cout << ave << endl;
}
float fun2(float x[3])	//函数定义,形式参数为数组*/

{
	float sum, aver;
	sum = x[0] + x[1] + x[2];
	aver = sum / 3.0;
	return(aver);
}

结果:6

也就是说,当实参数组的元素个数多于形参数时,函数默认值调用最前面几个参数(这里就是只算最前面三个实参的平均值)

如果在子函数中改变数组元素值,那么主调函数中实参数组的相应元素值也会相应改变。

在上述程序上设计改动证明该结论如下:

#include <iostream>
using namespace std;
int main()
{
    float fun2(float x[3]);//函数声明
    float a[3] = { 87.5,90,100 }; //定义数组并初始化*/
    float ave;
    ave = fun2(a);//调用函数并将数组名作为参数*/
    cout << ave << endl;
    cout << a[1] << endl;
}
float fun2(float x[3])    //函数定义,形式参数为数组*/

{
    float sum, aver;
    x[1] = 0;
    sum = x[0] + x[1] + x[2];
    aver = sum / 3.0;
    return(aver);
}

结果:

例5-7 将例 5-4中的求最大值用函数解决,并使用数组作为参数。

源程序:

#include <iostream>
using namespace std;
int main()
{
    int max_value(int array[][4]);
    int a[3][4] = { (11,32,45,67),(22,44,66,88),(15,72,43,37)};
    cout << "max value is " << max_value(a) << endl;
    return 0;
}
int max_value(int array[][4])
{
    int i, j, max;
    max = array[0][0];
    for (i = 0; i < 3; i++)
        for (j = 0; j < 4; j++)
            if (array[i][j] > max) max = array[i][j];
    return max;
}

#include <iostream>
using namespace std;
int main()
{
	int max_value(int array[][4]);
	int a[3][4] = { (11,32,45,67),(22,44,66,88),(15,72,43,37)};
	cout << "max value is " << max_value(a) << endl;
	return 0;
}
int max_value(int array[][4])
{
	int i, j, max;
	max = array[0][0];
	for (i = 0; i < 3; i++)
		for (j = 0; j < 4; j++)
			if (array[i][j] > max) max = array[i][j];
	return max;
}

我写的:

使用数组元素作为函数参数:这样搞我要申明12个形参,太麻烦了,这里我们就暂时省略。

使用数组名作为函数参数:

最开始写的:

#include <iostream>
using namespace std;
int main()
{
	int max_value(a[int x][int y]);
	int a[3][4] = { (11,32,45,67),(22,44,66,88),(15,72,43,37) };
	cout << "max value is " << max_value(a[3][4]) << endl;
	return 0;
}
int max_value(int a[int x][int y])
{
	int x,y, max;
	for (x = 0; x < 3; x++)
		for (y = 0; y < 4; y++)
			if (a[x][y] > max) max = a[x][y];
	return max;
}

根据书上的例5-6,照猫画虎,最终把上述程序修改为:

#include <iostream>
using namespace std;
int main()
{
	int max(int a[3][4]);
	int a[3][4] = { (11,32,45,67),(22,44,66,88),(15,72,43,37) };
	cout << "最大值为:" << max(a[3][4]) << endl;
	return 0;
}
int max(int a[3][4])
{
	int x,y,max=0;
	for (x = 0; x < 3; x++)
		for (y = 0; y < 4; y++)
			if  (a[x][y] > max) 
				max = a[x][y];
	return max;
}

但是结果还是不对:最终应改为:

#include <iostream>
using namespace std;
int main()
{
    int max(int a[3][4]);
    int a[3][4] = { (11,32,45,67),(22,44,66,88),(15,72,43,37) };
    cout << "最大值为:" << max(a) << endl;
    return 0;
}
int max(int a[3][4])
{
    int x, y, max=0;
    for (x = 0; x < 3; x++)
        for (y = 0; y < 4; y++)
            if (a[x][y] > max)
                max = a[x][y];
    return max;
}

整个过程主要问题在于:

声明和定义时,实参形参的长度和数据结构全都没有定义。

在修改过程中我的问题(疑惑):

1.书上不是说定义形参长度无所谓吗?我这里没有定义的都是形参,哪里错了?

2.说到形参长度,既然要长度,那为什么:

cout << "最大值为:" << max(a) << endl;
这个没声明长度可以,反而是

cout << "最大值为:" << max(a[3][4]) << endl;
不可以?

关于为什么的回答:

1. 形参长度确实是没有要求必须要写,但是这并不是在函数定义和声明里面写成(int a[int x][int y])的理由:

x和y是用来在每一个循环里面进行自增来进行下一位的处理的

在这里不是来打破形参数组的每行每列的要求限制的

即使这个形参数组的数组结构是可以灵活多变的,书上说了“形参数组可以不定义长度”

可书上也没说“形参数组可以不定义宽度以及其他的维度”啊

也就是说:

一方面形参数组可以不定义长度,另一方面形参数组不能忘了定义宽度以及其他的维度

或者说:

形参数组可以不定义长度,但是必须定义宽度以及其他的维度

2.为什么调用max函数时括号内(里)只能填a而不能填a[3][4]:

如果在括号内填a[3][4]

很可能(大概率)系统识别的a[3][4]是数组元素a[3][4]而不是a[3][4]整个数组整体

数组元素a[3][4]:a[3][4]里面第三行第四列的具体数组元素

更何况即使a代表整体数组,对于系统而言,这也只是一串数字而已

系统要的是一个int型的变量或者常量,不是一串数字

而如果在括号内填a:

a满足“是int型常量”,而且是数组首元素的内存首地址

没有语法错误,也可以传输地址,自然是正确选择

P88:

可以将max_value函数的首部改为以下几种情况,观察编译情况:

根据实际情况绘制如下表格:

int max_value(int array[][])  0
int max_value(int array[3][]) 0
int max_value(int array[3][4]) 1
int max_value(int array[10][10]) 0
int max_value(int array[12]) 0

1:运行成功;  0:报错;

上述结论无疑再次证明了:

形参数组可以不定义长度,但是必须定义宽度以及其他的维度

额外拓展:

为什么

int max_value(int array[10][4]) 1
int max_value(int array[3][10]) 0

?

原因如下:

详细可参考:

关于二维数组当做函数参数的问题_shujuliu818的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/Zz_zzzzzzz__/article/details/127250180#comments_25884677