c/c++ 一维数组、二维数组作为函数参数、返回值

64 篇文章 94 订阅

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的方法:

  1. 将size作为参数传入
  2. 使用数组的引用避免数组降价
    当参数是一个数组类型的引用时,数组长度成为参数与实参类型一部分,编译器会检查实参数组长度与形参是否匹配

int sum(int (& array )[10])

二、二维数组作为参数

与一维数组一样,比较常用有两种传入方式,但是区别在于必须写出列数。因为数组在调用时同样有数组降价的问题,实际函数得到的是一个指针,指向行向量构成的一维数组,这样每个一维数组的size必须提前定义好,便于分配栈空间。

  1. int sum(int array[][4], int size)
  2. 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);
}
  • 11
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值