定义多个变量

通过逗号分隔名称,能在单个语句中定义相同类型的多个变量。以下两段效果相同:


int a;
int b;

等同于:


int a,b;

常见错误:

int a, double b;//错误
int a; double b;//正确
int a;
int b;          //正确

初始化

int a;         // 默认初始化
int b = 5;     // 拷贝初始化
int c( 6 );    // 直接初始化

// 列表初始化 (C++11引进)
int d { 7 };   // 直接列表初始化
int e = { 8 }; // 拷贝列表初始化
int f {};      // 值列表初始化

int c( 6 );    // 直接初始化,直接将6设置到变量c当中,直接初始化很难区分变量和函数定义
int c();        //声明一个函数c

列表初始化

int width { 5 };    // 直接列表初始化,将变量width设置为 5
int height = { 6 }; // 拷贝列表初始化,将变量height设置为6
int depth {};       // 值初始化

列表初始化还有一个好处:不允许“缩小转换范围”。意味着,如果尝试使用变量不能安全保存的值,编译器将产生错误。

int width { 4.5 }; // error: int类型无法装下分数

拷贝和直接初始化只会删除小数部分,而将值4初始化到变量width(编译器会发出警告,因为很少需要丢失数据)。

当用空大括号对变量列表初始化时,进行值初始化。大多数情况,值初始化将变量初始化为零(或空,如果这更适合给定类型)。发生归零的这种情况,称为零初始化。

int width {}; // 值初始化 / 零初始化,将变量width设为 0

/*如果实际使用初始化的值,则显式设置初始化值。*/
int x { 0 };    // 显示将变量x设为 0
std::cout << x; // 使用设置的值

/*如果值在使用前被替换,请使用值初始化。*/
int x {};      // 值初始化 / 零初始化
std::cin >> x; // x直接被其它语句赋值

函数与二维数组

数组指针与指针数组

int *arr[4];
int (*arr)[4];

int *arr[4]是一个数组,由四个指向int类型的指针组成

int (*arr)[4]是一个指针,指向一个长度为4的int类型的数组

递归

#include<iostream>

void countdown(int n);
int main()
{
    countdown(4);
    return 0;
}

void countdown(int n)
{
    std::cout<<"counting down..."<<n<<std::endl;
    if(n>0)
    {
        countdown(n-1);
    }
    std::cout<<n<<"caboom!"<<std::endl;
}

递归流程如下:

sequenceDiagram participant main participant C4 as "countdown(4) [&n: 0x7ffeefbff5ac]" participant C3 as "countdown(3) [&n: 0x7ffeefbff584]" participant C2 as "countdown(2) [&n: 0x7ffeefbff55c]" participant C1 as "countdown(1) [&n: 0x7ffeefbff534]" participant C0 as "countdown(0) [&n: 0x7ffeefbff50c]" %% 调用阶段:main 启动递归链 main->>C4: countdown(4) activate C4 Note over C4: 🔽 counting down...4...0x7ffeefbff5ac C4->>C3: countdown(3) activate C3 Note over C3: 🔽 counting down...3...0x7ffeefbff584 C3->>C2: countdown(2) activate C2 Note over C2: 🔽 counting down...2...0x7ffeefbff55c C2->>C1: countdown(1) activate C1 Note over C1: 🔽 counting down...1...0x7ffeefbff534 C1->>C0: countdown(0) activate C0 Note over C0: 🔽 counting down...0...0x7ffeefbff50c Note over C0: ⚠️ n>0? false → 直接返回 %% 返回阶段:从 base case 开始回溯 C0-->>C1: return deactivate C0 Note over C1: 🔼 0 caboom!...0x7ffeefbff534 C1-->>C2: return deactivate C1 Note over C2: 🔼 1 caboom!...0x7ffeefbff55c C2-->>C3: return deactivate C2 Note over C3: 🔼 2 caboom!...0x7ffeefbff584 C3-->>C4: return deactivate C3 Note over C4: 🔼 3 caboom!...0x7ffeefbff5ac C4-->>main: return deactivate C4 Note over main: ⏹️ 递归结束,返回 main

函数指针

1.函数的地址

若think()为一个函数,则think为该函数的地址。函数作为参数传递时,必须传递函数名。

process(think());//传递的是函数的返回值
thought(think);//传递的是函数的地址

2.声明函数指针

声明函数的指针必须指定指针所指向的函数类型,声明应该指定函数的返回值类型和特征值(参数列表)

double pam(int)//函数原型
double (*pf)(int)//函数指针