第3章数据类型、运算符与表达式
3.1本章知识重点
1)C语言的基本词汇表和关于标识符的规定。
2)变量和常量:在程序运行过程中其值可以改变的量称为变量。变量具有数据类型、变量名、变量值和存储类型四个属性。变量在其存在期间,在内存中按照定义的类型占据不同长度的存储单元,并可以用来多次存放不同的数值。在程序运行过程中其值不能改变的量称为常量,其类型是由本身隐含的类型决定的。
3)转义字符:转义字符是一种特殊的字符常量,C语言约定以“”开头作为标记的字符序列为“转义字符”,学习中需要记住几个常用的转义字符。
4)字符常量和字符串常量的区别:字符常量与其对应的ASCII码等价,用单引号表示。字符串常量中的字符依次存储在内存中一块连续的区域内,并把空字符'0' (ASCII值为0)自动地附加到字符串的尾部作为字符串的结束标志,用双引号表示。
5)C语言中的数据类型:不同数据类型的数据具有不同的类型说明符,在内存中具有不同存储长度以及不同的取值范围和允许的操作。
6)运算符:C语言中的运算符不单单是我们通常认为的进行数学运算的符号,而是具有更加广泛的含义。C语言将描述各种操作的符号通称为运算符,除了控制语句和输入、输出以外的几乎所有基本操作都用运算符处理,所以有些文献中将其称为“操作符”。运算符具有两个属性:优先级和结合性(结合方向)。
7)表达式:用运算符将被操作对象连接起来,符合C语言语法的式子称为表达式。表达式的值也可以说是表达式的运算结果,所有表达式的值只有两类:数值和地址。
8)表达式求值的语法规则:当若干个不同优先级的运算符同时出现在表达式中时,运算符的优先级规定了运算的先后次序。当若干个具有相同优先级的运算符相邻出现在表达式中时,结合方向规定了运算的先后次序。一般来说,大多数运算符的结合方向为“从左到右”,只有单目运算符、赋值运算符和条件运算符的结合方向为“从右到左”。
9)几种表达式求值需要注意的问题:
- 算术表达式:应注意在除法运算中,两个整数相除的结果为整数。取余运算只能作用于两个整型数,并且规定运算结果的正负符号与被除数的符号一致。
- 赋值表达式:赋值运算符的优先级很低,仅高于逗号运算符。结合方向为“从右到左”,注意在运算中将右边表达式值的类型无条件地转换为左边变量的类型。要理解复合赋值运算符的含义,并学会正确的使用方法。
- 逗号表达式:逗号运算符的优先级最低,逗号表达式的值和类型就是最右边的表达式的值和类型。
- 自增运算和自减运算:自增运算和自减运算实质上是对于算术运算和变量赋值运算两种运算的结合。注意“++变量”或“变量++”出现在表达式中时求值的时机不同。
3.2习题解析
3.2.1计算题
设变量定义如下:
char a='a'; int i=3,j=5,b;
float x=2.5; double y=5.0, z;
计算下面表达式的值。
- y+=i-=j*=++x;
【答案】 -9.0
【解析】 表达式中出现三个复合赋值运算符和一个自增运算符,因为自增运算符优先级最高,先计算++x,然后再从右向左依次计算。
1)计算++x:结果x值为3.5。
2)计算j=++x相当于计算j=j3.5:先计算j*3.5值为17.5,将17.5赋予整型变量j,再做j=17.5,C语法规定以赋值表达式左边的变量类型作为表达式值的类型,结果j值为17。
3)计算i-=j*=++x相当于计算i=i-17,i=3-17,结果i值为-14。
4)计算y+=i-=j*=++x相当于计算y=y+(-14),y=5.0-14,结果y值为-9.0,表达式的值为-9.0。
- a=a+i, a+j
【答案】 105
【解析】 题中优先级最低的运算符是逗号运算符,所以是一个逗号表达式,从左向右依次计算每一个表达式,逗号表达式的值和类型就是最右边的表达式的值和类型。
1)计算a=a+i,结果a='a'+3, 变量a值为'd'。
2)计算a+j相当于计算'd'+5或者100+5('d'的ASCII码为100),因为变量a为字符型,变量j为整型,根据“类型向高转换”的规则,表达式a+j的运算结果为整型105。
3)表达式a+j的值为105,变量a值为'd'。
- a=(a+=i++, a+i)
【答案】 'h'
【解析】 括号运算符优先级最高,应先计算括号中的逗号表达式,再将该逗号表达式的值赋予变量a。
1)计算表达式i++,因为该表达式此时没有参与运算,所以暂不求值,变量i仍然等于3。
2)计算a+=i++相当于计算a=a+i,a='a'+3或者a=97+3('a'的ASCII码为97),因为变量a为字符型,表达式a=a+i的运算结果为变量a(等于'd')。
3)对表达式i++求值,相当于计算i=i+1,变量i等于4。
4)计算a+i相当于计算'd'+4:根据“类型向高转换”的规则,表达式a+i的运算结果为整型104。括号中的逗号表达式结果为整型104。
5)将104赋予变量a,表达式的值为'h',变量a值为'h'('h'的ASCII码为104)。
- (int)y% i %(int)(x+y)
【答案】 2
【解析】 该表达式做两次取余运算,是算术表达式。因为取余运算只能作用于两个整型数,所以首先需要对非整型表达式的值进行强制类型转换。
1)对变量y的值强制类型转换为整型,结果为5。
2)计算5% i相当于计算5%3,结果为2。
3)计算(int)(x+y),将表达式x+y的值7.5强制类型转换为整型,结果为7。
4)计算2%7,表达式的值为2。
- i+++j
【答案】 8
【解析】 该表达式形式上有三个加号,可以分解为一个自增运算符和一个加法运算符,是一个算术表达式。从左向右开始计算,首先将自增运算符和变量i结合,然后将i++的结果和变量j相加。可以将表达式等价表示为(i++)+j。
1)计算表达式i++,因为该表达式此时没有参与运算,变量i仍然等于3。
2)计算3+j相当于计算3+5,运算结果为8,表达式的值为8。
3)对表达式i++求值,相当于计算i=i+1,变量i等于4。
3.2.2选择题
- 下面转义字符中,错误的是( )。
A. ' 0xa5 ' B. ' 031 ' C. ' b ' D. ' " '
【答案】 A
【解析】 C语言中有一些特殊的字符,约定以“”开头作为标记,这类字符统称为“转义字符”,从字面上理解就是将反斜杠“”后面的字符转换成另外的意义,用于代表一种特定的控制功能或表示一个特别的字符。
本题中,转义字符' 031 ' 表示八进制所代表的字符。转义字符' b '表示退格操作,将当前位置移到前一列。转义字符' " ' 表示双撇号字符,而字符' ' 加1到2位十六进制数表示与该十六进制数对应的ASCII码所代表的字符。' 0xa5 '有4位十六进制数,不符合要求,如果去掉字符“”,' 0xa5 '表示一个十六进制数整型常量。
- 字符串"\\1234\\n"在内存中占( )字节。
A. 14 B. 9 C. 10 D. 11
【答案】 C
【解析】 字符串常量中的字符依次存储在内存中一块连续的区域内,并把空字符'0' (ASCII 值为0)自动地附加到字符串的尾部作为字符串的结束标志。每个转义字符和其他字符一样,在内存中占1个字节。因此,对于字符个数为n的字符串,所占内存空间应为n+1个字节。
首先计算字符串中一共有多少个字符,注意不要简单地数字符的个数,当遇到字符''时,应该考虑转义字符的判别。“\”为一个转义字符,该字符串中共有4个转义字符,'n'也是一个转义字符。除此之外,还有4个普通字符'1'、'2'、'3'、'4'。另外,字符串的结束标志'0'也占1个字节,所以该字符串在内存中占字节数为4+1+4+1=10。如果该题改为求字符串的长度,答案应该是9。
- 已知梯形的上底为a,下底为b,高为h,用C语言书写的正确的面积公式为( )。
A. 1/2(a+b)h B. 1.0/2(a+b)h C. 1.0/2.0(a+b)h D. 1.02a+bh
【答案】 B
【解析】 A项1/2(a+b)h中的1/2由于是两个整数相除,结果为整数0,导致整个表达式的计算结果为0。
B项1.0/2(a+b)h中的1.0/2由于是浮点数和整数相除,结果为浮点数0.5,修改了A项的错误,是一个符合C语言语法的正确算术表达式。
C项1.0/2.0(a+b)h中的两项相乘应该用算术运算符''连接,这种写法在一般数学代数运算中使用,但不符合C语言语法,可以改为1.0/2.0(a+b)*h。
D项1.02a+bh的语法没有问题,但根据算术运算符的优先级计算出的结果不是梯形的面积。
- 与k=n++完全等价的表达式是( )。
A. n=n+1, k=n B. k+=n+1 C. k=++n D. k=n, n=n+1
【答案】 D
【解析】 表达式k=n++的计算步骤是:
1)按照运算符的优先级,先计算表达式n++,相当于计算k=n++, 因为该表达式是后置自增运算,所以暂不求值。
2)计算k=n++, 相当于先计算k=n。
3)再对表达式n++求值,相当于计算n=n+1。
D项是正确的,B项可改写为k=k+(n+1), C项相当于n=n+1, k=n,与A项相同。
- 设变量定义如下:
- i=8, k, a, b;
double x=1.42,y=5.2;
则以下符合C语言语法的表达式是( )。
A. a=a3=2 B. a+=a-=(b=4)(a=3) C. y=float(i) D. x%(-3)
【答案】 B
【解析】 A项表达式a=a3=2首先将2赋予a3,由于赋值表达式左边必须是变量,不能是表达式,所以这是错误的写法。C项表达式y=float(i)的表示方法不正确,应该写成y=(float)i。D项表达式x%(-3)中的变量x是双精度实型,不可以进行取余运算。
- 假定变量定义如下:
- k=7,x=12;
则以下能使值为3的表达式是( )。
A. x%=(k%=5) B. x%=(k-k%5) C. (x%=k)-(k%=5) D. x%=k-k%5
【答案】 C
【解析】
A项 x%=(k%=5) 的计算过程:x=x%(k=7%5)→ x=x%(k=2)→ x=12%2→x=0。
B项 x%=(k-k%5) 的计算过程:x=x% (k-k%5)→ x=12% (7-7%5) →x=12% (7-2) → x=12%5→x=2。
C项 (x%=k)-(k%=5) 相当于(x=x%k)-(k=k%5),计算过程: (x=5)-(k=2)→5-2→3。
D项 x%=k-k%5 相当于x=x% (k-k%5),结果同B。
- 下列关于自增运算符++和自减运算符--的叙述中,正确的是( )。
A. 它们的运算对象可以是任意变量和常量。
B. 它们的运算对象可以是char型变量和 int型变量,但不能是float型变量。
C. 它们的运算对象可以是int型变量,但不能是double型变量和float型变量。
D. 它们的运算对象可以是char型变量、int型变量和float型变量。
【答案】 D
【解析】 自增运算符++和自减运算符--只能用于变量,不能用于常量和表达式,但对变量的类型没有限定。