数据类型、运算符和表达式
数据类型、运算符和表达式
C++程序中每个变量或常量都要拥有一种数据类型。
c++中的数据类型可以分为三类:
- 基本类型:C++语言预先定义好的数据类型
- 逻辑型
- 字符型
- 整形
- 浮点型
- 空值型
- 导出类型:由某种已知类型构造出来的数据类型
- 数组
- 指针
- 引用
- 用户定义类型:用户给出具体定义后才能使用的数据类型
- 枚举类型
- 类类型
基本类型
- 逻辑型:逻辑型用关键字bool表示。取值只包含true(1)和false(0)。
- 字符型:字符型用关键字char表示。用ASCII码表示,占用1字节,即8位。
- 整型:整型用关键字int表示,由于计算机的存储空间有限,因此整形数据的存储范围是计算机所能表示的全部整数,整型数据所占据的存储空间大小根据机器的不同有所差别,如16位计算机中,int用16位表示,32位计算机中,用32位表示。
- 浮点型:浮点型包括单精度型(float 占用4字节,表示范围:-3.4E38 ~ 3.4E38 有效数字7位,超出则舍去7位以后的数字)和双精度型(double 占用8字节,表示范围:-1.7977E308 ~ 1.7977E308 有效数字15位,超出则舍去15位以后的数字)两种。浮点数采用尾数加阶码的表示形式。
- 空值型:用关键字void表示。只可用于表示没有返回值的函数或用于声明数据类型尚不明确的指针变量。
基本类型的派生类型
基本类型的字长及其取之范围可以放大或缩小,改变后的类型叫作基本类型的派生类型。
派生类型声明符由基本类型关键字char、int、float、double前面加上类型修饰符组成。
类型修饰符包括:
- short 短类型,缩短字长。
- long 长类型,加长字长。
- signed 有符号类型,取值范围包括正负值。
- unsigned 无符号类型,取值范围只包括正值。
类型 | 声明符 | 长度(字节) | 取之范围 |
---|---|---|---|
有符号短整数 | short 或 short int 或 signed short int | 2 | -2^15 - 2^15-1 |
无符号短整数 | unsigned short 或 unsigned short int | 2 | 0 - 2^16-1 |
有符号整数 | int 或 signed int | 4 | -2^31 - 2^31 -1 |
无符号整数 | unsigned 或 unsigned int | 4 | 0 - 2^32 - 1 |
有符号长整数 | long long int signed long int | 4 | -2^31 - 2^31-1 |
无符号长整数 | undigned long unsigned long int | 4 | 0 -2 ^32 -1 |
有符号字符 | char signed char | 1 | -128 - 127 |
无符号字符 | unsigned char | 1 | 0-255 |
单精度数 | float | 4 | -3.402823x10^38 - 3.402823x10^38 |
双精度数 | double | 8 | -1.7977x10^308 - 1.7977x10^308 |
长双精度 | long double | 8 | -1.7977x10^308 - 1.7977x10^308 |
空值 | void |
常量
常量是指在程序执行过程中值不改变的量。
符号常量是一个标识符,在程序中必须遵循 先声明,后使用原则。
逻辑常量
由于逻辑值对应着整数1或0,所以它能够像其他整数一样出现在表达式中,参与各种整数运算。
字符常量
每个字符常量只能表示一个字符。
转义字符:用反斜线 \ 引导的下一个字符失去了原来的含义,而转义为具有某种控制功能的字符。
转义序列 | 对应值 | 功能 |
---|---|---|
\a | 7 | 响铃 |
\b | 8 | 退格 |
\f | 12 | 换页 |
\n | 10 | 换行 |
\r | 13 | 回车 |
\t | 9 | 水平制表 |
\v | 11 | 垂直制表 |
\\ | 92 | 反斜线 |
\’ | 39 | 单引号 |
\" | 34 | 双引号 |
\? | 63 | 问好 |
\ooo | ooo的十进制值 | 表示1-3位8进制数 |
\xhh | hh的十进制值 | 表示1-2位十六进制数 |
整形常量
- 十进制
- 八进制:数字0开头
- 十六进制:数字0和字母x开头
特殊后缀:
- u 表示unsigned
- L 表示long int
枚举常量
枚举常量是枚举类型中定义的值,即枚举值。用关键字enum表示。因此又成为enum类型。
enum <类型名> { <枚举值表> };
- 一个enum实际是int类型的一个子集,每个枚举值代表一个整数。
- n个枚举值未赋常量值时,从左至右赋值为从0-n-1
- 若第i个赋值为m,则其后从m+1开始赋值。
变量
变量是程序中用于存储信息的单元,它对应于某个内存空间。在定义变量时,需说明变量的名字和数据类型。这些信息将告诉编译器要为变量分配多少内存空间,以及变量中要存储什么类型的值。
变量的定义:
[<存储类>] <类型名> <变量名> [ = <初值表达式>],···;
- 存储类
- auto(default):用关键字auto声明的局部变量称为自动变量。由auto修饰的变量所占用存储空间的分配和释放工作由系统自动完成。
- register:用关键字register声明的局部变量称为寄存器变量。可能以寄存器作为该变量的存储空间,只是建议(非强制)系统使用寄存器,当寄存器不够用时,该变量仍按自动变量处理。
- static:用static声明的变量称为静态变量。任何静态变量的生存期将延续到整个程序的终止。若静态变量为被赋初值,系统将自动为其赋值为0。
- extern:用关键字extern声明的变量称为外部变量。变量一旦被声明为外部变量,系统就不必像一般变量那样为其分配内存,因为该变量已在这一局部的外面被定义。外部变量一般用于多个文件组成的程序中,有些变量在多个文件中被声明,但却是指同一变量。标明某一变量为外部变量可以避免为其重复分配内存。
- 类型名 一种已经存在的数据类型名称。
- 变量名 用户定义的标识符。
- 初值表达式 赋予变量的初值。
全局不变量和局部变量
- 全局变量:是所有函数定义、类定义和程序块之外声明的变量。若不对该变量进行初始化,则系统自动初始化为0值。
- 局部变量:在某个函数定义、类定义和程序块之内声明的变量。
生存期与作用域
- 生存期:从一个变量被声明且分配了内存开始,直到该变量声明语句失效,它占用的内存空间被释放为止。一个全局变量的生存期从它被声明开始,直到程序结束。一个局部变量的生存期从它被声明开始,直到包含它的最近的一个程序块结束。
- 作用域:指变量名可以代表该变量存储空间的范围。
TIPS:一般情况下,变量的作用域与声明周期一致,但由于C++允许在程序的不同部分为不同变量取相同的名字,因此一个变量名的作用域可能小于其生存期。
int f()
{
int a = 1 , b = 5;
if(b >= 3)
{
// 此处a为double,与int型的变量a没有关系
double a = 1.0;
b = 2;
}
return a;
}
typedef 类型说明
使用关键字tyoeof可以为已有类型名定义一个新类型名。
typedef <已有类型名> <新类型名>
typedef int integer;
integer a; // 等价于int a
TIPS:typedef类型说明并没有真正地定义新的数据类型,它只是相当于给某个已有的数据类型起了一个别名。在大规模程序中为了提高代码可读性通常使用这种形式。
符号常量声明语句
符号常量在使用前必须先进行定义。符号常量定义语句同变量定义语句类似,其语法格式为:
const <类型名> <符号常量名> = <初值表达式> , …;
系统执行符号常量定义语句时,需要依次为每个符号常量分配存储单元并赋初始值。并且这个值以后将保持不变,只允许读取不允许修改。
TIPS:若常量类型为int, int修饰符可以省略。
TIPS:true和false就是系统预先定义的符号常量。
运算符(操作符)
算术运算符分为三类:
- 单目(一元)运算符
- -
- ++
- –
- 双目(二元)运算符
- +
- -
- *
- \
- %
- 三目(三元)运算符
- 表达式1 ?表达式2:表达式3
不同类型进行计算的规则:
- 参加运算的两个运算分量均为整型时,结果为int。
- 参加运算的两个运算分量有一个单精度型,并且不包含双精度型时,结果为float。
- 参加运算的两个运算分量有双精度型时,结果为double;
关系运算符(全部都是双目运算符):
- <
- <=
- >
- >=
- ==
- !=
逻辑运算符:
- !(单目)
- &&(双目)
- ||(双目)
位运算符:
- 单目
- ~(按位取反)
- 双目
- & 按位与 双1为1
- | 按位或 有1为1
- ^ 按位异或 相同为0,不同为1
- >> 按位右移 全部向右移动,最左侧补0
- << 按位左移 全部向左移动,最右侧补0
sizeof
sizeof运算符,可进行字长提取操作。(即占用内存的字节数)
sizeof(<运算分量>)
sizeof(int) // 4
int a = 1;
sizeof(a) // 4
TIPS:运算分量可为变量类型或变量名。
圆括号运算符
圆括号运算符的三种用法:
- 用于函数调用 <函数名> (<实参列表>)
- 强制类型转换 (<类型名>) <表达式>
- 用于类型构造 <类型名> (<表达式>)
优先级和结合性
根据运算符的优先级和结合性,可以将表达式的计算顺序规则总结为以下3条:
- 优先计算带有括号的字表达式
- 没有括号部分,依照运算符优先级,由高到底进行计算。
- 具有相同优先级的运算符,按照结合性规定,依次进行计算。