目录
二、变量
三、复合类型
四、const限定符
五、处理类型
六、自定义数据结构
一、 基本内置类型
1、算术类型分为整形和浮点型,常见的算术类型:char:1个字节,short:2个字节,int:2个字节,long:4个字节,float:4个字节,double:8个字节,long long【c++11】:8个字节。可寻址的最小内存块称为“字节(byte)”,存储的基本类型称为“字(word)”。
2、带符号数和无符号数(unsigned):带符号数可以表示正数、负数或0;无符号数则只能表示大于0的数(嵌入式软件开发中常使用此类型)。
注意【Note】:
a、切勿混用带符号类型和无符号类型,因为当无符号取值为负时,会出现异常结果。
3、如何选用类型:
(1)当明确知道数值不可能为负时,选用无符号类型。
(2)使用int进行整数运算,如果数值超过int的表示范围,则选用long long。
(3)执行浮点运算选用double。
4、字符和字符串字面值:‘a’表示字符字面值,“Hello”表示字符串字面值。编译器在每个字符串结尾处添加一个空字符(‘\0’),所以字符串实际长度比内容多1。
二、变量
1、变量提供一个具名的、可供操作的存储空间。每个变量都有数据类型,数据类型决定着变量所占内存大小、存储的值的范围、以及变量可以参与的运算。
2、列表初始化【c++11】:int a={0}。
注意【Note】:
初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象当前值擦除,用一个新值代替。
函数体外的内置类型如果没有初始化,则其值默认为0或者空字符(串),而定义于函数体内的内置类型如果没有初始化,则其值是随机的,所以建议初始化每一个内置类型的变量。
3、变量的声明和定义:int i;--->声明;extern double pi=3.14;--->定义(extern关键字使得该变量可以在工程中其他文件中使用)。声明使得名字被程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明;而定义负责创建与名字关联的实体,定义会申请存储空间。
【Note】:
变量只能被定义一次,但是可以被多次声明,建议第一次使用变量时再定义它,不宜定义同名的局部变量。
4、变量命名规范:
(1)标识符要能体现实际含义。
(2)自定义标识符不能连续出现两个下划线,也不能以下划线紧连大写字母,定义在函数外的标识符不能以下划线开头。
(3)变量一般用小写字母。
(4)标识符一般以大写字母开头,单词间应有明显区分:Sales_item。
三、复合类型
1、引用:int &a=b;或者int b=1,&a=b;
每个引用都必须以符号&开头。
【Note】:
a、引用并非对象,没有实际地址,它只是已存在的对象的别名,所以不能定义引用的引用。
b、引用必须初始化,因为引用无法重新绑定到另一个对象。
引用(非const引用)只能绑定在对象上,而不能与字面值或者某个表达式绑定在一起,并且类型要与绑定的对象类型严格匹配。
2、指针:int a=1,*p=&a;
指针存放变量的地址,如果一条语句中定义了多个指针变量,则每个变量都必须以符号*开头。指针应该属于四种状态:(1)指向一个对象(2)指向紧邻对象所占空间的下一个位置(3)空指针(4)无效指针。
只要指针有一个合法值,就能将它用在条件表达式中,例如检查指针是否合法:if(p){...},非法指针会造成不可预计的后果。
空指针:不指向任何对象,试图在使用一个指针前可以先检查其是否为空(防止出现内存问题)。得到空指针有三种方式:(1)int *p=nullptr【c++11】;(2)int *p=0;(3)int *p=NULL(包含头文件cstdlib)。
void *指针:可以用于存放任意对象的地址。
【Note】:
指针本身是一个对象,允许对指针赋值和拷贝,但是指针不能指向引用。
b、指针在定义时无须初始化(一般不建议,容易产生内存问题)。
解引用操作符(*)仅适用于确实指向了某个对象的有效指针,对无效指针进行拷贝和访问都是非法的。
不能直接把int等类型的变量赋给指针,即使它的值是0;
建议初始化所有指针,如果实在不知道指针该指向何处,就把它初始化为空指针。
3、数组:char a[] = “hello”;
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。
4、理解复合类型的声明:面对比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清它的真实含义。例如:int *&r=p;--->r是对指针p的引用。
四、const限定符
1、被const限定的对象具有只读属性,const对象一旦创建后其值就不能改变,所以const对象必须初始化。例如:const int BufSize=512;默认情况下,const对象只在文件内有效,如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。
2、对const的引用(常量引用):const int ci=1024;const int &r=ri;对常量的引用不能用作修改它所绑定的对象。在初始化常量引用时,允许用任意表达式作为初始值,只要该表达式可以转换成引用的类型即可,允许为一个常量引用绑定非常量的对象、字面值,甚至是一般表达式。非常量引用不能绑定到常量对象上。对const的引用常用于函数参数中。
3、指针和const:
(1)指向常量的指针:int a=1;const int *p=&a;要想存放常量对象的地址,只能使用指向常量的指针。
(2)常量指针:int a=1;int *const p=&a;常量指针必须初始化,一旦初始化完成,存放指针的地址就不能再改变了。
(3)指向常量的常量指针:int a=1;const int *constp=&a;指针所指的对象的值和自己的地址均不能改变。
4、顶层const和底层const:顶层const表示指针本身是常量(例如:int *const p=&a),底层const表示指针所指的对象是一个常量(例如:const int *p=&a)。顶层const可以表示任意的对象是常量,比如算术类型、类、指针等,底层const则与指针和引用有关。
具有相同的底层const资格,或者两个对象可以进行转换。
5、constexpr和常量表达式
(1)常量表达式:值不会改变并且在编译过程中就能得到计算结果的表达式。显然字面值属于常量表达式,用常量初始化的const对象也是常量表达式。
一般来说,如果你认定变量是一个常量表达式,那就把它声明为constexpr类型【c++11】。声明为constexpr的变量一定是常量而且必须用常量表达式初始化。
constexpr int a = 20;
(2)字面值类型:常量表达式类型比较简单,值显而易见,就把它们称为字面值类型。算术类型、引用和指针类型都属于字面值类型,而类库、I/O库、string类型则不属于字面值类型,不能被定义为constexpr。定义为constexpr的指针的初始值必须为nullptr或者0。另外,用constexpr声明的指针是常量指针。
五、处理类型
1、类型别名:某种类型的同义词,可以让复杂的类型名字变得简单明了。
(1)typedef :typedef char *pstring;const pstring cstr = 0;pstring是char*的别名,基本类型是指针,所以cstr的类型是指向char的常量指针。
(2)using【c++11】:using v_int = vector<int>;v_int是vector<int>的类型别名。
2、auto类型说明符【c++11】:让编译器替我们去分析表达式所属的类型,auto定义的变量必须有初始值。可以使用auto声明多个变量,但是所有变量的类型必须一致。
3、decltype类型说明符【c++11】:decltype(f()) sum = x,选择并返回操作符的数据类型。
不是一个变量,则decltype返回表达式结果对应的类型。
解引用操作,decltype将得到引用类型。
括号变量,结果将是引用。
int i=42,*p = &i,b,&r = i;
decltype(r+0) b;//加法的结果是int,因此b的类型是int。
decltype(*p) c = b;//c是int&,必须初始化。
decltype((i)) d = c;//d是int&。
六、自定义数据结构
1、类数据成员:类的数据成员定义了类的对象的具体内容,可以为数据成员提供一个类内初始值【c++11】。创建对象时,类内初始值将用于初始化数据成员,没有初始化的成员将被默认初始化。
2、预处理器概述:预处理器是在编译之前执行的一段程序,可以部分地改变我们的程序。例如#include,预处理器会将指定的头文件代替#include,还有宏定义#define。
3、头文件保护符:防止重复包含头文件。要有意识地设置头文件保护符。
#ifndef text_H//当变量为定义时为真。
#define text_H//宏定义变量。
#endif