《C程序设计语言(第2版·新版)》第2章 类型、运算符与表达式

 

  类型:决定对象可取值的集合以及可执行的操作;运算符指定操作;表达式把变量和常量组合起来生成新值。
  ANSI C修补:所有整型都包括signed和unsigned两种;浮点运算可单精度还可long double类型运算;字符串可以编译时连接;支持枚举类型;const类型;扩充算术类型的自动强制类型转换规则

2.1 变量名

  将下划线看做字母;变量名是以字母开头的字母数字序列;库函数名字通常以下划线开头,不要用;区分大小写;传统上变量名用小写,符号常量名全大写,局部变量(尤其循环控制变量)一般短名,外部变量名字较长

2.2 数据类型及长度

基本:
  char:字符型,占用一个字节,可存本地字符集中一个字符;
  int   :整型,通常反映所用机器中整数的最自然长度;
  float:单精度浮点型
  double:双精度浮点型
 
  int前可加限定符short 或long, 此时int可省略;编译器根据硬件特性自主选择合适长度(short不长于int,int不长于long);通常short为16位,int为16或32位,long为32位;
  限定符signed和unsigned可加在上述任何整型以及char前。8位 char, unsigned范围0~255,signed范围-128~127(采用对二补码的机器上);不带限定符的char是否带符号取决于机器,但可打印字符总是正值;
  float、double、long double可表示相同长度也可表示两三种不同长度;
  定义以上类型长度的符号常量及其他与机器和编译器有关的属性在<limits.h>及<float.h>中可以找到;

2.3 常量

  1、2 、3 等整数常量属int型;大整数超出int范围,会被当做long处理;long类型以L或l结尾如123456789L;ul或UL结尾表示unsigned long;十进制31=八进制037=十六进制0x1f或0X1F;它们同样可加U、L等后缀;
  123.4、1.5e-2等为double; 加f或F是float,加l或L是long double;(It:float相当于short,double相当于int, long double 相当于long)
 
  字符常量如'x'是一个整数,其值为机器字符集中的数值,可与其他字符比较也可作为整数参与数值运算;
  转义字符:'\v'、'\013'、'\xb'(纵向制表符的八进制(\ooo)和十六进制(\xhh)表示);空字符(null)为'\0',其值也为0,但其属性是字符;
  常量表达式:只含常量,例如#define MAX 1000之后的char line[2+MAX+3];在编译时而非运行时求值(ps:博客中经测试,const变量也是如此)
 
  字符串常量:类似""、" u r naive"等括在双引号内的字符序列。其内用\"表示双引号;编译时可将多个字符串常量连接,比如“hello, ”“world”等价于“hello, world”;字符串常量实则是字符串数组,内部表示中加'\0'结尾,故物理存储单元数多1;这也说明C中字符串长度无限制,确定其长度需扫描完该字符串;库函数strlen(s)(在中)可求s长度(不含'\0');
  枚举常量:一个常量整型值列表,方便德建立常量值与名字得关系,可自动生成(#define 则不能)。例:
  enum boolean { NO, YES };//自动从0开始赋值,NO=0, YES=1
  enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t'}:
  enum months {JAN = 1, FEB, MAR, APR}; //未指定值将递增赋值; 
  之后可定义枚举变量enum months amonth; 则令amonth等于JAN, FEB等意义明显,也可赋其他整型值

2.4 声明

  变量必须声明才能使用(有些可以通过上下文隐式声明);可声明一个变量表;可用表达式初始化;
  非自动变量只能初始化一次且是常量表达式;
  外部变量与静态变量默认被初始化为0;
  显式初始化的自动变量每次都重新初始化(可以是任何表达式),未显式初始化的自动变量值未定义(即无效值);
 
  const可限定任何变量声明,其指定变量的值不能修改;数组则所有元素都不能修改;以下函数不能修改数组元素的值: int strlen(const char[])

2.5 算术运算符

+  -  *  /  %   
  二元,其中取模运算符%不能用于浮点数;有负操作数,结果取决于机器;

2.6 关系运算符与逻辑运算符

>  >=   <  <=  ==  !=  后两个优先级较低
 
&& 高于 ||;
 
逻辑非,一般用 if(!valid) 而不用 if(valid == 0)

2.7 类型转换

  一般,自动转换把操作数“变宽”且不丢失信息;无意义表达式会报错(例如浮点数做下标);可能丢失信息的表达式(比如把长整型值赋给短整型量)会警告,但合法;
  <ctype.h>中定义了一组与字符集无关的测试和转换函数(如tolower(c),isdigit(c)等);
  C未指定char是否带符号(但保证了可打印字符为非负值),转为int与机器有关;
  if, while, for 的测试部分,“真”与“非0”等价;
 
  C中有很多隐式算术类型转换:两操作数不同则把“较低”类型提升到“较高”类型;包含unsigned类型时较麻烦,与机器有关;赋值时右边值需转变为左边类型;char, short总被转换为int,故相互赋值可能会丢失信息;float转int会截取;double转float截取或舍入取决于机器;
  强制类型转换:(类型名) 表达式,是一个一元运算符,与其他一元运算符优先级相同;函数调用将进行自动强制类型转换;

2.8 自增、自减运算符

++n: n值增1后使用;n++:n值使用后增1;--类似;只能作用于变量;

2.9 按位运算符

  6个,可作用于整型,即带符号或无符号的;
&  |  ^  <<  >>  ~ 
  常用来建屏蔽码(It: 操作数都作为二进制来运算)左移补零右移无符号补零,有符号取决于机器(分补符号位的“算术移位”和补零的“逻辑移位”)

2.10 赋值运算符与表达式

op=, 其中op可为 +  -  *  /  %  <<  >>  &  ^  |
  赋值表达式具有值,类型和值都是左操作数的结果;

2.11 条件表达式

expr1 ? expr2 : expr3

2.12 运算符优先级与求值顺序

1 括弧、访问结构:()  []  ->  .
2 前置:     !  ~  ++  --  +  -  *  &  (type)  sizeof
3 算术-乘除取模: *  /  %
4 算术-加减:       +  -
5 移位:             <<  >>
6 关系-不等性:    <  <=  >  >=  
7 关系-相等性:    ==  !=
8 按位-与:          &
9 按位-异或:       ^
10  按位-或:        |
11 逻辑-与:       &&
12 逻辑-或:        ||
13 条件表达式:    ?:
14 赋值表达式:    =  +=  -=  *=  /=  %=  &=  ^=  |=  <<=  >>=
15 逗号表达式:     ,
 
其中:
2与13结合性是从右至左,其他都是从左至右;
四个运算符(&& || ?: ,)的多个操作数有规定运算顺序,其他运算顺序以及函数各参数求值顺序也未规定,取决于编译器,因最佳求值顺序同机器结构有很大关系;
建议:避免特殊实现方式,除非了解机器;
posted @ 2015-09-15 17:15  fFaXzz  阅读(248)  评论(0编辑  收藏  举报