const 形参和实参

当形参是 const 变量时,实参是 const 或者不是 const 变量都可以。 实参初始化形参时会忽略掉顶层 const:

 void gel(const int a){
;
} void gel(int a){
;
}
//这两个gel函数的形参列表是等价的,因此会出现编译错误。

指针或引用形参与 const

 #include <iostream>
using namespace std; void gel(int *a){
;
} void gel(int &a){
;
} int main(void){
int i = ;
const int ci = i;
string::size_type ctr = ;
gel(&i);//调用形参是int*的gel函数
// gel(&ci);//错误,不能忽略底层const,即不能用指向const int的指针初始化int*
gel(i);//调用形参是int&类型的gel函数
// gel(ci);//错误,不能把普通引用绑定到const对象ci上
// gel(1024);//错误,非常量引用不能绑定字面值
// gel(ctr);//错误,类型不匹配,ctr是无符号类型的
return ;
}

应该尽量使用常量引用避免将普通引用形参绑定到const 对象上的错误。

main 函数传参:

 #include <iostream>
using namespace std; int main(int argc, char **argv){
cout << argc << endl;
for(int i = ; i < argc; i++){
cout << argv[i] << endl;
}
return ;
}

main 函数有两个形参,通常命名为 argc 和 argv,其中 argv 是一个字符串数组,而 argc 是字符串数组的长度。其中 argv[0] 保存该源文件生成的可执行文件的名字,使用 argv 中的实参时,可选实参时从 argv[1] 开始的。

含有可变形参的函数:

为了能编写能处理不同数量实参的函数,c++11 新标准提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为 initializer_list 的标准库类型,如果实参的类型不同,可以编写一种特殊的函数--可变参数模板。

c++ 还有一种特殊的形参类型--省略符 可以传递可变数量的实参。这种功能一般只用于与 C 函数交互的接口程序。

initializer_list 定义在 initializer_list 头文件中。它提供的操作有:

     initializer_list<T> lst;//默认初始化,T类型元素的空列表
initializer_list<T> lst{a, b, c...};//lst 的元素和初始值一样多,lst 的元素是对应初始值的副本,列表中的元素是 const
lst2(lst);//拷贝或赋值一个 initializer_list 对象不会拷贝列表中的元素,拷贝后,原始列表和副本共享元素
lst2 = lst;
lst.size();//列表中元素的数量
lst.begin();//返回指向列表中首元素的指针
lst.end();//返回lst列表中的尾后指针

和 vector 一样,initializer_list 也是一种模板类型,定义 initializer_list 对象时,必须说明列表中所含元素的类型。

     initializer_list<string> ls;//initializer_list 的元素类型时 string
initializer_list<int> li;//initializer_list 的元素类型时 int

如果时向 initializer_list 形参中传递一个值的序列,则必须把序列放在一对花括号内,且允许多次调用传递的参数数目不同:

 #include <iostream>
#include <initializer_list>
using namespace std; void error_msg(initializer_list<string> li){
for(auto indx : li){
cout << indx << " ";
}
cout << endl;
} int main(void){
string s1, s2;
cin >> s1 >> s2;
if(s1 != s2) error_msg({"functionX", s1, s2});
else error_msg({"functionX", "okay"});
return ;
}

因为 initializer_list 包含 begin 和 end 成员,所以可以使用范围 for 循环。

对于含有 initializer_list 形参的函数,其形参列表是允许含有其他类型的形参的,而 initializer_list 形参中只能传指定类型的对象。

 #include <iostream>
#include <initializer_list>
using namespace std; void error_msg(initializer_list<string> li, int cnt){
cout << cnt << ":" << endl;
for(auto indx : li){
cout << indx << " ";
}
cout << endl;
} int main(void){
string s1, s2;
cin >> s1 >> s2;
if(s1 != s2) error_msg({"functionX", s1, s2}, );
else error_msg({"functionX", "okay"}, );
return ;
}

省略符形参:

省略符形参是为了方便于 c++ 程序访问某些特殊的 c 代码而设置的,这些代码使用了名为 varargs 的 c 标准库功能。省略符形参应该仅仅用于 c 和 c++ 通用的类型,且大多数类型的对象在传递给省略符形参时都无法正确拷贝。

省略符形参只能出现在列表的最后一个位置,它的表现形式只有以下两种:

void gel(parm_list, ...);
void gel(...);

第一种形式指定了 gel 函数的部分形参类型,对应于这些形参的实参将会执行正确的类型检查。省略符形参所对应的实参类型无需类型检查。在第一种形式中,声明符后面的逗号是可选的。

 #include <iostream>
