变量和基本类型
1.基本内置类型
包括算数类型和空类型:
算术类型包括字符、整型数、布尔值和浮点数;空类型不对应具体值,仅用于一些特殊场合(ex,当函数不返回任何值时使用空类型作为返回值)
1.1 算术类型
如表所示:
带符号类型和无符号类型
整型可以划分为**带符号的(signed)和无符号的(unsigned)**两种;
字符型:char、unsigned char和signed char(char会表现为其中一种)
当一个算术表达式中既有无符号数 又有int值时,那个int值就会转化为无符号数:
unsigned u = 10;
int i = -42;
cout << u + i << endl; //先将整数-42转化为unsigned再相加,值等于这个负数加上无符号数的模;
test:
//下面两组定义是否有区别:
int month = 9, day = 7;
int month =09, day = 07;
第一组定义是正确的,定义了两个十进制数;
第二组定义是错误的,编译时候会报错:0开头表示为八进制数,而数字9超出了八进制表示范围;
2. 变量
**定义:**变量提供一个具名的、可供程序操作的存储空间;
语法:类型说明符 变量名 = 初始值;
示例
int sum = 0, value = 1;
char c = 'a';
string s = "dbzdxnj";
重点注意:在C++中,初始化 != 赋值 :初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值删除,而以一个新值来替代;
初始化列表
**定义:**用花括号来初始化变量
int num = 1;
int num = {1};
int num{0};
int num(0);
当用于内置类型变量时,如果使用初始化列表且初始值存在丢失信息的风险时,编译器会报错:
long double ld = 3.141592653;
int a{ld}, b = {ld}; // 错误:存在信息丢失
int c(ld), d = ld; // 正确,确实丢失信息
默认初始化
内置类型定义于任何函数体之外的变量被初始化为0;
定义在函数体内部的内置类型变量将不被初始化;
类的对象如果没有显式地初始化,其值由类确定;
test
//下列变量的初值分别是什么
string global_a; //string 类无论在哪都初始化为空串
int global_b; // 函数外初始化为0
int main() {
int global_c; // 函数内不初始化
string global d;
}
变量声明和定义
声明使得名字为程序所知,一个文件如果想要使用别处定义的名字,必须包含对那个名字的声明;
定义负责创建与名字关联的实体;
声明一个变量而非定义它,就在变量名前加关键字extern , 且不要显式初始化变量:
extern int i; // 声明i而非定义;
int j; //声明并定义
标识符命名
字母、数字和下划线;定义在函数体外的标识符不能以下划线开头;
用户自定义标识符不能连续出现两个下划线;
且不能下划线紧连大写字母开头;
3. 引用
引用即别名:引用为对象起了另外一个名字
int val = 100;
int &refval = val; //val的引用为refval
int &refval2; // 报错,引用必须初始化
定义引用时, 程序把引用和初始值绑定在一起,而不是拷贝;一旦初始化完成,引用将和它的初始值对象一直绑定在一起。
无法令引用重新绑定到另外一个对象,因此引用必须初始化;
引用不是一个对象,只是一个别名
注意:
int &ref1 = 10; //错误: 引用初始值不能是字面值,必须为一个对象
double a = 1.5;
int &ref2 = a; // 错误: 引用类型初始值必须是int
4. 指针
指针存放某个对象的地址;
指针的类型和它指向的对象的类型要严格匹配;
空指针:不指向任何对象
int *p = nullptr; //c++11新标准,推荐
int *p = 0;
int *p = NULL;
void*指针可用于存放任意对象的地址;
但不能直接操作void* 指针所指向的对象;
double val = 100, * p = &val;
void *ptr = &val;
练习 : 给定指针p,你能知道它是否指向了一个合法的对象吗?如果能,叙述判断的思路
【解答】
在C++程序中,应该尽量初始化所有指针,并且尽可能等定义了对象之后再定义指向它的指针。如果实在不清楚指针应该指向何处,就把它初始化为nullptr或者0,这样程序就能检测并知道它有没有指向一个具体的对象了。其中,nullptr是 C++11新标准刚刚引入的一个特殊字面值,它可以转换成任意其他的指针类型。在此前提下,判断p是否指向合法的对象,只需把p作为if语句的条件即可,如果p的值是 nullptr,则条件为假;反之,条件为真。如果不注意初始化所有指针而贸然判断指针的值,则有可能引发不可预知的结果。一种处理的办法是把if§置于try结构中,当程序块顺利执行时,表示p指向了合法的对象;当程序块出错跳转到 catch语句时,表示p没有指向合法的对象。
指向指针的引用
指针是对象,所以存在对指针的引用;引用不是对象,所以不存在指向引用的指针;
int val = 10;
int *p;
int *&ref = p; // ref 是对指针 p 的一个引用
ref = &i;
*ref = 0;
法的对象;当程序块出错跳转到 catch语句时,表示p没有指向合法的对象。
指向指针的引用
指针是对象,所以存在对指针的引用;引用不是对象,所以不存在指向引用的指针;
int val = 10;
int *p;
int *&ref = p; // ref 是对指针 p 的一个引用
ref = &i;
*ref = 0;