c++primer笔记----函数

  • 自动对象的声明周期:对于普通局部对象, 当函数的控制路径经过变量定义语句时创建该对象。当达到定义所在块末尾时销毁它。内置类型不会默认初始化,即产生未定义的值

  • 局部静态对象:static a = 0;当函数的控制路径经过变量定义语句时创建该对象。程序终止才进行销毁。内置类型会自动初始化为0

  • 函数声明:含有函数声明的头文件应该被包含到定义函数的源文件中

void print(int a, int b);
  • 当用实参初始化形参的时候,会忽略掉顶层“const
void f(const int i);
void f(int i);   //error:重复定义
  • 数组形参:传递的是指向数组首元素的指针
void print(const int*)
void print(const int[])
void print(const int[10])
  • 传递数组长度
void print(const int *beg, const int *end)
void print(const int *beg, size_t size)
void print(int (&arr)[10])  //传递引用,这个10限制了数组长度是10
  • 传递多维数组
void print(int (*matrix)[10], int rowSize)  //数组对象是int[10]
void print(int matrix[][10], int rowSize)   //等价的
  • main:命令行选项
#include <iostream>
using namespace std;

int main(int argc, char *argv[]){
    for(int i=1; i<=argc; i++){  
    //argc是字符串的个数, argv是字符串数组,
    //argv[0]保存数组的名字,而非用户输入
        cout << argv[i] << "  ";
    }
    cin.get();
}
//运行
// g++ a.cpp
// .\a.exe i d d
//输出:i d d
  • 传递不同数量实参initializer_list。定义在同名的头文件下
void error_msg(initializer_list<string> il)
{
    for(auto beg = il.begin(); beg != il.end(); ++beg)
        cout << *beg << " ";

    cout << endl;
}
  • 引用返回左值
char &get_val(string &str)
{
    return str[0];
}

get_val(s) = 'a';  //可以当左值
  • 列表初始化返回值
return {"dsdf", "dfdgfdf"};  //a={"dsdf", "dfdgfdf"}; a根据列表值进行初始化
  • 返回数组指针。感觉没有软用
typedef int arrT[10];  //arrT是一个类型别名:含有10个整数的数组
using arrT = int[10];   //等价
arrT* func(int i);  //函数返回一个指针,指针指向含有10个整数的数组

//定义返回数组指针的函数
int (*func(int i))[10];

//使用尾置返回类型
auto func(int i)->int(*)[10]

//使用decltype
int odd[] = {1,2,3,4,5};
decltype(odd) *arrPtr(int i)
{
    return &odd;
}
  • 函数重载:同一作用域,形参列表不同,函数名相同。main函数不能重载。返回值没影响
//重载和const形参:顶层ocnst有无都相同。底层const有无可以重载
void fact(int i);
void fact(const int i); //error:重复声明。  顶层const 就是 i不能变

void fact(int*);
void fact(int* const);   //error:重复声明

void fact(int&);
void fact(const int&);

void fatc(int*);
void fact(const int*);  //不过,传入非const对象时,优先选择非const参数的函数
  • const_cast:改变const属性
const_cast<const string&>(s1);
const_cast<string&>(s1);
  • 重载和作用域:名字查找发生在类型检测之前
void print(const string&);
void print(double);
{
void print(int);
void print("hahaha");  //error:void print(int)屏蔽掉了之前的2个
}
  • 内联函数:在函数前面加上inline

  • constexpr:是指能用于常量表达式的函数,遵守约定:函数返回类型及所有形参的类型都是字面值常量,而且函数体有且只有一条return语句

  • 调试帮助:assert(expr),在头文件<cassert>中。assert(word.size()>threshold);如果是假,则输出信息并终止程序执行。assert是预处理宏,由预处理器处理

  • NDEBUG预处理变量:如果定义了它,则assert将不执行运行时检查。

#ifndef NDEBUG
    //执行检查
#endif
  • 编译器定义的局部静态变量
// __func__ :局部静态变量
cout << __func__ ;
//__FILE__:存放文件名的字符串字面值
//__LINE__:存放当前行的整型字面值
//__TIME__:存放文件编译时间的字符串字面值
//__DATE__:存放文件编译日期的字符串字面值
  • 函数匹配

    1. 确定候选函数:函数同名;声明在调用点可见
    2. 可行函数:形参,实参数量相等;实参,形参类型相同,或能转换为形参的类型
    3. 寻找最佳匹配:实参,形参类型越接近,匹配的越好。最佳匹配应满足,每个实参的匹配不劣于其他可行函数;至少一个匹配优于其他可行函数
  • 函数指针:

bool fun(int a, int b);
//函数指针
bool (*pf)(int a, int b); //未初始化
pf = fun;  // 函数名作为右值时,自动转换未指针
pf = &fun;  //pf(a,b) or *pf(a, b) //函数指针之间不存在转换规则

//函数指针形参
//返回指向函数的指针    类型别名有用到 auto decltype using typedef

猜你喜欢

转载自blog.csdn.net/qq_28038207/article/details/81029322