c++primer第二章笔记

Chapter 2. Variables and Basic Types

2.1 Primitive Built-in Types

2.1.1 Arithmetic Types

基本类型大小下限(节选):

int16
long32
long long64

多种字符类型:char, wchar_t, char16_t, char32_t

long double的大小为96或128bits

与其他基本类型不同,char并不等同于signed char,char具体是signed还是unsigned依编译器而定

适用类型的一些规则:

  • 不可能为负的值使用unsigned整数类型
  • 用char表示小整数时,加上signed/unsigned来指定它的符号
2.1.2 Type Conversions

赋值时类型转换规则:

  • 用非bool类型值给bool类型赋值时,如果为0,则布尔值为false,否则为true
  • 将布尔值赋值给其他类型值时,如果为true,则值为1,否则值为0
  • 将浮点数值赋给整数类型时,小数被丢弃
  • 给unsigned类型赋值,超出范围,则对该值取模
  • 给signed类型赋值,超出范围,undefined

如果一个表达式中同时出现了同样长度类型的unsigned类型值和signed类型值,signed类型值会被转化为unsigned类型值

for循环中不要使用unsigned类型值作为循环变量,否则可能无限循环

不要混合signed和unsigned类型值

2.1.3 Literals

literal: 字面量,常量

十进制常量大小匹配:int, long, long long

八进制和十六进制常量大小匹配:int, unsigned int, long, unsigned long, long long, unsigned long long

如果使用的常量超出了最大表示范围,则会报错

