C++学习(c++17)——1.1 C++基础知识

C++学习(c++17)——1.1 C++基础知识

​ 假期花了2个月,连滚带爬地白嫖完C++的一个教学视频(总时长144h),然后开始尝试去运用知识做一些小项目。但实验室的大佬吴学长的魔鬼提问把我又打回原形,然后这次准备拿着资料去踏踏实实学习(把Cpppp放在学校宿舍真是一个错误的决定。) 这次的学习主要围绕的是c++17的一些特性,并且巩(完)固(善)假期里面看视频学习的c++。【学校有小程序大赛,又有老师组织的论文学习的作业,啊啊啊,我想学会分身术】

注意注意:此系列笔记内容适用对象为和我一样白嫖了网课,基础却不扎实或者想要学习c++17标准的人。


命名空间

C++17允许方便地使用嵌套的命名空间。

c++17前:

namespace MyLibraries{
    namespace NetWorking{
        namespace FTP{
            /*...*/
        }
    }
}

C++17:

namespace MyLibraries::NetWorking::FTP{
    /*...*/
}

//同时可使用名称空间别名:
namespace MyFTP = MyLibraries::NetWorking::FTP;

字面量

数值字面量中可以使用数字分隔符(一个单引号),例如

  • 23'456'789
  • 0.123'456f

C++17中增加了对十六进制浮点字面量的支持,如0x3.ABCp-10、0Xb.cp123(p-10指*2的-10次方)

数据类型

C++17中增加了std::byte来表示单个字节(在c++17之前,用字符或无符号字符来表示一个字节,但那些类型感觉像在处理字符。std::byte则指明意图——内存中的单个字节)

std::byte b{42};

注意

  1. 需要头文件。
  2. std::byte的初始化需要使用单元素列表进行直接列表初始化。

枚举类型

建议用类型安全的enum class强类型枚举来替代类型不安全的enum枚举。

条件语句

if语句

C++17中允许在if语句中包括一个初始化器,语法如下:if (;<conditional_expression>) {}。中引入的变量只在<conditional_expression>和中可用。

switch语句

当一个case表达式后的语句执行完后,如果没有遇到"break",则会继续执行下一个case后的语句,这被称为"fallthrough"。(因为它经常成为bug来源,所以编译器会生成警告信息)

C++17中,可用使用[[fallthrough]]特性,来告诉编译器这是特意为之。

C++17中,switch和if一样支持使用初始化器:switch(;) {}

函数

函数返回类型的推断(auto)

C++14允许要求编译器自动推断出函数的返回类型。要使用这个功能,需要把auto指定为返回类型:

auto addNumber(int number1,int number2){
    return number1 + number2;
}

编译器根据 return后的表达式 推断返回类型。函数中可以有多个return,但是应该解析为同种返回类型。也可以包含递归调用,但是第一个return语句必须是非递归调用(有递归出口)。

当前函数的名称(func)

​ 每个函数都有一个预定义的局部变量______func______,其中包含当前函数的名称。这个变量的一个用途是用于日志记录。

数组

C风格的数组【建议改用array和vector】

要获取基于栈的c风格数组的大小(元素个数),可以使用C++17 std::size()函数(需要头文件)。例如

int myArray[3];
unsigned int arraySize = std::size(myArray);

C++17之前获取元素个数:

unsigned int arraySize = sizeof(myArray) / sizeof(myArray[0])//sizeof操作符返回实参的大小(单位为字节)
std::array

std::array是一种大小固定的特殊容器。基本上是对c风格数组进行简单包装。

好处:

  1. 总是知道自身大小。
  2. 不会自动转换为指针,从而避免了某些bug。
  3. 具有迭代器,可以方便地遍历元素。
array<int, 3> arr = {1,2,3}
cout << "Array size:" << arr.size()<<";";
cout << "2nd element:" << arr[1];

上述代码的输出结果为Array size:3;2nd element:2。

std::vector

标准库提供的多个不同的非固定大小容器之一。vector是动态的,可以在运行时添加或者删除元素。

//Create a vector of integers
vector<int> myVector = { 11, 22};

//Add some more integers to the vector using push_back()
myVector.push_back(33);
myVector.push_back(44);

//Access elements
cout << "1st element: "<< myVector[0] << endl;

结构化绑定(structured bindings)

结构化绑定允许使用数组、结构、pair或元组中的元素来初始化多个变量。

例如,假设有下面的数组:

std::array<int, 3> values = {11, 22, 33};

那么可以同时声明三个变量,用这个数组来进行初始化【注意,结构化绑定必须要使用auto关键字】

auto [x, y, z] = values;

绑定的变量个数必须和右侧表达式中值个数一样。

且当所以非静态成员都是公有的情况下,才能将结构化绑定用于结构(struct)。

基于区间的for循环(Range-Based for Loop)

这是除了原本的while、do-while(至少执行一次的循环)、for循环外的第四种。这种循环允许方便地迭代容器中的元素。可用于C风格的数组、初始化列表,也可以用于具有返回迭代器的begin()和end()函数的类型,如std::array,std::vector等标准库容器。

std::array<int, 4> arr = {1, 2, 3, 4};
for(int i : arr){
	std::cout << i << std::endl;
}

(若想迭代元素时不制作副本,则应使用引用变量)

初始化列表

在头文件<initializer_list>头文件中定义。利用初始化列表,可以用于可变数量参数的函数。

#include <initializer_list>

using namespace std;

int makeSum(initializer_list<int> 1st){
    int total = 0;
    for(int value : 1st){
        total += value;
    }
    return total;
}

初始化列表是类型安全的。

posted @ 2020-04-06 19:53  LeoRanbom  阅读(587)  评论(0编辑  收藏  举报