美文网首页
[进阶]C++:数组形参

[进阶]C++:数组形参

作者: 离群土拨鼠 | 来源:发表于2019-07-09 17:26 被阅读0次

    使用表准库规范

    #include <iostream>
    using namespace std;
    namespace print
    {
        void Print(const int* a, const int* b)
        {
            while (a != b)
            {
                std::cout << *a++ << std::endl;
    
            }
        }
        void Print(const int* a, const size_t b)
        {
            for (size_t i = 0; i < b; i++)
            {
                cout << a[i] << endl;
            }
        }
    }
    int main()
    {
        std::cout << "Hello World!\n";
        int j[2] = { 0,1 };
        print::Print(begin(j), end(j));//用到了标准库
        print::Print(j, end(j)-begin(j));//用到了标准库
    }
    

    传递多维数组

    • C++语言中实际上没有真正的多维数组,多为的多维数组实际上是数组的数组
    void print (int max[][10],int rowSize){}
    

    等价定义

    void Print (int(*max)[10], int rowSize) {}
    

    main:处理命令行选项

    int main(int argc,char *argv[]){}
    

    第二个形参argv是一个数组,它的原属是指向C风格的字符串指针,第一个形参argc表示数组中字符串的数量。也可以写成如下形式

    int main(int argc,char **argv){}
    

    当实参传递给main后,第一个元素指向程序的名字或者空字符串
    之后传递命令行提供的参数

    prog -d -o oflie data0
    
    argv[0]="prog";
    argv[1]="-d";
    argv[2]="-o";
    argv[3]="ofile";
    argv[4]="data0";
    argv[5]="0";
    
    

    含有可变形参的函数

    有时我们无法提前预知应该向函数传递几个实参。如果所有的实参类型相同,可以传递一个名为initializer_list的标准库类型;如果类型不同,可以编写一个特殊的函数,以后会讲到

    • initializer_list形参
      如果函数的实参数量未知,但是所有的类型相同。
    void Error_Msg(initializer_list<string> il)
    {
        for (auto beg = il.begin(); beg < il.end(); beg++)
        {
            cout << *beg << "";
            cout << endl;
        }
    }
    int main()
    {
        std::cout << "Hello World!\n";
        Error_Msg({ "H","s","v" });//三个参数
        Error_Msg({ "R","G" });//两个参数
    }
    

    省略符参数

    • 省略符参数有两种形式:
    void foo(parm_list,...)
    void foo(...)
    

    第一种形式指定了foo函数的部分形参的类型

    返回类型

    • 不要返回局部对象的引用或指针
    const string& mainip()
    {
        string ret;
        if (!ret.empty())
        {
            return ret;//错误。返回局部对象的引用
        }
        else
        {
            return "Empty";//错误,返回一个局部临时变量
        }
    }
    int main()
    {
        std::cout << "Hello World!\n";
        cout<<mainip()<<endl;
    }
    

    对于第一个return,显然它返回的是一个局部变量。第二个return中,字符串字面值转换成了一个局部临时变量,该对象和ret一样是局部的。

    • 引用返回左值
      调用一个引用的函数得到左值,其他返回类型得到右值。
    char& get_val(string& str, string::size_type ix)
    {
        return str[ix];
    }
    int main()
    {
        std::cout << "Hello World!\n";
        string s("a value");
        cout << s << endl;//输出a value
        get_val(s, 0) = 'A';//将s[0]改成A
        cout << s << endl;//输出A value
    
    }
    

    列表初始化返回

    • 根据C++11的新规定,函数可以返回花括号包围的值的列表
    vector<string> process()
    {
        return{"a","b"};
    }
    

    返回数组指针

    • 因为数组不能被拷贝,所以不能返回数组。不过可以返回数组的指针或引用。
    typedef int arrt[10];
    arrt* func(int i);//func返回一个指向含有10个整数的数组的指针
    
    • 声明一个返回数组指针的函数
    int arr[10];//arr是一个含有10个整数的数组
    int *p1[10];//p1是一个含有10个指针的数组
    int(*p2)[10]=&arr;//p2是一个指针,他指向含有10个整数的数组
    
    • 如果我们想定义一个返回数组指针的函数,则数组的维度必须跟在函数名字之后。举个例子:
    int (*func(int i)) [10];//
    

    ( * func ( int i ) )表示我们能对函数调用的结果执行解引用操作
    ( * func ( int i ) )[10]表示解引用func的调用将得到一个大小是10的数组。

    • 也可以使用尾置返回类型。
    auto func(int i)->int(*)[10];
    //func接受一个int类型的实参,返回一个指针,该指针指向一个含有10个整数的数组
    

    使用decltype

    • 如果我们知道返回的指针指向那个指针,就可以使用decltype关键字声明返回类型。
    int odd[]={1,2,3,4};
    int even[]={5,6,7,8};
    decltype(odd) *arrPtr(int i)
    {
      return (i%2)? &odd:&even;
    //返回一个指向数组的指针
    }
    

    参考:C++primer 第五版

    相关文章

      网友评论

          本文标题:[进阶]C++:数组形参

          本文链接:https://www.haomeiwen.com/subject/caeahctx.html