C++和标准库速成(六)——结构化绑定、循环、初始化列表、C++中的字符串

1. 结构化绑定

  结构化绑定允许声明多个变量,这些变量使用数组、结构体、pair或元组中的元素以初始化。例如,假设有下面的数组:
  std::array values { 11, 22, 33 };
  可声明3个变量x、y和z,像下面这样使用数组中的3个值进行初始化。注意:必须为结构化绑定使用auto关键字。例如,不能用int替代auto。
  auto [x, y, z] { values };
  使用结构化绑定声明的变量数量必须与右边表达式中的值数量匹配。
  如果所有非静态成员都是公有的,也可将结构化绑定用于结构体。例如:

struct Point {
	double m_x, m_y, m_z;
};
Point point;
point.m_x = 1.0;
point.m_y = 2.0;
point.m_z = 3.0;
auto [x, y, z] { point };

  正如最后一个例子,以下代码将pair中的元素分解为单个变量:

std::pair myPair { "hello", 5 };
auto [theString, theInt] { myPair }; // decompose using structured bindings.
std::cout << std::format("theString: {}\ttheInt: {}\n", theString, theInt);

2. 循环

2.1 while循环

  只要条件表达式的求值结果为true,while循环就会重复执行一个代码块。例如,下面的代码会输出“This is silly."五次。

int i { 0 };
while ( i < 5 ) {
	std::cout << "This is silly.\n";
	++i;
}

  在循环中使用break关键字立刻跳出循环并继续执行从程序。关键字continue可用来返回到循环顶部并对while表达式重新求值。然而,在循环中使用continue经常被认为是不良的编码风格,因为它们会使程序的执行产生无规则的跳转,应该慎用。

2.2 do/while循环

  C++还有一个版本的while循环,称为do/while循环。其运行方式类似于while循环,但会首先执行代码,而判断是否继续执行的条件检测被放在结尾处。如果想让代码块至少执行一次,并且根据某一条件确定是否多次执行,就可以使用这个循环版本。下面的代码尽管条件为false,但仍会输出"This is silly."一次。

int i { 100 };
do {
	std::cout << "This is silly.\n";
	++i;
} while ( i < 5 );

2.3 for循环

  for循环提供了另一种循环语法。任何for循环都可转换为while循环,反之亦然。然而,for循环的语法一般更简便,因为可看到循环的初始表达式、结束条件以及每次迭代结束后执行的语句。在下面的代码中,i被初始化为0;只要i小于5,循环就会继续执行;每次迭代结束时,i的值会增1。

for ( int i { 0 }; i < 5; ++i) {
	std::cout << "This is silly.\n";
}

2.4 基于范围的for循环

  基于范围的for循环是第四种循环,这种循环允许方便地迭代容器中的元素。这种循环类型可用于C风格数组、初始化列表,可用于任何具有返回迭代器的begin()和end()方法的类型,例如std::array、std::vector以及其他所有标准库容器。
  下面首先定义了一个包含4个整数的数组,此后基于范围的for循环遍历数组中的每个元素的副本,输出每个值。为在迭代元素时不制作副本,应使用引用变量。

std::array arr { 1, 2, 3, 4 };
for ( int i : arr ) {
	std::cout << i << "\n";
}

  从C++20开始,可以在基于范围的for循环中使用初始化器:

for ( <initializer>; <for-range-declaration> : <for-range-initializer>) { 
	<body> 
}

  任何在<initializer>中引入的变量只能被用于<for-range-initializer>和<body>中,不能被用于基于范围的for循环之外。示例如下:

for (std::array arr { 1, 2, 3, 4}; int i : arr ) {
	std::cout << i << "\n";
}

3. 初始化列表(C++11)

  初始化列表在<initializer_list>头文件中定义;利用初始化列表,可轻松地编写能接收可变数量参数的函数。std::initializer_list是一个模板,要求在尖括号之间指定列表中的元素类型,这类似于指定vector中存储的对象类型。示例如下:

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

  makeSum()函数总是接收一个整数类型的初始化列表作为参数。可按如下方式使用该函数:

int a { makeSum({ 1, 2, 3 }) };
int b { makeSum({ 10, 20, 30, 40, 50, 60 }) };

  初始化列表是类型安全的,列表中的所有元素必须为同一类型。对于此处的makeSum()函数,初始化列表中的所有元素都必须是整数。尝试使用double数值进行调用,将导致编译器生成错误或警告。

4. C++中的字符串

  在C++中使用字符串有两种方法。
  C风格的字符串:用字符数组表示字符串。
  C++风格的字符串:将C风格的表示封装到一种易于使用和更安全的string类型中。
  C++中std::string类型在<string>头文件中定义,C++ string的用法与基本类型几乎相同。示例如下:

std::string myString { "Hello, World" };
std::cout << std::format("The value of myString is {}\n", myString);
std::cout << std::format("The second letter is {}\n", myString[1]);

参考

[比] 马克·格雷戈勒著 程序喵大人 惠惠 墨梵 译 C++20高级编程(第五版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值