一、数据类型 – data type:定义使用存储空间(内存)的方式
(1)内部数据类型:编译器本身能理解的数据类型。标准C的内部类型规范不说明每个内部数据类型必须有多少位,只规定其必须能存储的最大值和最小值。
用户定义数据类型:抽象数据类型。
(2)4个基本数据类型:char、int、float、double
(3)说明符:short、long、signed、unsigned
(4)unsigned不保存符号,因此有一个多余位可以用,所以能存储比signed数大两倍的整数。
(5)除了char类型,其它内置的数据类型都是signed,可以通过signed char强制使用符号位。
二、指定存储空间分配
1、全局变量
(1)在所有函数的函数体外定义,程序所有部分可使用。
(2)在一个文件中使用extern关键字来声明另一个文件中存在的全局变量,那么这个文件可以使用这个数据。
2、静态变量
(1)函数内部的局部变量定义为static时:局部变量的值在程序整个生命期存在,初始化只在函数第一次调用时执行。
(2)static作用于函数名和所有函数外部的变量时:在文件外部不可以使用这个名字,函数名或变量局限于文件,具有文件作用域。
三、运算符,位运算
1、左值和右值
(1)左值:明确的命名变量,有一个存储数据的物理空间
(2)右值:任意常量和能产生值的表达式
2、一些tips
(1)若打印一个bool值,一般会看到1表示true,0表示false
(2)异或(xor)”^”:两输入位之一是1,而不同时为1,则是1.(相同为0,不同为1)
(3)如果移位运算后面的值比运算符左边的操作数位大,则结果不定
(4)&&是逻辑运算符,&是位运算符
(5)逗号运算符可以用于分隔表达式,但只产生最后一个表达式的值。
四、常量、预处理器宏
1、常量
(1)在旧版本的C中,使用预处理器
#define PI 3.1415926
缺点是不能进行类型检查;不能得到地址(不能传递指针和引用);不能识别作用域。
(2)C++中,使用命名常量
const int size = 100; //必须初始化
另:const – 这是不会变的;
volatile – 不知道什么时候就变了
2、预处理器宏
(1)#define PRINT(STR, VAR) /
Cout << STR “=” << VAR << endl
使用时,PRINT(“v+w”, u);
跟在宏名后面的括号中的参数会被闭括号后面的所有代码替代。在调用宏的地方删除名字,并替换代码。所以使用宏时,编译器不会报告任何错误信息,并不进行类型检查。
(2)#define P(EX) cout << #EX << “:” << EX << endl
#EX为字符串化的预处理特征,可获得任一表达式并把它转换成一个字符数组。比如:P(a)将产生代码cout << “a:” << a << endl
(3)关于assert()宏
#include<cassert>
assert(expression); //若表达式为假,则程序终止
若在include之前插入语句行插入#define NDEBUG则可清除由assert()宏产生的代码。
(4)typedef命名别名
typeof 原类型名 别名;
eg: typedef unsigned long ulong;
与预处理器的不同之处:编译器知道将名字做类型处理。
五、有关sizeof
Sizeof提供给我们有关数据项目所分配的内存的大小,告诉我们任何变量使用的字节数,也告诉我们数据类型的大小。有关sizeof的东东可见这篇博客《深入理解sizeof》。
六、数组的标识符
数组的标识符不像一般变量的标识符:
(1)数组的标识符不是左值,不能给它赋值,他只时间进入方括号的语法手段。
(2)给出数组名没有方括号时,得到的即是数组的起始地址。
(3)可以把数据标识符看成是数据起始地址的只读指针。
(4)声明一个数组为函数参数,实际上声明的是一个指针。给函数传递数组时,实际上是传递了起始地址。数组不会按值传递,不会自动得到传递给函数的数组的本地拷贝,修改数组时,其实是修改外部对象。