C++ Primer(三)---- 函数

1、编译器能以任意可行的顺序对实参求值。(https://www.cnblogs.com/easonliu/p/4224120.html)

2、局部变量:形参和函数体内部定义的变量。

3、如果局部静态变量没有显式的初始值,它将执行值初始化。内置类型的局部静态变量初始化为0。

4、如果一个函数永远也不会被我们用到,那么它可以只有声明没有定义。函数声明也称作函数原型。

5、函数参数传递:传引用调用、传值调用。

6、当形参为const,且为顶层const时:

  • 和其他初始化过程一样,当用实参初始化形参时会忽略掉顶层const。当形参由顶层const时,传给它常量or非常量对象都是可以的。
  • 以下重载不可行:
    void fcn(const int i) {..}
    void fcn(int i) {..}

    由于顶层的const被忽略,所以传入两个fcn函数的参数可以完全一样。

7、数组形参:

  • void print(const int*);
    void print(const int[]);
    void print(const int[10]);//实际上不一定由10个元素

    以上三个函数等价,每一个函数的唯一形参都是const int*类型。

    int i = 0, j[2] = {0, 1};
    print(&i);//正确, &i类型为int*
    print(j);//正确, j转换成int*且指向j[0]
  • C++允许将变量定义为数组的引用,形参也可以是数组的引用。
    void print(int (&arr) [10])
    {
        ...
    }

    这样子的写法固定了数组的维度。

    int i = 0, j[2] = {0, 1};
    int k[10];
    print(&i);//错误,不是10个元素的数组
    print(j);//同上
    print(k);//正确 

8、argv的第一个元素指向程序的名字或一个空字符串。

9、含有可变形参的函数:使用initializer_list<T>

  • C++11新特性,如果函数的实参数量未知但全部实参类型都相同,则可以使用initializer_list。定义在同名的头文件中。
  • initializer_list的对象永远都是常量值。赋值或拷贝一个initializer_list对象不会拷贝列表中的元素;拷贝后原始列表和副本共享元素。
  • 使用迭代器访问。
  • 想向initializer_list形参传递一个值的序列,则必须把序列放在一对花括号内。
    if(expected != actual)
        error_msg({"xxx", "xxx"});

10、C的省略符形参。

11、不要返回局部对象的引用或指针。

const string& manip()
{
    string ret;
    if(!ret.empty())
        return ret;
    else
        return "Empty";
}

  上述两条return语句都是错误的。第二个中,字符串字面值转换为了一个局部临时string对象。

  new的空间在堆区。

12、列表初始化返回值。C++11。

13、引用返回左值,其他返回类型得到右值。可以像使用其他左值那样来使用返回引用的函数调用。可以为返回类型是非常量引用的函数结果赋值。

14、返回数组指针

  •  返回数组指针的函数:int (*func(int i))[10];
  • 尾置返回类型:
    auto func(int i) -> int(*)[10];
  • 使用decltype
    int odd[] = {1,3,5,7,9};
    int even[] = {0,2,4,6,8};
    decltype(odd) *arrPtr(int i)
    {
        return (i % 2)? &odd: &even;
    }

    注意decltype的结果是一个数组。

15、函数重载

  • 顶层const不影响传入函数的对象。一个拥有顶层const的形参无法与另一个没有顶层const的形参区分开来:
    Record lookup(Phone);
    Record lookup(const Phone);//error
    
    Record lookup(Phone*);
    Record lookup(Phone* const);//error
  • 如果形参是某种类型的指针或引用,那么可以通过区分其指向的是常量对象或非常量对象实现重载。
    Record lookup(Account&);
    Record lookup(const Account&);
    
    Record lookup(Account*);
    Record lookup(const Account*);

    const对象只能传递给const形参。因为非常量可以转换成const,上面4个都可以。但编译器优先选择非常量版本的函数。

  • class A{
    public:
        A(A a){}//error
    };

     

转载于:https://www.cnblogs.com/hlk09/p/9651009.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值