关于函数传参的其他问题(const形参实参/可变形参)
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形参实参/可变形参)的更多相关文章
- python函数传参是传值还是传引用?
首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...
- [Java]_函数传参的疑惑与思考
问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. void dfs(TreeNode node , int sum , ArrayList& ...
- pytest十一:函数传参和 firture 传参数 request
为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登录函数就行.但是登录 ...
- 『Python × C++』函数传参机制学习以及对比
一.Python函数传参 在python中,函数传参实际上传入的是变量的别名,由于python内在的变量机制(名称和变量值相互独立),只要传入的变量不可变(tuple中的元素也要是不可变的才行),那么 ...
- 函数传参传的是啥的思考【java Python】
今天看<java 核心 卷1>的时候,作者提到了函数传参的问题,他提到,java传参,传的是值,而不是引用,然后,函数将要传的实参的值(如果实参是基本数据类型,那么就是值.如果实参是对象, ...
- JS——变量和函数的预解析、匿名函数、函数传参、return
JS解析过程分为两个阶段:编译阶段.执行阶段.在编译阶段会将函数function的声明和定义都提前,而将变量var的声明提前,并将var定义的变量赋值为undefined. 匿名函数: window. ...
- C#篇(三)——函数传参之引用类型和值类型
首先应该认清楚在C#中只有两种类型: 1.引用类型(任何称为"类"的类型) 2.值类型(结构或枚举) 先来认识一下引用类型和值类型的区别: 函数传参之引用类型: 1.先来一个简单的 ...
- pytest_函数传参和firture传参数request
前言为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...
- 函数传参和firture传参数request
前言 为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数.比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行.但 ...
随机推荐
- 转:Python正则表达式指南
本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...
- oracle:RETURNING 子句
RETURNING 自己通常结合DML 语句使用.(INSERT UPDATE DELETE) 使用方法: UPDATE table_name SET expr1 RETURNING column_n ...
- 管理授权&管理决策&管理组织&管理目标
[管理授权] 1.如果一个管理者不明白为公司培养人的责任,就很可能成为公司的瓶颈.这个问题的解决在于让管理者学会“授权”,把大部分自己紧抓不放的事情下放给部门内其他人做. 2.为一件事负责和亲自做是两 ...
- Android输入法部分遮挡UI的问题(与EditText框相切)
首先,我们来看看遇到问题的图片 遇到的问题是,当点击输入框之后,输入法会切到红线的位置,理想状态应该是在绿线位置 那么,是什么原因造成的呢? 问题其实很简单,是因为drawableleft图片比该输入 ...
- Elasticsearch聚合限制内存使用
限制内存使用 通常为了让聚合(或者任何需要访问字段值的请求)能够快点,访问fielddata一定会快点, 这就是为什么加载到内存的原因.但是加载太多的数据到内存会导致垃圾回收(gc)缓慢, 因为JVM ...
- 刷题向》图论》BZOJ1001 平面图最大流、平面图最小割、单源最短路(easy+)
坦白的说这是一道水题,但是因为是BZOJ上的1001,所以这道题有着特殊的意义. 关于最大流转最短路的博客链接如下:关于最大流转最短路两三事 这道题的图形很规矩,所以建边和建点还是很简单的. 题目如下 ...
- Mask_RCNN训练模型初步测试结果
调用训练的模型,加载测试集,发现测试效果并不理想,所以,需要调整训练参数,继续训练模型
- 246. Strobogrammatic Number 上下对称的数字
[抄题]: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at u ...
- dataview 组件使用示例
来自<sencha touch 权威指南> ------------------------------- 例子1——app.js代码如下: Ext.require(['Ext.data. ...
- poj1722 SUBTRACT
应该是基础的dp练手题 线性dp最主要的就是关于阶段的划分,这个题中我没想到的一点就是开状态的时候使用了前i个数能合成的数来记录 我自己的想法就是类似于区间dp这样的记录方法,这种方法确实开了很多冗余 ...