C++补充部分

时间:2024-10-16 18:37:37

NULL在源码中就是个0,因此可能会存在一些二义性问题。

#include <iostream>
using namespace std;


void func(int a)
{
    cout << "a=" << a << endl;
}

void func(int *b)
{
    cout << "b=" << b << endl;
}

int main()
{
    func(NULL);

    return 0;
}
在C++11中使用nullptr代替NULL,作为空指针的表示方式。
#include <iostream>
using namespace std;


void func(int a)
{
    cout << "a=" << a << endl;
}

void func(int *b)
{
    cout << "b=" << b << endl;
}

int main()
{
    func(nullptr);  // b=0

    return 0;
}

2、类型推导(熟悉)

使用auto关键字可以推导类型。C++11引入的。

#include <iostream>
using namespace std;



int main()
{
    auto i = 10;    // i的类型被推导为(int)
    cout << i<< endl;

    auto i2 = 192.3;    // i2的类型被推导为浮点型
    cout << i2 << endl;

    auto i3 = new auto(10); // i3的类型被推导为int *
    cout << *i3 << endl;

    auto i4 = "hello";
    cout << i4 << endl;

    auto i5 = 'a';
    cout << i5 << endl;

    delete i3;


    return 0;
}
decltype可以推导表达式的类型,需要注意的是,decltype只会分析表达式的类型,不会具体计算表达式的值。
#include <iostream>
using namespace std;

int main()
{
    auto a = 1;
    auto y = 2;

    decltype(a*y+232) z = 888.32;   // int * int + int = int
    cout << z << endl;

    return 0;
}

3、初始化列表(掌握)

C++11中引入了列表初始化(初始化列表、通用统一初始化、一致性初始化)语法,可以使用{}对对象进行初始化。

#include <iostream>
#include <array>
#include <vector>
using namespace std;

class Student
{
private:
    string name;
    int age;

public:
    Student(string name,int age):name(name),age(age){}

    void show()
    {
        cout << name << " " << age << endl;
    }
};

int main()
{
    array<int,5> arr1 = {1,2,3,4,5}; // 1 2 3 4 5
    for(auto i:arr1)
    {
        cout << i << " ";
    }
    cout << endl;

    array<int,5> arr2 = {1,2,3};    // 1 2 3 0 0
    for(auto i:arr2)
    {
        cout << i << " ";
    }
    cout << endl;

    vector<int>vec1 = {1,2,2};
    for(auto i:vec1)
    {
       cout << i << " ";    // 1 2 2
    }
    cout << endl;

    int arr3[3] = {1,3,5};
    for(auto i:arr3)
    {
       cout << i << " ";    // 1 3 5
    }
    cout << endl;

    Student s = {"张三",99};
    s.show();   // 张三 99

    return 0;
}

4.进制输出(了解)

C++11可以对整数进行不同进制的输出。

#include <iostream>

using namespace std;

int main()
{
    // 为了区分不同进制,可以增加进制显式功能,此功能设定持久
    cout << showbase;
    // 默认为十进制
    cout << dec << 1234 << endl; // 1234

    cout << oct << 1234 << endl; // 2322

    // 输出进制的设定是持久的
    cout << 9 << endl;  // 11
    cout << hex << 256 << endl; // 100

    // 取消进制显式功能
    cout << noshowbase;
    cout << 16 << endl; // 10
    return 0;
}

5、设定输出域宽度(了解)

可以使用setw()来制定一个整数或者一个字符串输出占用的域宽度。

● 当设定的域宽度小于数据本身时,仍然会显式为数据本身的宽度。

● 当设定的域宽度大于数据本身时,会显示为设定的宽度。

需要注意,输出域宽度不是持久的,需要每次输出设定。

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    // 仍然会按照实际的宽度输出
    cout << setw(5) << 123456 << setw(5) << 123456 << endl;

    // 使用域宽度
    cout << setw(10) << 123456 << setw(10) << 123456 << endl;

    cout << setw(10);
    cout << 123456 << endl;

    cout << 123456 << endl; // 域宽度无效, 因为输出域宽度只能作用于下一行

    cout << setw(10);
    cout << 123456 << endl;

    return 0;
}

6.文件IO

#include <iostream>
#include <fstream>
using namespace std;



int main()
{
    // 文件输入流对象,用于读取数据
    // 参数1:读取的路径
    // 参数2:读取的方式 二进制
    ifstream ifs("D:\\meeting_01.mp4",ios_base::binary);
    if(!ifs)
    {
        cout << "文件或路径不存在" << endl;
        return 0;
    }

    // 文件输出流对象,用于输出数据
    // 参数1:写出的路径
    // 参数2:写出的方式,二进制
    ofstream ofs("C:\\Users\\Administrator\\Desktop\\meeting_01.mp4",ios_base::binary);
    if(!ofs)
    {
        cout << "输出路径不存在" << endl;
        return 0;
    }

    // 把文件指针移动到输入流尾部
    // 参数1:相对偏移量
    // 参数2:移动的位置
    ifs.seekg(0,ios::end);
    cout << "文件总大小:" << ifs.tellg() << "bytes" << endl;

    // 把文件流指针移动回头部
    ifs.seekg(0,ios::beg);

    // 准备一个buffer
    char buf[2048];
    long long hasRead = 0;  // 已经读取的文件大小

    while(ifs)
    {
        // 读取固定的长度到buf中
        ifs.read(buf,2048);

        // 输出指定长度的数据到目标位置
        // 参数1:数据来源
        // 参数2:输出的数据量gcount为上一次文件指针偏移量
        ofs.write(buf,ifs.gcount());

        hasRead += ifs.gcount();
        cout << "已经拷贝的字节数:" << hasRead << endl;
    }

    // 收尾
    ifs.close();
    ofs.flush();    // 清空缓存区
    ofs.close();

    cout << "文件拷贝完成!!!!" << endl;
    return 0;
}