#include <initializer_list>
using namespace std; void gel1(string, ...){} void gel2(string ...){}//省略string后面的逗号 void gel3(...){} void gel3(int a, int b){
cout << a << " " << b << endl;
} int main(void){
int a = , b = ;
string s1 = "jf", s2 = "jfk";
char ch1 = 'f', ch2 = 'j';
gel1(s1, a, b, ch1, ch2);
// gel1(a, a, a);//错误,指定了的形参会进行类型检查
gel2(s1, a, b);
// gel3(s1, a, b);//错误,string不是c和c++通用的类型
gel3(a, b, ch1, ch2);
gel3(a, b);//输出1 2.省略号的优先级别最低,所以在函数解析时,只有当其它所有的函数都无法调用时,编译器才会考虑调用省略号函数的。
return ;
}

关于函数传参的其他问题(const形参实参/可变形参)的更多相关文章

  1. python函数传参是传值还是传引用?

    首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...

  2. [Java]_函数传参的疑惑与思考

    问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. void dfs(TreeNode node , int sum , ArrayList& ...

  3. pytest十一:函数传参和 firture 传参数 request

    为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行.但是登录 ...

  4. 『Python × C++』函数传参机制学习以及对比

    一.Python函数传参 在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么 ...

  5. 函数传参传的是啥的思考【java Python】

    今天看<java 核心 卷1>的时候,作者提到了函数传参的问题,他提到,java传参,传的是值,而不是引用,然后,函数将要传的实参的值(如果实参是基本数据类型,那么就是值.如果实参是对象, ...

  6. JS——变量和函数的预解析、匿名函数、函数传参、return

    JS解析过程分为两个阶段:编译阶段.执行阶段.在编译阶段会将函数function的声明和定义都提前,而将变量var的声明提前,并将var定义的变量赋值为undefined. 匿名函数: window. ...

  7. C#篇(三)——函数传参之引用类型和值类型

    首先应该认清楚在C#中只有两种类型: 1.引用类型(任何称为"类"的类型) 2.值类型(结构或枚举) 先来认识一下引用类型和值类型的区别: 函数传参之引用类型: 1.先来一个简单的 ...

  8. pytest_函数传参和firture传参数request

    前言为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...

  9. 函数传参和firture传参数request

    前言 为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行.但 ...

随机推荐

  1. 0003-程序流程1之app.js

    index.html中引入各种依赖的文件 由ng-app处开始angular Js的管理 angular.module('App', ['']) .run(function($rootScope,.. ...

  2. 一篇文章让你了解并掌握memcached

    第一章 memcached简介 1.1为什么引入memcached 随着数据量的增大,访问的集中,REBMS负担加重,数据库响应恶化. Memcached是高性能的分布式内存缓存服务器,目的是通过缓存 ...

  3. spark 中文编码处理

    日志的格式是GBK编码的,而hadoop上的编码是用UTF-8写死的,导致最终输出乱码. 研究了下Java的编码问题. 网上其实对spark输入文件是GBK编码有现成的解决方案,具体代码如下 impo ...

  4. 如何使用ThinkPHP5 ,自动生成目录?

    具体步骤: A.在build.php中按照实际需求修改定义模块的内容: B.修改Public/index.php,在代码中加入: // 读取自动生成定义文件 $build = include '/.. ...

  5. js格式化时间和时间操作

    js格式化时间 function formatDateTime(inputTime) { var date = new Date(inputTime); var y = date.getFullYea ...

  6. Leetcode:Container With Most Water分析和实现

    题目大意是提供n个非负整数,a1,...,an,可以将其理解为多个边界(垂直的线段),其中ai处于x坐标i处,并且ai代表的线段高度即为ai的值.要求我们取这样的i与j,使得ai与aj以及x坐标轴围成 ...

  7. ZOJ3954 Seven-Segment Display

    题意: emmmm见原题吧 分析: 这也是当时省赛选拔的题,场上以为是大模拟,然后没敢写...补题发现是道水题··· 因为每一列的顺序不一定,但是行是一定的.所以只要把每一列组成一个数字,然后弄两个集 ...

  8. 【bzoj1017】[JSOI2008]魔兽地图DotR

    1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1658  Solved: 755[Submit][S ...

  9. Linux中IO监控命令的使用分析

    一篇不错的有关linux io监控命令的介绍和使用. 1.系统级IO监控 iostat iostat -xdm 1    # 个人习惯 %util         代表磁盘繁忙程度.100% 表示磁盘 ...

  10. Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…

    好像是某CF的题,不记得…… 很套路的题,但是觉得可以做一下笔记. 倍增 + 差分. 有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x ...