5、函数

1、局部静态变量,只初始化一次,程序终止才销毁

static int a = 1;

2、如果形参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝给形参。C++建议使用引用类型的形参代替指针。如果函数无需改变引用形参的值,最好将其声明为常量引用。

//即(int &)i,引用对象i 
void reset(int &i)
{
    i = 0;
}

int j;
reset(j);//则j = 0

//比较两个字符串长度,采取引用
//调用的时候会定义(const string &)s1 = 实参字符串
bool isShorter(const string &s1, const string &s2)//引用两个常类型字符串
{
    return s1.size() < s2.size();
}

3、不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。

int i =42;
const int &r = i; //初始化绑定,但是不能修改i的值
                    //非const可以传递给const,只是不能修改

int &r3 = r;    //  错误!!非const不能绑定const类型

4、数组以指针的形式传递给函数,一开始不知道切确的尺寸,调用者应该提供一些额外的信息。
数组的大小类型为size_t;

void print(const int *beg, const int *end)
{
    while(beg != end)
        cout << *beg++ << endl;
}

int a[4] = {0, 1, 2, 3};
print(begin(a), end(a));
//(&a)这是一个引用,该引用指向10int的数组
void f(int (&a)[10])
{
}

5、main

//第一个参数argc存命令行传入的字符串数量;二维数组(字符串数组)存每个字符串(命令行传入的具体字符串),一般argv[0]为程序名字,不需要用户传入。
int main(int argc, char *argv[])
{
    ....
}

6、含有可变形参的函数
initializer_list类型类似于vector,initializer_list是一种库类型,参数数量可变,类型必须相同,对象中的元素永远是常量值。

void error_msg(initializer_list<string> il)
{
    for(auto beg = il.begin(); beg != il.end(); ++beg)
        cout << *beg << "";
    cout << endl;
}

string expected = "1234";
string actual = "abcdefg";
if(expected != actual)
    error_msg({"functionX", expected, actual});
else
    error_msg({"functionX", "okay"});

6、函数返回
不要返回局部对象的引用和指针

//返回类型为引用(const string &)
const string &mapip()
{
    string ret;
    if(!ret.empty())
        return ret; //错!!,调用时相等于绑定const string &x =ret,那么就是返回局部变量的引用
    else
        return "Empty";//错!!返回了局部临时变量,函数调用完会回收
}

尾式返回

//func函数返回一个指针,该指针指向10整数的数组
// -> int(*)[10]表示返回类型
auto func(int i) -> int(*)[10];

7、函数重载:几个函数名字相同,参数列表不同。
(1)单独返回类型不同不行
(2)顶层const(const执行对象非其指针)不行,底层const可以,即const指针和引用是可以区分的
(3)C++中名字查找发生在类型检测之前

8、默认实参:用户调用时不指定值,则使用默认值

typedef string::size_type sz;
string screen(sz ht = 24; sz wid = 80; char backgrnd = ' ');

9、内连函数:在函数前面加上inline,避免函数调用开销

10、constexpr函数:用于常量表达式,规定:返回值及所有形参类型都必须是字面量。编译器会把constexpr函数隐式转化为内连函数。

constexpr int new_sz() 
{
    return 42;
}

11、调试,预处理宏assert(),定义NDEBUG则关闭该功能,头文件cassert, 预处理命令不需要使用using声明

assert(表达式),如果表达式为假(0),则输出信息并,停止程序
__func__//函数名
__FILE__//文件名
__LINE__//行号
__TIME__//编译时间
__DATA__//编译日期

12、函数指针

int func(const string &a)
{
    ......
}
int (*f)(const string &);

//下面2句等价
f = func;
f = &func;

//下面调用函数等价

f("hello");
(*f)("hello");
func("hello");
//下面2句等价
//*f1(int),f1返回一个指针;int (*xx)(int *, int);该指针指向函数
int (*f1(int))(int *, int);
auto f1(int) -> int (*)(int *, int);

13、为解决不同源文件中同名函数或变量的问题(引用其他文件变量要加extern,引用函数不需要),C++引入命名空间。命名空间给一组全局程序实体的定义取一个名字,使之构成一个作用域。

  • file.h
namespace A
{
    extern int x;
    void f();
    void g();
}
  • file.cpp
namespace A
{
    int x = 1;
    void f()
    {
        .......
    }
    void g()
    {
        .......
    }
}
  • main.cpp
#include "file.h"
void main()
{
    A::f();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值