第二章 变量和基本类型
2.1基本内置类型
- 类型unsigned int 可以所写为unsigned
- 和其他整型不同,字符型被分为了三种:char,signed char,unsigned char。类型char和类型 signed char 并不一样。类型char实际上会表现为上诉两种形式中的一种,具体由编译器决定。
- 当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如:8比特大小的unsigned char 可以表示0到255区间内的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255.【(-1)%256=(-1+256)%256=255%256=255】
- 当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的。
- 如果表达式里既有带符号类型又有无符号类型,当带符号类型取值为负时会出现异常结果,这是因为带符号数会自动地转换哼无符号数。(eg:unsigned u =10,u2=42; cout<<u-u2<<endl ; 结果为4294967264(-32的二进制补码))
- 字面值:是一个不能改变的值,如数字,字符,字符串等。单引号内的字符字面值,双引号内的是字符串字面值。
2.2变量
- 对象是具有某种数据类型的内存空间。
- 事实上在c++语言中,初始化和赋值是两个完全不同的操作。初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。
- 定义于函数体内的内置类型的对象如果没有初始化,则其值未定义。类的对象如果没有显式地初始化,则值由类确定。
- 声明:使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义负责创建与名字关联的实体。(int k;声明并定义了k)
练习2.10
#include<iostream> #include<string> using namespace std; string global_str; int global_int; int main() { int local_int; string local_str; cout<<global_str<<endl; cout<<global_int<<endl; cout<<local_int<<endl; cout<<local_str<<endl; return 0; }
结果为global_str和local_str为空字符串,global_int为0,local_int没有初始值。
2.3复合类型
- 把int 变量直接赋给指针是错误的的操作,即使int变量的值恰好等于0也不行。(int *p = 0; 0是字面常量)
练习2.22;2.23
假设p是一个int 型指针,请说明下述代码含义;给定指针p,你能知道它是否指向一个合法的对象吗?
if(p)//...........
if(*p)//.........
- 是否是空指针
- 指针所指的值是否为0
if(p)
//合法
else
//不合法
2.4const限定符
- const对象必须初始化
- 某些时候有这样一种const变量,他的初始值不是一个常量表达式,但又确实有必要在文件间共享,解决方法是与对const变量不管是定义韩式声明都添加extern关键字。
- 常量表达式:是指不会改变并且在编译过程就能得到计算结果的表达式。
2.5处理类型
- 遇到一条使用了类型别名的声明语句时,人们往往会错误地尝试把类型别名替换成它贝莱的样子,这种理解是错误的!(typedef char *pstring; const pstring cstr = 0;//cstr是指向char的常量指针)
- auto定义的变量必须有初始值
- 赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果i是int,则表达式i=x的类型是int&。