#include
就是如此。
)。
)#ifndef
的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。ifndef
会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once
的方式。#pragma once
一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的 “同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。main()
函数中,可以忽略显示的retrun语句;此时,会自动返回0。main()
函数或没有参数,或者具有两个参数,如下所示:int main(int argc, char* argv[])
namespace MyLibraties{
namespace Networking {
namespace FTP {
/* ... */
}
}
}
这在C++17中得到极大简化:
namespace MyLibraries::Networking::FTP {
/* ... */
}
可使用名字空间别名,为另一个名字空间指定一个更简短的新名称,例如:namespace MyFTP = MyLibraries::Networking::FTP
float myFloat = 3.14;
int i1 = (int)myFloat; //方法1
int i2 = int(myFloat); //方法2
int i3 = static_cast<int>(myFloat); //方法3
当自动转换变量的类型时,应该了解潜在的数据丢失情况。
int i = 1;
cout << "i++: " << i++ << endl;
cout << "i: " << i << endl;
int j = 3;
cout << "++j: " << ++j << endl;
cout << "j: " << j << endl;
C++17允许在if语句中包括一个初始化器,语法如下:
if (
中引入的任何变量只在
和 body
中可用。此类变量在if语句以外不可用。
下面列出它的形式:
if (Employee employee = GetEmployee(); employee.salary > 10000){...}
在这个示例中,初始化器获得一名雇员,以及检索雇员的薪水是否超出 1000 的条件。只有满足调教才执行if语句体。
一旦找到switch条件匹配的case表达式,就执行其后的所有语句,直至遇到break语句为止。即使遇到另一个case表达式,执行也会继续,这称为 fallthrough 。下列有一组语句,会为把不同的case执行:
switch (backgroundColor) {
case Color::DarkBlue:
case Color::Black:
//为深蓝色或黑色背景色执行的代码
break;
case Color::Red:
//为红色背景色执行的代码
break;
}
[[fallthrough]]
特性,告诉编译器某个fallthrough是有意为之,如下所示:switch (backgroundColor) {
case Color::DarkBlue:
doSomethingForDarkBlue();
[[fallthrough]];
case Color::Black:
//为深蓝色或黑色背景色执行的代码
doSomethingForBlackOrDarkBlue();
break;
case Color::Red:
case Color::Green:
//为红色或绿色背景色执行的代码
break;
}
switch (; ) {body}
中引入的任何变量只在
和 body
中可用。此类变量在switch语句以外不可用。C++14允许要求编译器自动推断出函数的返回类。要使用这个功能,需要把auto指定为返回类型:
auto addNumbers(int number1, int number2)
{
return number1 + number2;
}
编译器根据return语句使用的表达式推断返回类型。函数中可有多个return语句,但他们应解析为相同的类型。这种函数甚至可包含递归调用(调用自身),但函数中的第一个return语句必须是非递归调用。
std::size()
函数(需要
)。例如:unsigned int arraySize = std::size(myArry);
在array
中,必须在尖括号中指定两个参数。第一个参数表示数组中元素的类型,第二个参数表示数组的大小。
array<int, 3> arr = {9, 8, 7};
cout << "Arry size = " << arr.size() << endl;
cout << "2nd element = " << arr[1] << endl;
显示结果:
注意:C风格的数组和std::array都具有固定的大小,在编译时必须知道这一点。在运行时数组不会增大或缩小。
C++17引入结构化绑定(structured bindings)的概念,允许声明多个变量, 这些变量使用数组、结构、pair或元组中的元素来初始化。
例如,假设有下面的数组:
std::array<int, 3> values = {11, 22, 33};
可声明三个变量x、y和z,使用其后数组中的三个值进行初始化。注意,必须为结构化绑定使用auto关键字。例如,不能用int替代auto。
auto [x, y, z]= values;
使用结构化绑定声明的变量数量必须与右侧表达式中的值数量匹配。
如果所有非静态成员都是公有的,也可将结构化绑定用于结构。例如:
struct Point { double mX, mY, mZ;};
Point point;
point.mX = 1.0; point.mY = 2.0; point.mZ = 3.0;
auto [x, y, z] = point;
在循环中可使用 break 关键字立刻跳出循环并继续执行程序。关键字 continue 可用来返回到循环顶部并对while表达式重新求值。这两种风格都不提倡使用,因为它们会使程序的执行产生无规则的跳转,应该慎用。
初生始化列表在
头文件中定义:利用初始化列表,可轻松地编写能接收可变数量参数的函数。initializer_list 类是一个模板, 要求在尖括号之间指定列表中的元素类型,这类似于指定vetor中存储的对象类型。下例演示如何使用初始化列表:
#include
using namespace std;
int makeSum(initializer_list<int> lst)
{
int total = 0;
for (int value : lst) {
total += value;
}
return total;
}
makeSum()
函数接收一个整型类 型的初始化列表作为参数。函数体使用“基于区间的for 循环”来累加总数。可按如下方式使用该函数:
int a = makeSum({1, 2, 3}) ;
int b = makeSum({10, 20, 30, 40, 50, 60}) ;
初始化列表是类型安全的,会定义列表中允许的类型。对于此处的makeSum()
函数,初始化列表中的所有元素都必须是整数。尝试使用double 数值进行调用,将导致编译器生成错误或警告,如下所示:
//在初始化列表中,不能将类型“ double”缩小为“ int”(已提供修复)
int c = makeSum({1, 2, 3.0});
欢迎关注公众号:c_302888524
发送:“C++高级编程(第3版)” 获取电子书