数组作为参数

写C++代码遇到数组作为参数,常常忘记怎么写形参,这里记录一下。

  • 一维数组作为参数
  1. 传入数组 int []
    为了规范,常常需要将数组的size一同传入,这是因为C++/C遇到参数为数组时,不会去一个个拷贝数组内的元素(太过于耗时),此时数组在函数内退化为数组首地址。 使用sizeof(array)/sizeof(array[0])得到1,可以验证我们前面的说法。
    一般情况下,函数内经常需要使用数组的size,此时就需要我们将size传入函数。
int sum(int array[], int size)
  1. 传入数组首地址 int *
int sum(int * array, int size)

与上面一种其实本质上并没什么不同。
不管哪一种,只要函数内部对传入的数组进行了修改,该数组本身的值也会改变,因为传入的都是地址,可以直接对地址上存储的元素进行修改。

  1. 还有一种不推荐使用的传参方法
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表示的都是行数,然后还有几种比较不常用的方法
  3. 固定两个维度,比较死板
int sum(int array[10][4])
  1. 使用二维指针 , n,m分别表示行数、列数
int sum(int **array, int n, int m)int ** array =  new int *[n];
for(int i=0;i<n;i++)
{array[i] = new int[m];
}
for(int i=0;i<n;i++)
{delete [] array[i];
}
delete [] array;

因为每一行都是单独new的,这样有个坏处就是数组空间是不连续的

  1. 使用二维指针,但是将内存分配连续化
int sum(int **array, int n, int m)
int ** array = new int *[n];
array[0] = new int[n*m];delete []array[0];
delete []array;
  • 二维数组作为参数总结
    一般情况下,前面二种方式够用。但如果遇到列大小未知时,形参那里不能传入const int类型时,可以通过手动new、delete空间使用后面二种方式。

  • 函数返回数组

  1. 返回输入数组的指针
    这里有个容易造成错误的点,函数返回的是数组指针,但是如果返回之后指针指向的数组被销毁了呢?
    提到这里,在复习一下内存空间的四个区域,栈空间、堆区间、数据区(静态区)、代码区。静态变量、全局变量是放在数据区的,作用范围是全局的,而局部变量通常位于栈空间,随着被调用函数的退出自动释放空间被销毁。
    如果函数内部new一个数组, 然后函数结束返回这个数组指针,就会出现数组其实已经被销毁的情况,为了解决这个问题,可以将一个空的数组的首地址传入函数,然后返回。
int * sum(int * array, int *res, int size)int array[3] = {1,2,3};
int *res = new int [3];or int res[3] ;
// 不能是 int *res;//不是一个数组
  1. 利用静态变量返回数组
    上一条提过静态变量存放在静态区,作用范围是全局的,而且函数执行之后不会释放这一部分的空间。可以在函数内部定义静态的局部数组返回。
int * sum(int * array, int size){static int * res= new int[size];}

静态局部变量在第一次使用时分配内存并初始化,而全局变量与全局静态变量以及类的静态成员在main函数执行之前就分配内存并初始化。
// 注意这里 使用 static int res[size];出错 提示 res的存储size不是常量, 而且即便把 size改为 const int类型同样报错。
但是 int res[size]不会报错,暂时还不理解。

通常返回数组是需要知道其size的,这一点可以通过再传入一个size的引用解决。
但是一般遇到这种情况推荐使用vector等数据结构。

还有一些知识点:

  • char数组的长度
    当返回的是char数组的长度时,以‘\0’为识别符号计算长度,可以通过strlen()计算长度

  • sizeof length strlen 还有size这几个计算长度的函数的区别

  1. 首先strlen一般用于求字符串数组的长度的,参数是char *,也可以求解string类型长度
  2. C++中length()只是用于字符串长度的函数。strlen() length() size()都可以求string长度
  3. sizeof()求所占空间的总字节数,也可以用于求长度 sizeof(数组名)/sizeof(第一个元素) 当用于字符数组时需要-1,因为末尾有’\0’

