第一章 基础

函数

函数的类型由返回值类型和括号中参数类型顺序组成:

double get(const vector<double>& vec, int index);
// 类型是 double(const vector<double>&, int)

对于成员函数,类的名称也是函数类型的一部分

char& String::operator[](int index);
// 类型是 char& String::(int)

重载函数

使用相同的名称定义多个函数,被称为重载函数,是泛型编程的基本特性之一。

每个重载函数都应该有相同的语义

类型,变量与运算

int inch; // 声明了inch是int类型,类型决定了可以执行的操作
  • 类型:定义了对象的取值范围以及可进行的操作
  • 对象:存放某个特定类型值的内存空间
  • 值:一系列二进制位,具体含义由类型决定
  • 变量:一个有名字的对象

C++提供了大量的基础类型,每种基础类型与硬件设施对应,硬件设置决定了基础类型的固定尺寸,既可存值的范围。

char变量的尺寸取决于机器上存放一个字符需要的空间(通常是8位,既1字节)。其他类型通常是char的整数倍。

类型的实际尺寸依赖于实现,sizeof可以获取类型对应尺寸。例如sizeof(char)等于1,sizeof(int)通常为4。

如果要使用指定尺寸的类型,可以使用标准库的类型别名:例如int32_t

算数运算

大部分操作符的计算顺序是从左到右:x.y,x->y,x[y]。赋值符号是从右到左(x+=y)

由于历史原因,其他一些表达式:f(x)+g(y)。与函数参数:h(f(x), g(y))的运算顺序是未定义的(这里指的x,y的求值顺序,不是函数调用顺序)。

初始化

double d1 = 2.3; // 初始化d1为2.3
double d2 {2.3}; // 初始化d2为2.3
double d3 = {2.3}; // 初始化d3为2.3,使用{...}时,=符号可省略
complex<double> z = 1; // 数值为双精度浮点的复数
complex<double> z2 {d1, d2};
complex<double> z3 = {d1, d2};
vector<int> v {1, 2, 3, 4, 5, 6}; // int类型动态数组

使用{}初始化可以避免窄化类型转换

int i1 = 7.8; // i1变成了7
int i2 {7.8}; // 错误!

定义变量时,如果变量类型可以从初始化符号中推导出来,可是使用auto。

auto b = true;  // bool
auto ch = 'x';  // char
auto i = 123;   // int
auto d = 1.2;   // double
auto bb {true}; //

auto可以避免冗长的类型名称,在泛型编程中,这一点很重要。

作用域与生命周期

声明语句吧一个名字引入作用域:

  • 局部作用域
  • 类作用域
  • 命名空间作用域
  • 全局作用域

对象必须被构造(初始化)才能使用,并且在退出作用域时销毁。对于命名空间对象,将在程序结束时被销毁。对于成员函数,销毁时间点取决与对象所属对象的销毁时间点。一个使用new创建的对象可以持续生存,直到使用delete将其销毁。

常量

C++支持两种不变性。

  • const:大致意味着“我承诺不修改这个值”。由编译器的静态检查来强制执行 const 承诺。const 声明的值可以在运行时被计算。
  • constexpr:大致意味着“在编译时计算出值”。主要用于声明常量,把数据置于只读内存区域。constexpr 的值必须由编译器计算。
constexpr int dmv = 17;
const double sqv = sqrt(var);

double sum(const vector<double>&);

vector<double> v {1.2, 3.4, 4.5};
constexpr double s2 = sum(v); // 错误,不是一个常量表达式
posted @ 2024-07-22 23:19  蔬菜园  阅读(2)  评论(0编辑  收藏  举报