变量和常量
程序两种基本数据对象
声明语句
说明变量的名字及类型,也可以指定变量的初值
运算符
指定将要进行的操作
表达式
把变量与常量组合起来生成新的值
类型
对象的类型决定该对象可取值的集合以及可以对该对象执行的操作
0x0 变量名
变量名和常量名的限制
- 由字母和数字组成,但第一个字符必须为字母,"_"看做是字母
- 区分大小写,通常变量名小写,常量名大小
- 内部名保证至少前31个字符有效,外部变量名仅保证前6个字符的唯一性,不区分大小写
- 关键字不能用作变量名
0x1 数据类型及长度
C基本数据类型
- char 字符型,占用1字节
- int 整型,通常反映所用机器中整数的最自然长度
- float 单精度浮点型
- double 双精度浮点型
长度
short通常为16位,long类型通常为32位,int类型可以为16位或32位。
原则: 16位 <= short <= int <= long, long >= 32位
限定符
short,long限定整数,如:
short int sh;
long int counter;
int 可省略
类型限定符
signed,unsigned可用于限定char类型或任何整型。unsigned类型的数总是正值或0。
不带限定符的char类型对象是否带符号取决于具体机器。
long double类型表示高精度的浮点数。
0x2 常量
整数常量
long类型的常量以字母l或L结尾。
无符号常量以字母u或U结尾.后缀ul或UL表示unsigned long类型。
带前缀0(数字零)的整型常量表示它为八进制,带前缀0x或0X表示它为十六进制形式。
浮点常量
浮点常量中包含一个小数点或一个指数。
没有后缀的浮点数常量通常为double类型,后缀f或F表示float类型。
字符常量
字符常量是一个整数,书写时将字符放在单引号内,如'x'。
字符在机器字符集中的数值就是字符常量的值。
字符常量可以像其它整数一样参与数值运算。
某些字符可以通过转义序列表示为字符和字符串常量。
字符常量'\0'表示值为0的字符,也就是空字符(null)。
常量表达式是仅包含常量的表达式,在编译时求值,可以出现在常量可以出现的任意位置。
字符串常量
也称为字符串字面量,使用双引号包括的0个或多个字符组成的字符序列。
编译时会将多个字符串常量连接起来.如"Hello " "world"等价于"Hello world"。
字符串常量就是字符数组,字符串的内部表示使用一个空字符'\0'作为串的结尾,所以存储字符串的物理存储单元数比实际存储的字符数多一个。
枚举常量
枚举是一个常量整型值的列表
enum boolean { NO, YES};
没有显示说明,enum类型中第一个枚举名的值为0,第二个为1,以此类推.如果只指定了部分枚举名的值,未指定值的枚举名的值将从最后一个指定值向后递增。
enum escapes { BELL = '\a', BACKSPACE = '\b',
TAB = '\t', NEWLINE = '\n', VTAB = '\v', RETURN = '\r' };
enum months { JAN = 1, FEB, MAR, APR, MAY, JUN,
JUL, AUG, SEP, OCT, NOV, DEC };
0x3 声明
所有变量必须先声明后使用,一个声明指定一种变量类型,可以一次声明多个变量。
int lower, upper, step;
char c, line[1000];
可在变量声明时同时初始化
char esc = '\\';
默认情况下,外部变量与静态变量将被初始化为0.未经显示初始化的自动变量的值为未定义(无效值)。
任何变量的声明都可以使用const限定符限定,表示改变量的值不能被修改.对数组而言,const限定符指定数组所有的元素的值不能被修改。
const double e = 2.32342343;
const char msg[] = "Hello";
int strlen(const char[]); //限定函数参数
0x4 算术运算符
二元算术运算符: +, -, *, /, % 。整数除法会截断结果中的小数部分。
取模运算符不能用于float和double类型。
优先级: +,-
< *,/,%
< +,-(一元运算符)
算术运算符采用从左到右的结合规则
0x5 关系运算符和逻辑运算符
关系运算符: >, >=, <, <=
相等性运算符: ==, !=, 比关系运算符优先级较低
关系运算符的优先级比算术运算符低
逻辑运算符: && , ||, &&比||优先级高,又都比关系运算符和相等性运算符的优先级低。
使用圆括号控制运算优先级
逻辑表达式中,如果关系为真,则表达式结果值为1,如果为假,则结果值为0。
逻辑非运算符!将非0操作数转换为0,将操作数0转换为1。
0x6 类型转换
当一个运算符的几个操作数类型不同时,就需要通过一些规则把它们转换为某种共同的类型。
自动转换把“比较窄的”操作数转换为“比较宽的”操作数,并且不丢失信息。
C语言中没有指定char类型的变量是signed还是unsigned,仅保证机器的标准打印字符集中的字符不是负值。如果要在char类型的变量中存储非字符数据,最好指定signed或unsigned限定符。
signed和unsigned值之间的比较运算是与机器相关的,因为它们取决于机器中不同整型类型的大小。
赋值时也要进行类型转换, 赋值运算符右边的值需要转换为左边变量的类型。
函数调用的参数是表达式,所以在把参数传递给函数时也可能进行类型转换。没有函数原型时,char和short类型都被转换为int类型,float类型转换为double类型。
强制类型转换
(类型名) 表达式
0x7 自增运算符和自减运算符
自增运算符++,自减运算符--, 使其操作数递增或递减1,且只能用于变量。
- 前缀: 先将值递增/减1,在使用该值
- 后缀: 先使用该值,再将值递增/减1
0x8 按位运算符
C提供6个位操作符。这些运算符只能作用于整型操作数。
- & 按位与(AND)
- | 按位或(OR)
- ^ 按位异或(XOR)
- << 左移
- >> 右移
- ~ 按位求反(一元运算符)
0x9 赋值运算符和表达式
赋值运算符是一种缩写, 赋值运算符只计算一次
expr1 op= expr2 等价于 expr1 = (expr1) op (expr2)
如: +=, -=, *=, /=, %= 等
赋值表达式的类型是它的左操作数的类型,其值是赋值操作完成后的值。
0xA 条件表达式
expr1 ? expr2 : expr3
0xB 运算符优先级与求值次序
运算符 | 结合性 |
---|---|
() [] -> . | 从左至右 |
! ~ ++ -- + - * (type) sizeof | 从右至左 |
* / % | 从左至右 |
+ - | 从左至右 |
<< >> | 从左至右 |
< <= > >= | 从左至右 |
== != | 从左至右 |
& | 从左至右 |
^ | 从左至右 |
| | 从左至右 |
&& | 从左至右 |
|| | 从左至右 |
?: | 从左至右 |
= += -= *= /= &= ^= != <<= >>= | 从右至左 |
, | 从右至左 |
不要依赖无法确定优先级的用法,如函数参数,1元运算符的多个操作数的计算顺序等。