c++ 数组作为参数、返回值相关推荐

  1. java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回

    java方法带参数返回值 在当前的系列文章中,我正在致力于减少调用Java方法和构造函数所需的参数数量,到目前为止,我一直专注于直接影响参数本身的方法( 自定义类型 , 参数对象 , 构建器模式 , ...

  2. Java数组作为方法返回值

    // 数组作为方法返回值 一个方法可以有0.1.多个参数:但是只能有0或者1个返回值. 如果希望一个方法当中产生了多个结果数据进行返回, 使用一个数组作为返回值类型即可. 任何数据类型都能作为方法的参 ...

  3. 学习大数据的第13天——Java面向对象(接口、分析参数返回值的类型不同时如何解决、包以及访问权限修饰符(public、protected、默认、private))

    学习大数据的第13天--Java面向对象(接口.分析参数返回值的类型不同时如何解决.包以及访问权限修饰符(public.protected.默认.private)) 接口 接口的基本定义: 1.1.语 ...

  4. 数组作为方法返回值_返回地址

    package com.learn.day05.demo03;/* 一个方法可以有0.1.多个参数:但是只能有0或者1个返回值,不能有多个返回值. 如果希望一个方法当中产生了多个结果数据进行返回,怎么 ...

  5. java 参数返回_Java基础---Java中带参数返回值方法的使用(四十)

    Java 中带参带返回值方法的使用 如果方法既包含参数,又带有返回值,我们称为带参带返回值的方法. 例如:下面的代码,定义了一个 show 方法,带有一个参数 name ,方法执行后返回一个 Stri ...

  6. 函数指针,函数指针数组,函数返回值为函数指针

    函数的名字就是函数的首地址:定义函数指针; int (*p)(int )     p为函数指针变量名字,int 为函数的返回值类型为int型:(int)为函数的形参类型为int型, 注:因为优先级所以 ...

  7. Java基础---Java中带参数返回值方法的使用(四十)

    Java 中带参带返回值方法的使用 如果方法既包含参数,又带有返回值,我们称为带参带返回值的方法. 例如:下面的代码,定义了一个 show 方法,带有一个参数 name ,方法执行后返回一个 Stri ...

  8. python3 限定方法参数 返回值 变量 类型

    typing模块的作用 自python3.5开始,PEP484为python引入了类型注解(type hints) 类型检查,防止运行时出现参数和返回值类型.变量类型不符合. 作为开发文档附加说明,方 ...

  9. java 函数参数 返回值_java中如何用函数返回值作为post提交的参数?

    1.我想实现的功能是在java程序中导入HttpURLConnection类,然后将函数的值作为post方法要提交的参数,最后显示在显示台上. 2.要用到的函数是自己写的可以显示实时计算机cpu.内存 ...

  10. python函数调用位置_python函数定义,调用,传参,位置参数及关键字参数,返回值

    使用函数是真正开始编程的第一步,函数y=f(x)我们并不陌生,对x进行一顿操作得到一个值y.给不同的x,进行相同的操作,得到相应的y值. 程序层面函数是执行特定任务的一段代码,将一段代码定义成函数并为 ...

最新文章

  1. 帮我看看这个是什么意思 c++代码
  2. mac idea用自带的maven还是_免费版的 IDEA 为啥不能使用 Tomcat ?
  3. xgb多线程成功运行记录
  4. Python3 注释
  5. redis系列:通过队列案例学习list命令
  6. web.xml中webAppRootKey
  7. java解析ajax的数据_java ajax 请求后获取 json 数据 以及 使用 解析 ,解惑
  8. 绘图的尺寸_Auto CAD机械绘图尺寸标注教程10(标注多重引线)
  9. wamp 局域网访问
  10. 针对dhtmlX当中的treegrid在java类当中的封装实现的步骤(后台代码)
  11. WAIT numslaves timeout
  12. JAVA实现时间换算
  13. linux 内网ip扫描工具,C#开发:局域网IP地址扫描小工具
  14. [干货] 杜绝广告, 让你的电脑变的更加干净舒适
  15. pythonrender函数_Render函数
  16. 灰度变换-位图切割(比特平面分层)
  17. ncm格式转mp3格式
  18. 第7章、 Linux 档案与目录管理
  19. moment中时间为12小时制,dayjs中时间为12小时制
  20. 配置eyeOS系统--1--虚拟机下安装CentOS6系统

热门文章

  1. 从0到1搭建数仓DWD层案例实践
  2. postgreSQL的外键级联删除
  3. MySQL的安装(超详细,附教程、安装包)
  4. linux创建邮件列表,如何订阅linux-kernel邮件列表
  5. 【Alpha】阶段第九次Scrum Meeting
  6. 模块电路选型(2)----主控模块
  7. 【深度学习】 MAE|心中无码,便是高清
  8. 文件夹内图片消失不见了怎么办?文件夹内图片消失怎样找回来
  9. ZOJ 3084 SG函数
  10. 虚拟机安装Linux系统