c/c++ 一维数组、二维数组作为函数参数、返回值
一、一维数组作为参数
传入数组 int []
为了规范,常常需要将数组的size一同传入,这是因为C++/C遇到参数为数组时,不会去一个个拷贝数组内的元素(太过于耗时),此时数组在函数内退化为数组首地址。 使用sizeof(array)/sizeof(array[0])得到1,可以验证我们前面的说法。
一般情况下,函数内经常需要使用数组的size,此时就需要我们将size传入函数。
int sum(int array[], int size)
#include <stdio.h>
int sum(int array[],int size)
{
int summ=0,i;
for(i=0;i<size;i++)
{
summ+=array[i];
}
return summ;
}
int main()
{
int arr[3]={1,2,3};
int ArrSum;
ArrSum=sum(arr,3);//注意这边传入参数是还是写arr,而不能写arr[]或arr[3]
printf("%d",ArrSum);
return 0;
}
传入数组首地址 int *
int sum(int * array, int size)
与上面一种其实本质上并没什么不同。
不管哪一种,只要函数内部对传入的数组进行了修改,该数组本身的值也会改变,因为传入的都是地址,可以直接对地址上存储的元素进行修改。
#include <stdio.h>
int sum(int *array,int size)
{
int summ=0,i;
for(i=0;i<size;i++)
{
summ+=*(array+i);
}
return summ;
}
int main()
{
int arr[3]={1,2,3};
int ArrSum;
ArrSum=sum(arr,3);//这边传递的参数还是arr,和函数参数是数组一样
printf("%d",ArrSum);//但是这里的arr表示的是指针
return 0;
}
还有一种不推荐使用的传参方法
int sum(int array[20])
or
const int size = 20;
int sum(int array[size])
从效果来讲,与前面两种并无本质区别,但是容易出错,(const),而且函数内也get不到size
一维数组作为参数总结
三个等价的一维数组传参方式
int sum(int *)
int sum(int [])
int sum(int [10])
为了避免数组越界,传入size的方法:
- 将size作为参数传入
- 使用数组的引用避免数组降价
当参数是一个数组类型的引用时,数组长度成为参数与实参类型一部分,编译器会检查实参数组长度与形参是否匹配
int sum(int (& array )[10])
二、二维数组作为参数
与一维数组一样,比较常用有两种传入方式,但是区别在于必须写出列数。因为数组在调用时同样有数组降价的问题,实际函数得到的是一个指针,指向行向量构成的一维数组,这样每个一维数组的size必须提前定义好,便于分配栈空间。
- int sum(int array[][4], int size)
- int sum(int (*array)[4], int size)
这两种方法中size表示的都是行数,然后还有几种比较不常用的方法
#include <stdio.h>
int sum(int array[][3],int size)
{
int summ=0,i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
summ+=array[i][j];
}
}
return summ;
}
int main()
{
int arr[2][3]={1,2,3,4,5,6};
int ArrSum;
ArrSum=sum(arr,6);//注意只要参数是数组的,调用的时候就写数组名就可以了,不管是一维数组还是二维数组
printf("%d",ArrSum);
printf("\n%d",arr);
printf("\n%d",arr[0]);
return 0;
}
#include <stdio.h>
int sum(int *array,int size)//这边的参数是一个指向整型的指针
{
int summ=0,i;
for(i=0;i<size;i++)
{
summ+=*(array+i);//因此这边只需要一次间接寻址即可
}
return summ;
}
int main()
{
int arr[2][3]={1,2,3,4,5,6};
int ArrSum;
ArrSum=sum(arr[0],6);//注意这里传入的参数是arr[0]而不是arr,arr表示的是数组第一行(即arr[0])的地址,而arr[0]表示的是arr[0]]0]的地址,但是有一个奇怪的地方是arr和arr[0]的地址是一样的。
printf("%d",ArrSum);
printf("\n%d",arr);
printf("\n%d",arr[0]);
return 0;
}
#include <stdio.h>
int sum(int (*array)[3],int size)//这边的参数是一个数组指针,该指针指向的是一个数组(包含了三个int型的数组)
{
int summ=0,i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
summ+=*(*(array+i)+j);//深刻理解这个表达式的含义。
}
}
return summ;
}
int main()
{
int arr[2][3]={1,2,3,4,5,6};
int ArrSum;
ArrSum=sum(arr,6);//
printf("%d",ArrSum);
return 0;
}
三、函数返回数组
返回输入数组的指针
这里有个容易造成错误的点,函数返回的是数组指针(指向数组的指针),但是如果返回之后指针指向的数组被销毁了呢?
提到这里,再复习一下内存空间的四个区域,栈空间、堆区间、数据区(静态区)、代码区。静态变量、全局变量是放在数据区的,作用范围是全局的,而局部变量通常位于栈空间,随着被调用函数的退出自动释放空间被销毁。
一维数组,返回数组指针
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// 要生成和返回随机数的函数
int * getRandom( )
{
static int r[10];
// 设置种子
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// 要调用上面定义函数的主函数
int main ()
{
// 一个指向整数的指针,不是指向数组的指针,只是指向数组第一个元素对的指针。
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
#include "stdio.h"
#include "stdlib.h"
int * Max(int *arr,int n)
{
int *a=(int *)malloc(2*sizeof(int));
int maxNum=0,maxIndex,i;
for (i=0;i<n;i++)
if (arr[i]>maxNum)
{maxNum=arr[i];maxIndex=i+1;}
a[0]=maxNum;a[1]=maxIndex;
return a;
}
void main()
{
int a[2]={5,2};//a[0]=5,a[1]=2;
int *b=Max(a,2);
int i;
for(i=0;i<2;i++)
printf("b[%d]=%d\n",i,b[i]);
free(b);
}
二维数组指针
#include "stdio.h"
#include "stdlib.h"
int **Max(int **arr,int n,int m)
{
int **data,i,j;
data=(int **)malloc(n*sizeof(int *));//强制类型转换,将其转成二维指针。
for ( i=0;i<n;i++)
data[i]=(int *)malloc(2*sizeof(int));
for ( i=0;i<n;++i)
{
int maxNum=0;
for (j=0;j<m;++j)
{
//printf("arr[%d][%d]=%d ",i,j,*((int *)arr+m*i+j));
if (*((int *)arr+m*i+j)>maxNum)
{
maxNum=*((int *)arr+m*i+j);
data[i][0]=maxNum;data[i][1]=j;
}
}
//printf("\n");
}
return data;
}
void main()
{
int a[2][3]={5,2,4,6,3,9};
int **b=Max((int **)a,2,3);//同上,强制类型转换,这里为什么要进行类型转换呢,二维数组名是二维指针吗?看起来是,那编译不通过说明二维数组名不是二维指针。
int i;
for (i=0;i<2;i++)
{
printf("the maximum num for row %d is %d\n",i+1,b[i][0]);
printf("the maximum num for row %d is in %d",i+1,b[i][1]+1);
printf("\n");
}
for(i=0;i<2;i++)
free(b[i]);
free(b);
}