嵌入式学习-C嘎嘎-Day08
[1. nullptr](#1. nullptr)
[2. 类型推导](#2. 类型推导)
[3. 初始化列表](#3. 初始化列表)
[4. 格式化输出](#4. 格式化输出)
[4.1 进制](#4.1 进制)
[4.2 域](#4.2 域)
[5. 文件流](#5. 文件流)
1. nullptr
nullptr是C++11的新关键字,用于取代NULL。
#include <iostream>`
`using` `namespace std;`
`void` `func(int)`
`{`
` cout <<` `"A"` `<< endl;`
`}`
`void` `func(char*)`
`{`
` cout <<` `"B"` `<< endl;`
`}`
`int` `main()`
`{`
`func(NULL);` `// A`
`}`
`
上面的代码中调用第二个函数比较合理,但是实际运行调用的是第一个函数,因为NULL就是0。
#include <iostream>`
`using` `namespace std;`
`void` `func(int)`
`{`
` cout <<` `"A"` `<< endl;`
`}`
`void` `func(char*)`
`{`
` cout <<` `"B"` `<< endl;`
`}`
`int` `main()`
`{`
`func(NULL);` `// A`
`func(nullptr);` `// B`
`}
使用nullptr可以区分0和空。
2 . 类型 推导
在C++11中,可以使用auto和decltype关键字进行类型推导。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`auto a =` `1;` `// auto被自动推导为int`
`auto b =` `new` `auto(2);` `// auto被自动推导为int*`
` cout << a << endl;` `// 1`
` cout <<` `*b << endl;` `// 2`
`delete b;`
`}
使用decltype推导表达式类型时,编译器只会计算类型而不计算数值。
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
`// decltype可以对表达式进行类型推导`
`auto x =` `1;`
`auto y =` `2;`
`decltype(x+y) z =` `123;`
` cout << z << endl;`
`}`
`
3 . 初始化 列表
C++11中引入了初始化列表语法(列表初始化、通用统一初始化、一致性初始化),使用{}进行初始化。
#include <iostream>`
`using` `namespace std;`
`class` `Student`
`{`
`private:`
`int id;`
` string name;`
`public:`
`Student(int id,string name):id{id},name{name}{}`
`void` `print()`
`{`
` cout << id <<` `" "` `<< name << endl;`
`}`
`};`
`int` `main()`
`{`
`int a{1};`
` cout << a << endl;`
`int b{};`
` cout << b << endl;` `// 0`
`int arr[]` `=` `{1,2,4};` `// 推导数组长度为3`
`for(int i=0;i<3;i++)`
` cout << arr[i]` `<<` `" ";`
` cout << endl;`
` Student s =` `{1,"张三"};`
` s.print();`
`}
【思考】一共学习了哪些C++11新特性?
- for-each
- array
- nullptr
- 类型推导
- 初始化列表、窄化
- 智能指针
- 继承构造
- override关键字
- 类型转换
- constexpr
4 . 格式化 输出
4 . 1 进制
使用cout输出时,可以切换进制:
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
` cout << dec;` `// 切换到十进制输出(默认)`
` cout <<` `1234` `<< endl;`
` cout << oct;` `// 切换到八进制`
` cout <<` `8` `<< endl;` `// 10`
` cout << hex;` `//切换到十六进制`
` cout <<` `255` `<< endl;` `// ff`
`}
为了区分不同的进制显示,可以增加显示进制的功能:
#include <iostream>`
`using` `namespace std;`
`int` `main()`
`{`
` cout << showbase;` `// 进制显示`
` cout << dec <<` `1234` `<< endl;` `// 十进制就是正常显示`
` cout << oct <<` `3434` `<< endl;` `// 八进制前面补0`
` cout << hex <<` `2344` `<< endl;` `// 十六进制前面补0x`
` cout << noshowbase;` `// 关闭进制显示`
` cout << dec <<` `1234` `<< endl;`
` cout << oct <<` `3434` `<< endl;`
` cout << hex <<` `2344` `<< endl;`
`}
4 . 2 域
可以使用setw函数指定输出内容占用的宽度:
- 如果设定域的宽度大于数据本身的宽度,显示为设定域的宽度;
- 如果设定域的宽度小于数据本身的宽度,显示为数据本身的宽度。
每次都需要在输出前使用setw函数,使用前需要引入头文件 #include <iomanip>
#include <iostream>`
`#include <iomanip> // 头文件`
`using` `namespace std;`
`int` `main()`
`{`
` cout <<` `setw(10)` `<<` `"12c";`
` cout <<` `setw(6)` `<<` `"12c8787878";`
` cout <<` `setw(6)` `<<` `"12c";`
`}
5 . 文件 流
使用C++实现一个文件拷贝的程序:
#include <iostream>`
`#include <fstream> // 头文件`
`using` `namespace std;`
`int` `main()`
`{`
` ifstream ifs("E:\\bbq.mp4",ios_base::binary);` `// 文件输入流对象`
`if(!ifs)`
`{`
` cout <<` `"读取失败!"` `<< endl;`
`return` `0;`
`}`
` ofstream ofs("C:\\Users\\jngwu\\Desktop\\bbq(2).mp4",`
` ios_base::binary);` `// 文件输出流对象`
`if(!ofs)`
`{`
` cout <<` `"无法保存!"` `<< endl;`
`return` `0;`
`}`
`// 使用数组作为缓存`
`char buffer[1024];`
`long` `long size =` `0;` `// 文件大小`
`long` `long has_copied =` `0;` `// 已经读写的大小`
`// 文件指针从头部移动到尾部`
` ifs.seekg(0,ios::end);`
` streampos ps = ifs.tellg();` `// 获取文件的移动量`
` cout <<` `"移动量:"` `<< ps << endl;`
` size = ps;`
`// 文件指针移动回头部`
` ifs.seekg(0,ios::beg);`
`// 循环读写`
`while(ifs)`
`{`
`// 读取数据`
` ifs.read(buffer,1024);`
`//gcount返回39行读取的数据量`
`int copy_size = ifs.gcount();`
` has_copied += copy_size;` `// 累积读写的数据量`
`// 输出数据`
` ofs.write(buffer,copy_size);`
`// 百分比显示`
` cout <<` `100*has_copied/size << endl;`
`}`
`// 收尾`
` ifs.close();`
` ofs.flush();`
` ifs.close();`
`}