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. java成神之——集合框架之队列,栈,集合并发

    集合 队列和双端队列 PriorityQueue Deque BlockingQueue Queue 栈 集合并发 线程锁 线程安全集合 结语 集合 队列和双端队列 PriorityQueue 此队列 ...

  2. phpStudy启动失败时的解决方法 提示缺vc9运行库

    问题描述: 问题产生原因分析: php5.3.5.4和apache都是用vc9编译,电脑必须安装vc9运行库才能运行. php5.5.5.6是vc11编译,如用php5.5.5.6必须安装vc11运行 ...

  3. X11 转发

    SecureCRT只支持字符界面,如果要在终端界面能弹出GUI,需要本地安装X11 server,然后服务器讲X11请求forward到本地,即可. x11 server 可以使用Xming, Xma ...

  4. Java的Base64加密原理

    出自:   http://www.cnblogs.com/winner-0715/p/5920269.html http://www.cnblogs.com/koliop090/p/5203553.h ...

  5. 从cocos2d-x-2.x到cocos2d-x-3.x: lua项目配置

    cocos2dx-x3.0的正式版出来也有一段时间了,现在最新的版本是到了3.2alpha,和2.x系列相比,能够找到的相关资料除了官网上的wiki,其他的也不见得多,遇到的一些和2.x的差异和问题在 ...

  6. 接口测试中如何利用cookies保持会话

    使用cookies保持会话自己研究了下应该有两种方式: 1.保持会话的第一种方法:如果用的是同一个HttpClient且没去手动连接放掉client.getConnectionManager().sh ...

  7. Linux ping不通外网

    在linux中ping www.baidu.com 无法ping通,可能原因是DNS没配置好 方法一: 修改vi /etc/resolv.conf  增加如下内容: nameserver 114.11 ...

  8. SpringBoot RestController 同时支持返回xml和json格式数据

    @RestController 默认支持返回json格式数据,即使不做任何配置也能返回json数据 当接口需要支持xml或json两种格式数据时应该怎么做呢? 只要引入 Jackson xml的 ma ...

  9. 关于windows的锁定状态

    本来以为要在项目里用上的,现在看来不需要了,把相关的函数列一下吧,以后如果用到了,再写详细点 锁定计算机 : LockWorkStation 注册Windows状态变化的监听函数: BOOL WTSR ...

  10. 14-stringstream

    C++中stringstream的使用方法和样例 原创 2016年11月06日 15:46:49 标签: string / C++ 7427 之前在leetcode中进行string和int的转化时使 ...