[C++ Primer]第二章 变量与基本类型

2018-09-18  本文已影响0人  两全丶

2.1 基本内置类型

包括

2.1.1 算术类型

算术类型所占的大小在不同机器上有所差别

类型 h含义 最小尺寸(字节)
bool 未定义
char 1
wchar_t 宽字符 2
char16_t Unicode字符 2
char32_t Unicode字符 4
short 2
int 2
long 4
long long 8
float 6位有效数字
double 10位有效数字
long double 10位有效数字

带符号类型和无符号类型

对于char(注意)

类型选择的建议

2.1.2 类型转换

含有无符号类型的表达式

for(unsigned int u = 10;u >= 10;--u)
  cout << u << endl;
//改为
while(u > 0)
{
  u--;//必须先减再输出
  cout << u << endl;
}

2.1.3 字面值常量

每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型

整型和浮点型字面值

整型

浮点型

字符和字符串字面值

转义序列

常用的有

指定字面值的类型

字符和字符串字面值前缀

前缀 含义 类型
u Unicode16字符 char16_t
U Unicode32字符 char32_t
L 宽字符 wchar_t
u8 UTF-8字符串(用于字符串) char

整型浮点型字面值后缀

后缀 含义 类型
u or U unsigned能匹配的最小类型 无符号
l or L 至少为long long
ll or LL 至少为long long long long
f or F float float
l or L(浮点型) long double long double

布尔字面值和指针字面值

布尔

指针

2.2 变量

2.2.1 变量定义

初始值

double price = 109.99;

列表初始化(C++11)

//等价于 int sold = 0;
int sold = {0};
int sold{0};
int sold(0);

默认初始化

2.2.2 变量声明和定义的关系

为了支持分离式编译(拆分为多个文件), C++将声明和定义区分开来。要在多个文件里使用同一个变量,必须将声明和定义分离。

声明(Declaration)

使得名字为程序所知(可以声明别处定义过的变量,进行使用)

定义(Definition)

负责创建与名字关联的实体

extern int i; //只声明而不定义i
int j; //声明并且定义j
extern double pi = 3.14 //extern语句如果包含初始值就不再只是声明,包括了定义(函数体内部这么做会报错)

2.2.3 标识符

2.2.4 名字的作用域

2.3 复合类型

复合类型指基于其他类型定义的类型。

2.3.1 引用

引用为对象其了另外一个名字。使用&d来定义引用类型

int a = 100;
int &ref = a;//ref 指向 a
//int &ref;错误,引用必须被初始化

2.3.2 指针

指针是指向另外一种类型的复合类型,通过*d来定义

int a = 1;
int *pointer = &a;

指针与引用的区别

获取对象的地址

通过取地址运算符&

指针也需要与其被指对象的类型严格匹配(有两个例外的情况)

int a = 1;
int *pointer = &a;//取地址运算符&

空指针与野指针

利用指针访问对象

使用解引用符*

int a = 1;
int *pointer = &a;//取地址运算符&
cout << *pointer << endl;

其他指针操作

void*指针

可以存放任意类型对象的地址,但是在使用时必须进行类型转换才能使用

int a = 1;
void *p1 = &a;//合法
cout << *p1 << endl;//不合法
int *p2 = (int *)p1;
cout << *p1 << endl;//合法

2.3.3 理解复合类型的声明

变量的声明

int *p;
int a;
int &ref = a;
// *, &在这里为类型修饰符

指向指针的指针

通过*的个数来区别指针的级别

int a = 1;
int *pi = &a;//一级指针
int **pii = &pi;//二级指针
//也是由于使用了不同的类型修饰符

绑定指针的引用

由于指针是对象,所以可以用引用绑定指针

int i = 42;
int *p = &i;
int *&ref = p;//绑定int *指针的引用

2.4 const限定符

const限定符用来声明常量值

const int bufsize = 512;

const作用域

默认情况下,const对象仅在文件内有效

若想要让const对象在其他文件中也能访问到,必须在定义和声明时都添加extern关键字

extern const int bufsize = 125;//定义也要加上extern

extern const int bufsize;//声明加上extern

2.4.1 const的引用

可以将const对象绑定到引用上, 但是该引用必须也用const修饰

const int a = 125;
const int &ref = a;

初始化和对const的引用

在两种情况下,引用绑定的对象可以不和引用类型匹配

int i = 42;//非常量对象
const int &ref1 = i;//绑定非常量对象,注意必须为const
double dval = 3.14;//浮点数
const int &ref2 = dval;//绑定类型不匹配的对象,但是浮点数可以转化为int
/*
实际上发生的事情为,创建了一个临时变量,该引用绑定到了该临时变量上
如果该引用不是const的,修改该引用修改的是临时变量,而不是原来的变量,所以必须为const的
const int temp = dval;
const int &ref2 = temp;
*/

2.4.2 指针和const

类似于常量引用,一样可以定义指向常量的指针,但是指针必须用const修饰

const double pi = 3.14;
double *ptr = &pi; //错误,必须用const修饰
const double *ptr = &pi;

const指针

代表的意思为不能改变该指针所指向的对象.注意const的位置

int *const pointer;

const指针必须初始化

int a = 0;
int b = 0;
const int *ptr = &a;
ptr = &b; //错误

2.4.3 顶层const

顶层const

对于指针来说表示指针本身是个常量

一般的,顶层const可以表示任意的对象是常量

底层const

对于指针来说表示指针所指的对象是个常量

一般的,底层const则与指针和引用等符合类型的基本类型部分有关(所指的东西)

2.4.4 constexpr和常量表达式

常量表达式指不会改变,且在编译过程中就能计算得到的表达式

constexpr常量

c++11新标准规定, 可以用constexpr来声明一个常量表达式变量(是一个常量)

constexpr int mf = 20; //是常量表达式
constexpr int m1 = size();//不是常量表达式,不行

字面值类型

指针和constexpr

用constexpr修饰指针,表达的意思使该指针为常量指针(即该指针本身不能改变)

2.5 类型别名

使用类型别名可以简化类型书写

2.5.1 类型别名

typedef

typedef double wages; //wages i = 0.0; 即为声明一个double类型的变量
typedef int *p;//p为int *的同义词
typedef int p[10];//p为int arr[10]的同义词

别名声明(c++11)

using SI = Sales_item; //SI是Sales_item的同义词

指针、常量和类型别名

typedef int *p;//p为int *的同义词
const p i = 0; //i为指向char的常量指针(注意不是指向常量 的指针)

不能简单的将类型别名替换为他原来的名字

const int *i = 0;//这就变成了指向const int常量的指针了,而不是常量指针

2.5.2 auto类型说明符

C++11新标准允许用auto类型说明符让编译器替我们去分析表达式所属的类型

int i1 = 0;
float i2 = 1.2;
auto var = i1 + i2;//var为float

复合类型、常量和auto

编译器推断出来的类型和初始值类型有时不完全一样,编译器会做适当的调整

如果希望推断出auto类型为顶层const,可以加上const

const auto f = ci;

还可以将引用类型设置为auto

auto &g = ci;

2.5.3 decltype类型指示符

上一篇下一篇

猜你喜欢

热点阅读