返回值处理
在代码的编译运行时,常常需要一个函数最后返回多个结果,返回的结果中可能是类型相同的也可能时不同的,多个返回类型已经不能或者用现有的方式能很好的解决这个问题,如果是同一类型的返回值,我们可以返回数组,如果是多个不同的返回值,那么已经显得比较乏力,如何处理返回值已经成为了重要的问题。
我们可以将所有需要返回的数据类型扔进一个结构体,在返回时只需要返回一个结构体即可。
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <string> struct Returntype { int x; int y; std::string s1; }; Returntype Example (int a,int b,std::string s) { a=a+10 ; b=a+15 ; name=s; Returntype r1; r1.x=a; r1.y=b; r1.s1=name; return r1; } int main () { int a=1 ; int b=1 ; std::string name="LYsnowQ" ; Returntype Re; Re=Example (a,b,name); return 0 ; }
在传参时直接将地址传入,&取地址符号相当于在函数内部直接修改参数值,所以不需要返回值即可直接对main参数进行修改,或者可以使用指针传入变量地址,再在内部解引用后进行赋值操作。
两者区别在于:取地址必须传入有效的参数,而指针可以传入空指针(nullptr)
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <iostream> #include <string> void Example (int & a,int & b,std::string& s) { a=a+10 ; b=a+15 ; s="LYsnowQ" ; } int main () { int a=1 ; int b=1 ; std::string name; Example (a,b,name); return 0 ; } void Example (int * a,int * b,std::string* s) { if (a!=0 ) *a=*a+10 ; if (b!=0 ) *b=*a+15 ; if (s!=0 ) *s="LYsnowQ" ; } int main () { int a=1 ; int b=1 ; std::string name; Example (&a,&b,&name); return 0 ; }
array和vector的区别在array是直接在栈上进行操作,返回时要快于vector,因为vector底层是在堆上进行操作。array在使用时还需要规定长度,所以在使用便携性能上array不如vector方便
而array和vector的共同缺陷是只能返回相同类型的变量,而多个类型混合时显得乏力
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> #include <string> #include <array> #include <vector> std::array<int ,2> Example (int a, int b) { a = a + 10 ; b = a + 15 ; std::array<int ,2> results; results[0 ] = a; results[1 ] = b; return results; } int main () { int a = 1 ; int b = 1 ; std::array<int ,2> Re = Example (a, b); return 0 ; } std::vector<int > Example (int a, int b) { a = a + 10 ; b = a + 15 ; std::vector<int > results; results[0 ] = a; results[1 ] = b; return results; } int main () { int a = 1 ; int b = 1 ; std::vector<int > Re = Example (a, b); return 0 ; }
tuple的本质是一个类。它可以包含x个变量,而pair一次只能支持两个量,但是pair可以嵌套多个量
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <iostream> #include <string> #include <tuple> std::tuple<int ,int ,std::string> Example (int & a, int & b, std::string& s) { a = a + 10 ; b = a + 15 ; s = "LYsnowQ" ; return std::make_tuple (a, b, s); } int main () { int a = 1 ; int b = 1 ; std::string name; std::tuple<int ,int ,std::string> T=Example (a, b, name); std::string name2 = std::get <2 >(T); return 0 ; } #include <iostream> #include <string> #include <tuple> std::pair<int , std::string> Example (int & a,std::string& s) { a = a + 10 ; s = "LYsnowQ" ; return std::make_pair (a,s); } int main () { int a = 1 ; int b = 1 ; std::string name; std::pair<int ,std::string> P = Example (a,name); a=P.first; name=P.second; std::tie (a,name)=Example (a,name); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> #include <string> #include <tuple> std::tuple<std::string,int > CreatePersion () { return {"LYsnowQ" ,24 }; } int main () { auto person = CreatPerson; std::string& name = std::get <0 >(person); int age = std::get <0 >(person); auto [name, age] = CreatPerson (); }
综上来说,在返回多个值时,最直观的使用结构体去返回,可以提高代码的可读性,然而在性能上使用取地址符更好的节约性能开支,在pair和tuple中代码的可读性不高且较为复杂,在vector和array中存在着无法返回多个不同变量的限制。在使用结构化绑定时也会显得简洁好懂。
资料来源
youtube上the cherno的c++系列