C++04缺省参数、哑元、内联函数、动态内存分配

前言:更多内容请看总纲《嵌入式C/C++学习路》

1. 缺省参数

  • 可以为函数的参数指定缺省值,调用该函数时若未指定实参,则与该实参相对应的形参取缺省值
  • 函数参数的缺省值只能在函数声明中指定(编译器只看声明,不看定义)
  • 如果函数的某一个参数具有缺省值,那么该参数后面的所有参数必须都具有缺省值
  • 不要因为使用缺省参数而导致重载歧义
#include 
using namespace std;
void foo(int a, char b, float c = 4.56f, const char *d = "Hello C++ !")
{
    cout << a << ' ' << b << ' ' << c << ' ' << d << endl;
}
void bar(int x = 666); // 在声明中定义缺省参数

int main(void)
{
    foo(10, 'A', 1.23f, "Hello world!");
    foo(10, 'A', 1.23f); // 缺省
    foo(10, 'A');        // 缺省
    bar();  // 缺省
    return 0;
}

void bar(int x)
{ // 这是函数定义,声明在main上面,在声明里定义缺省参数
    cout << x << endl;
}

在这里插入图片描述

2. 哑元

  • 只指定类型而不指定名称的函数参数,我们称为哑元
  • ——保证函数的向下兼容
  • ——形成函数的重载版本
#include
using namespace std;
void foo(int){   // 哑元参数
    cout << "foo(int)" << endl;
}

int main(void){
    foo(10);
    return 0;
}

在这里插入图片描述

3. 内联

  • 内联就是用函数已被编译好的二进制代码,替换对该函数的调用指令
  • 内联在保证函数特性的同时,避免了函数调用开销
  • 注意内联与有参宏(宏函数)的区别
  • 内联会使可执行文件的体积和进程代码的内存变大,因此只有频繁调用的简单函数才适合内联
  • 若函数在类声明中直接定义,则自动被优化为内联,否则可在其声明处加上inline关键字
  • inline关键字仅表示期望该函数被优化为内联,但是否适合内力那则完全由编译器决定
  • 稀少被调用的复杂函数和递归函数都不适合内联

C++04缺省参数、哑元、内联函数、动态内存分配_第1张图片

4. 动态内存分配

  • 继续使用标准C库函数malloc/calloc/realloc/free
  • 使用new/delete操作符在堆中分配/释放内存

int pi = new int;
delete pi;

  • 在分配内存的同时初始化

int *pi = new int (100);

  • 以数组方式new的也要以数组方式delete

int *pi = new int[ 4 ]{1,2};
delete[] pi;

#include 

using namespace std;
int main()
{
    int *p1 = new int;
    *p1 = 1234;
    cout << *p1 << endl;
    delete p1;
    p1 = new int(1000); // 带初值
    cout << *p1 << endl;
    delete p1;
    p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0
    cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl;
    delete[] p1;  // 记得加中括号
    return 0;
}

在这里插入图片描述
C++04缺省参数、哑元、内联函数、动态内存分配_第2张图片

  • 通过new操作符分配N维数组,返回N-1维数组指针

int (*prow)[4] = new int [3][4]; // 二维数组的首地址是一维数组
int (*ppage)[4][5] = new int [3][4][5]; // 三维数组的首地址是二维

  • 不能通过delete操作符释放已释放过的内存
  • delete野指针后果未定义,delete空指针安全,即 p = NULL;
  • 内存分配失败,new操作符抛出bad_alloc异常
  • 定位分配:

new(指针)类型(初值);
在一个已分配的内存空间中创建对象

#include 

using namespace std;
int main()
{
    int *p1 = new int;
    *p1 = 1234;
    cout << *p1 << endl;
    delete p1;
    p1 = new int(1000); // 带初值
    cout << *p1 << endl;
    delete p1;
    p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0
    cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl;
    delete[] p1;
    int (*p2)[4] = new int[3][4]{{1, 2, 3, 4},
                                {5, 6, 7, 8},
                                {9, 10, 11, 12}};
    for (size_t i = 0; i < 3; i++)
    {
        for (size_t j = 0; j < 4; j++)
        {
            cout << p2[i][j] << ' ';
        }
        cout << endl;
    }
    delete[] p2;

    return 0;
}

C++04缺省参数、哑元、内联函数、动态内存分配_第3张图片

#include 

using namespace std;
int main()
{
    int *p1 = new int;
    *p1 = 1234;
    cout << *p1 << endl;
    delete p1;
    p1 = new int(1000); // 带初值
    cout << *p1 << endl;
    delete p1;
    p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0
    cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl;
    delete[] p1;
    int(*p2)[4] = new int[3][4]{{1, 2, 3, 4},
                                {5, 6, 7, 8},
                                {9, 10, 11, 12}};
    for (size_t i = 0; i < 3; i++)
    {
        for (size_t j = 0; j < 4; j++)
        {
            cout << p2[i][j] << ' ';
        }
        cout << endl;
    }
    delete[] p2;

    short buf[4];  // 在栈里面不需要释放内存
    p1 = new(buf) int(0x12345678);
    cout << showbase << hex << *p1 << endl; // showbase打印前缀   hex是16进制
    cout << buf[0] << ' ' << buf[1] << endl;  // 内存地址重叠

    return 0;
}

C++04缺省参数、哑元、内联函数、动态内存分配_第4张图片

你可能感兴趣的:(嵌入式C/C++,c++)