前言
无论是在C语言还是C++中,函数都是十分重要的内容。可谓是整个程序的基础,一个优秀的工程程序,必定是由许多功能各异的函数组成。今天,我们就先来聊一聊函数,聊一聊函数与数组之间的关系。
函数的三要素
函数的组成
函数由三部分组成,分别是:返回值、函数名、参数列表,具体形式如下:
返回值 函数名(参数列表)
其中,返回值可以是除数组之外的任意数据类型,比如:整型、浮点型、结构体、类…
而函数名实际上就是函数的地址,参数列表指的是函数的形参或者实参。
函数的使用方法
在使用函数时,需要完成下述工作:
1、提供函数原型,即函数声明,描述了函数与编译器之间的接口,便于编译器查找函数;
2、提供函数定义,即函数实现;
3、调用函数
函数的参数传递与返回值
在C++中,提供了三种函数传递参数的方法,分别是:
1、值传递(包括传递空值);
2、地址传递;
3、引用传递
相对应的,函数的返回值也可以分为三种,分别是:
1、返回一个数值(包括返回空值);
2、返回一个地址;
3、返回一个引用。
函数与数组之间的爱恨情仇
函数返回数组的方法
在C++中,函数的返回值不能是数组,但是我们可以将数组作为结构体或者对象的成员进行返回。同时,我们不能对数组进行整体赋值,但是当数组作为结构体或者对象的成员时,便可以进行实现数组的整体赋值。如下:
//函数返回数组
#include <iostream>
using namespace std;
typedef struct
{
int arrayTemp[2][4];
}arrayStruct;
arrayStruct& setArray(arrayStruct&,int);
void showArray(arrayStruct& ,int );
int main()
{
arrayStruct arrayTwo;
showArray(setArray(arrayTwo,2),2);
return 0;
}
arrayStruct& setArray(arrayStruct& arraStruct,int row)
{
for(int i = 0;i < row;i++)
{
for(int j = 0;j < 4;j++)
{
arraStruct.arrayTemp[i][j] = j;
}
}
return arraStruct;
}
void showArray(arrayStruct& arraStruct,int row)
{
for(int i = 0;i < row;i++)
{
for(int j = 0;j < 4;j++)
{
cout << arraStruct.arrayTemp[i][j] << endl;
}
}
}
输出结果:
//对数组进行整体赋值
#include <iostream>
using namespace std;
typedef struct
{
int arrayTemp[2][4];
}arrayStruct;
arrayStruct& setArray(arrayStruct&,int);
void showArray(arrayStruct& ,int );
int main()
{
arrayStruct arrayTwo;
setArray(arrayTwo,2);
arrayStruct arrayTwoCopy;
arrayTwoCopy = arrayTwo;//赋值操作
showArray(arrayTwoCopy,2);//显示赋值后的数组元素
return 0;
}
arrayStruct& setArray(arrayStruct& arraStruct,int row)
{
for(int i = 0;i < row;i++)
{
for(int j = 0;j < 4;j++)
{
arraStruct.arrayTemp[i][j] = j;
}
}
return arraStruct;
}
void showArray(arrayStruct& arraStruct,int row)
{
for(int i = 0;i < row;i++)
{
for(int j = 0;j < 4;j++)
{
cout << arraStruct.arrayTemp[i][j] << endl;
}
}
}
输出结果:
通过上面的的示例,我们便实现了返回数组以及对数组进行整体赋值的操作!!!
数组作为函数参数
由前面的文章我们知道,数组名就是数组的首地址,也就是数组第一个元素的地址,当我们将数组名作为参数传递给函数时,实际上便是将数组的地址传递给了函数,即上述的地址传递。所以,我们在声明函数时,需要将参数定义为一个指针类型,示例如下:
//程序目的:对数组进行赋值后,打印在屏幕上
void setArray(int*,int length);//赋值函数声明
void showArray(const int*,int length);//打印函数声明
int main()
{
int arrayTest[10] = {0};
setArray(arrayTest,sizeof(arrayTest) / sizeof(arrayTest[0]));
showArray(arrayTest,sizeof(arrayTest) / sizeof(arrayTest[0]));
return 0;
}
void setArray(int* arrayTemp,int length)//赋值函数定义
{
for(unsigned int i = 0;i < length;i++)
{
arrayTemp[i] = i;
}
}
void showArray(const int* arrayTemp,int length)//打印函数定义
{
for(unsigned int i = 0;i < length;i++)
{
cout << arrayTemp[i] << "\t";
}
cout << endl;
}
程序运行结果:
二维数组作为函数参数
无论是一维数组还是二维数组,数组名都被视为数组的首地址,唯一不同的是:
在一维数组中,数组的首地址是数组第一个元素的地址,而对于二维数组而言,数组的首地址不仅是数组第一个元素的首地址,同时也是数组第一行的首地址。如下:
//一维数组的首地地址
int arrayOne[2] = {3,6};//声明一个一维数组,并进行初始化
cout << "一维数组的首地址为:" << array << endl;
cout << "一维数组的第一个元素的地址" << &array[0] << endl;
//二维数组的首地址
int arrayTwo[2][3] = {{2,3,4},{6,7,8}};//声明一个二维数组并进行初始化
cout << "二维数组的首地址为:" << arrayTwo << endl;
cout << "二维数组的第一个元素的地址" << &arrayTwo[0][0] << endl;
cout << "二维数组的第一行元素的地址" << &arrayTwo[0] << endl;
输出结果如下:
实际上,二维数组可以被理解为是由多个一维数组组成,而一维数组便是只有一行元素的二维数组。
在实际应用中,当我们需要将二维数组作为函数的参数时,一定要注意二维数组的参数传递形式,因为不容易理解,所以容易出错。我们需要牢记的是:我们传递的参数是一个指向数组的指针,而不是由指针组成的数组。如下所示:
//错误参数传递,参数表明其是一个由3个指向int类型的指针组成的数组
int sum(int *arrayTwo[3],int length);
//正确参数传递,参数表明其是一个由3个int数据组成的数组的指针
int sum(int (*arrayTwo)[3],int length);
//或者,这样的形式更容易理解,很容易知道传入的参数是一个二维数组
int sum(int arrayTwo[][3],int length);
在按照上面的示例,将二维数组作为函数参数时,务必将二维数组的列数在参数中进行准确的表示,而行数不需要进行显性的说明,并且说明之后,也不会起作用!!!
简而言之,我们只需要牢记,在将数组作为函数参数时,传输函数的参数一定是指针!!!
测例如下:
#include <iostream>
using namespace std;
void showArray(int [][4],int);
int main()
{
int arrayTwo[2][4] = {{1,2,3,4},{5,6,7,8}};
showArray(arrayTwo,2,4);
return 0;
}
void showArray(int arrayTwo[][4],int row)
{
for(int i = 0;i < row;i++)
{
for(int j = 0;j < 4;j++)
{
cout << arrayTwo[i][j] << endl;
}
}
}
输出结果如下:
总结
本文,主要介绍了C++中将一维数组和二维数组作为函数参数时的一些处理方法,但这只涉及普通数组的处理,当我们学习到动态内存分配时,情况将会变得更加复杂,我们将在后续的文章中进行总结学习。
本文如有错误和疏漏之处,还望各位读者不吝指正,谢谢!