• 关于函数传参的其他问题(const形参实参/可变形参)


    const 形参和实参

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

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

    指针或引用形参与 const

     1 #include <iostream>
     2 using namespace std;
     3 
     4 void gel(int *a){
     5     ;
     6 }
     7 
     8 void gel(int &a){
     9     ;
    10 }
    11 
    12 int main(void){
    13     int i = 0;
    14     const int ci = i;
    15     string::size_type ctr = 0;
    16     gel(&i);//调用形参是int*的gel函数
    17     // gel(&ci);//错误,不能忽略底层const,即不能用指向const int的指针初始化int*
    18     gel(i);//调用形参是int&类型的gel函数
    19     // gel(ci);//错误,不能把普通引用绑定到const对象ci上
    20     // gel(1024);//错误,非常量引用不能绑定字面值
    21     // gel(ctr);//错误,类型不匹配,ctr是无符号类型的
    22     return 0;
    23 }

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

    main 函数传参:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main(int argc, char **argv){
     5     cout << argc << endl;
     6     for(int i = 0; i < argc; i++){
     7         cout << argv[i] << endl;
     8     }
     9     return 0;
    10 }

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

    含有可变形参的函数:

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

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

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

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

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

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

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

     1 #include <iostream>
     2 #include <initializer_list>
     3 using namespace std;
     4 
     5 void error_msg(initializer_list<string> li){
     6     for(auto indx : li){
     7         cout << indx << " ";
     8     }
     9     cout << endl;
    10 }
    11 
    12 int main(void){
    13     string s1, s2;
    14     cin >> s1 >> s2;
    15     if(s1 != s2) error_msg({"functionX", s1, s2});
    16     else error_msg({"functionX", "okay"});
    17     return 0;
    18 }

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

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

     1 #include <iostream>
     2 #include <initializer_list>
     3 using namespace std;
     4 
     5 void error_msg(initializer_list<string> li, int cnt){
     6     cout << cnt << ":" << endl;
     7     for(auto indx : li){
     8         cout << indx << " ";
     9     }
    10     cout << endl;
    11 }
    12 
    13 int main(void){
    14     string s1, s2;
    15     cin >> s1 >> s2;
    16     if(s1 != s2) error_msg({"functionX", s1, s2}, 1);
    17     else error_msg({"functionX", "okay"}, 2);
    18     return 0;
    19 }

    省略符形参:

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

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

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

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

     1 #include <iostream>
     2 #include <initializer_list>
     3 using namespace std;
     4 
     5 void gel1(string, ...){}
     6 
     7 void gel2(string ...){}//省略string后面的逗号
     8 
     9 void gel3(...){}
    10 
    11 void gel3(int a, int b){
    12     cout << a << " " << b << endl;
    13 }
    14 
    15 int main(void){
    16     int a = 1, b = 2;
    17     string s1 = "jf", s2 = "jfk";
    18     char ch1 = 'f', ch2 = 'j';
    19     gel1(s1, a, b, ch1, ch2);
    20     // gel1(a, a, a);//错误,指定了的形参会进行类型检查
    21     gel2(s1, a, b);
    22     // gel3(s1, a, b);//错误,string不是c和c++通用的类型
    23     gel3(a, b, ch1, ch2);
    24     gel3(a, b);//输出1 2.省略号的优先级别最低,所以在函数解析时,只有当其它所有的函数都无法调用时,编译器才会考虑调用省略号函数的。 
    25     return 0;
    26 }
  • 相关阅读:
    图论小测
    有关连通性
    差分约束
    php中代码执行&&命令执行函数【转载】
    Boss直聘的一个csrf与url跳转漏洞(已经修复)
    Immunity Canvas初体验加操作指南
    SSRF复习版本
    XXE漏洞复习版本
    信息收集汇总
    web前端逆向初体验
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/8038734.html
Copyright © 2020-2023  润新知