字符常量的前缀:

  • u: Unicode 16 characters, char16_t
  • U: Unicode 32 characters, char32_t
  • L: Wide characters, wchar_t
  • u8: utf-8(string literals only, char

整数常量不会是负值,因为负数前面的负号并不算作数的一部分,而是作为一个运算符

string literal: 字符串常量,就是引号中的字符串

两个用spaces/tabs/newlines分隔的字符串常量会被连接成同一个字符串常量

用8进制数表示字符,反斜杠后面最多跟3位数字,且只会解析反斜杠后的前3位数字

用16进制数表示字符,如果反斜杠后跟多位数字,则会解析成宽度更大的字符

nullptr是一个指针类型字面值

2.2 Variables

2.2.1 Variable Definitions

string类型:变长的字符序列

变量定义时,可以在同一条定义语句中,用左边的变量的值定义右边变量的值,如:

double a = 1.0, b = a;

C++中,初始化与赋值操作是有区别的

初始化:在变量被创建时给它一个初始值

赋值:抹掉变量的现有值并用一个新的值代替

C++中基本类型的初始化方法示例:

int a = 0;
int a = {0};
int a(0);
int a{0};

当可能发生精度损失时不能使用大括号进行初始化,数组也不可以

如果一个变量被定义但没有初始化,则它会被以默认的方式初始化

在函数体内的变量的默认初始化方式为undefined

一个未初始化的string变量,会被默认初始化为一个empty string

2.2.2 Variable Declarations and Definitions

std::表示使用的是定义在standard library中的对象

declaration(声明):当一个文件使用一个定义在其他地方的名字,需要声明

definition(定义):创建一个实体

声明确定变量的类型和名字

定义是一个声明,并且会为变量分配空间,有时会初始化

当一个声明不是一个定义时,需要在变量前加上extern关键字

所有带有显示初始化的声明都是定义。如果一个变量声明时带有extern,并且被初始化,则这是一个定义

在函数中,初始化一个extern变量时错误的

变量只能定义一次,可以声明很多次

2.2.3 Identifiers

identifiers: 名字

尽量不要使用以两条下划线开头,或者以一条下划线接一个大写字母开头的名字

在函数外部的名字尽量不要以一条下划线开头

2.2.4 Scope of a Name

最好在第一次使用一个变量的时候定义它

在outer scope中定义的变量,可以在inner scope中定义同名变量,两者为不同变量

"::"双冒号是scope operator,globe scope没有名字,当globe scope和函数中出现了重名变量,可以在变量名前加::来指定使用的是globe scope中的变量

2.3 Compound Types

引用和指针是compound types

2.3.1 References

引用变量必须初始化

引用变量不能更改引用对象

引用就是别名

不能用字面量初始化引用,也不能用表达范围更大的类型的表达式值初始化引用

2.3.2 Pointers

指针的类型和它指向的对象的类型必须匹配

指针值的几种情况:

  • 指向一个对象
  • 指向一个对象的结束位置
  • NULL,表示没有指向对象
  • 除以上几种以外,都为invalid pointers

invalid pointers会导致错误

三种将指针值设置为null的方式:

int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL;

nullptr是一个指针类型的字面值,它可以转换为任何指针类型

NULL的定义在cstdlib中,是一个预处理器变量,预处理器会将它替换成0

现代C++程序应当避免使用NULL而使用nullptr

将一个int的值赋给一个指针是非法的,但可以用0进行赋值

两个同类型的指针是可以用"==. !="相互比较的

void* 可以指向任意类型的对象的地址

不能使用void*来操作它指向的对象

2.3.3 Understanding Compound Type Declarations

因为引用不是一个对象,因此引用没有指针

对一个变量的声明,从右向左读,如int *&r,表示r是 引用,引用的对象是一个int*

2.4 Const Qualifier

const变量必须被初始化,不能被赋值

编译器会自动将代码中的const变量换成它的值

const变量的范围是定义它的文件,除非是extern const变量,extern const变量在定义和声明时都要有extern

2.4.1 References to Const

const类型的引用在声明时前面也要加上const,如:const int &r = c;

const引用不能用来改变它引用的对象值

const引用,引用的对象可以是:普通变量/字面值/表达式,他们的类型可以和引用相同,也可以是能够自动转化成引用类型的类型(因为对于可以自动转化的类型,编译器会先创建一个临时const对象存放右边表达式的值,之后再让const引用引用这个临时对象)

如果右边变量的类型不是const引用的类型,且右边的变量不是常量,则改变右边变量的值,const引用的值不会改变,理由见上句括号

普通的引用不能用字面值初始化

2.4.2 Pointers and Const

pointer to const:

不能通过这种指针修改它指向的对象,它指向的对象可以是一个非const变量

声明方式:

const double pi = 3.14;
const double *cptr = π

指针本身的值可以改变

const pointer:

必须初始化,并且初始化过后它的值(即指向的地址)不能被改变

声明方式:

int errNumb = 0;
int *const curErr = &errNumb;

可以通过这个指针改变指向对象的值

2.4.3 Top-Level Const

对于指针:

top-level const: const pointer

low-level const: pointer to const

top-level const: 一个对象本身是const

low-level const: 一个compound type指向的类型为const

low level的compound type不能用来给普通的compound type赋值

const int*不能用来给int*赋值

2.4.4 Constexpr and Constant Expressions

constant expression: 常量表达式,即在编译期可以求值的表达式

字面值是一个constant expression

一个用constant expression初始化的const对象也是一个constant expression

constexpr:用于告知编译器,其所修饰的表达式是常量表达式,以便编译器进行优化;编译器会对它是否真的是常量表达式进行检查,如果不是,则将运算留到运行时

constexpr隐含有const

literal和literal type有区别,literal指字面值,literal type指可在编译期求值

literal type: 算术类型、引用、指针和一些类

指针和引用是literal type,但constexpr中的指针只能以nullptr/某个地址固定的变量的地址初始化,引用也只能用地址固定的变量的地址初始化

当一个指针变量被声明为constexpr,则这个指针是一个const pointer

constexpr强制top-level const

2.5 Dealing with Types

2.5.1 Type Aliases

aliases: 别名

可以使用typedef关键字来为类型创建别名,如下:

typedef double wages;
typedef wages base, *p; //base is a synonym for double, p for double*

另一种定义别名的方式是:

using SI = Sales_item;

使用别名时注意const的位置,如果是一个指针的别名,则指针本身为一个对象,在用别名声明时句首加const,即表示这个对象不能修改。因此得到的是constant pointer而不是pointer to constant

2.5.2 The Auto Type Specifier

auto关键字让编译器来推断变量的类型

用auto关键字声明的变量必须显式初始化

可以在同一条auto声明语句中定义多个变量,但这些变量的基本类型必须相同

auto忽略top-level const,保留low-level const

如果我们希望推断出来的type拥有top-level const,则需要:

const auto f = ci;

也可以在变量前加"&"来声明引用

2.5.3 The Decltype Type Specifier

当我们希望用一个表达式的类型声明变量,却不想将变量初始化成表达式的值时,可以用decltype

decltype能够返回一个表达式的类型

decltype(f()) sum = x;

decltype与auto不同,它能够区分base type和它的引用类型

decltype(*p) c = &i;

*p的类型为引用类型,而不是普通类型

如果在decltype中给变量加括号,则会得到它的引用类型,即

decltype((type))

得到的总是引用类型

赋值表达式的类型:

赋值表达式的类型是左操作数的类型的引用类型

2.6 Defining Our Own Data Structures

2.6.1 Defining the Sales_data Type

在新标准中,我们可以为结构体的成员提供初始化,没有初始化的成员会被用默认方式初始化

不可以用圆括号初始化

2.6.2 Using the Sales_data Class
2.6.3 Writing Our Own Header Files

每当头文件被更改,使用这个头文件的代码都需要重新编译

preprocessors: 预处理器

当预处理器遇到"#include"时,它会用相应头文件的内容替换#include语句

preprocessor variables: 只有两种状态,defined和not defined

#define语句定义了preprocessor variables

#ifdef和#ifnedf用于判断一个preprocessor variable是否被定义

如果判断的结果为true,那么从#ifxxx到#endif中间的语句会被执行

header guard:

#ifnedf SALES_DATA_H
#define SALES_DATA_H
/* ... */
#endif

Chapter Summery

type的作用:定义了变量的存储空间大小,以及它能够进行的操作

Defined Terms

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值