移位运算具体实现有3种方式: 循环移位、逻辑移位、算术移位(带符号)。 (1)循环移位:在循环移位中,移入的位数等于移出的位数。
(2)逻辑移位:在逻辑移位中,移出的位丢失,移入的位取0。
(3)算术移位:在算术移位(带符号)中,移出的位丢失,左移入的位取0,右移入的位取符号位,即最高位代表数据符号,保持不变。
C语言中的移位运算方式与具体的C语言编译器有关,通常实现中,左移位运算后右端出现的空位补0,移至左端之外的位则舍弃;右移运算与操作数的数据类型是否带有符号位有关,不带符号位的操作数右移位时,左端出现的空位补0,移至右端之外的位则舍弃,带符号位的操作数右移位时,左端出现的空位按符号位复制,其余的空位补0,移至犹端之外的位则舍弃。
例如,假设 a = 58(10) = 72(8)=00111010(2),a << 2的值为: 00111010 00 = 11101000(2) = 350(8)=232 (10)= 58*4
在数据可表达的范围里,一般左移1位相当于乘2,作移2位相当于乘4。 同样,假设 a = 58(10) = 00111010(8),a >> 1的值为: 0 00111010 = 00011101 (2) = 35(8) = 29 (10) = 58/2 一般右移1位相当于除2,右移2位相当于除4。 再次提醒:操作数的移位运算并不改变原操作数的值。即经过上述移位运算,a仍为58,除非通过赋值 a = a >> 2,改变a的值。
复合位赋值运算符就是在赋值运算符 = 前加上位运算符。
5.5.8 其它运算
1、长度运算
长度运算符sizeof是一个单目运算符,用来返回变量或数据类型的字节长度。使用长度运算符可以增强程序的可移植性,使之不受具体计算机数据类型长度的限制。
例如,设a是整形变量,则sizeof(a)求整型变量a的长度,值为4(bytes),sizeof(int)求整型的长度,值为4(bytes),sizeof(double)求双精度浮点型的长度,值为8(bytes)。 2、特殊运算符
C语言中,还有一些比较特殊的、具有专门用途的运算符。例如: (1)( )括号:用来改变运算顺序
(2)[ ] 下标:用来表示数组元素,祥见下一章 (3)* 和 & : 与指针运算有关,祥见第7章 (4)-> 和 . :用来表示结构分量,祥见第8章 3、运算符的优先级与结合
C语言中,运算符共分15个优先级,分别用1~15来表示,1表示优先级最高,15表示优先级最低。
C语言中运算符的结合性分两类,左结合(从左到右)和右结合(从右到左)。单目运算符、双目运算符和赋值运算符的结合性是从右到左,其它运算符的结合性是从左到右。
5.5.9 程序解析
例5.10 输入一行字符,将其中的大写字母转换为相应的小写字母后输出,小写字母转换为相应的大写字母后输出,其它字符按原样输出。
21
输入一行字符,就是输入以回车符 ? \\ n ?结束的一批字符,即以? \\ n ?作为循环的结束标志,大小写字母的判断和转换用else-if语句实现。 #include
printf(\ ch = getchar(); while(ch!='\\n') {
if(ch>='A'&&ch<='Z') // 如果ch是大写字母 ch = ch - 'A' + 'a'; // 大写字母转换为小写字母 else if(ch >= 'a' && ch <='z') // 如果ch是小写字母 ch = ch - 'a' + 'A'; // 小写字母转换为大写字母 putchar(ch); // 输出转换后的字符 ch = getchar(); // 读入下一个字符 }
printf(\}
运行结果:input characters: Reold 123? rEOLD 123? 程序还可以写成: #include
printf(\
while((ch = getchar()) != '\\n') //直到输入回车为止 {
if(ch>='A'&&ch<='Z') //如果ch是大写字母 ch = ch - 'A' + 'a'; //大写字母转换为小写字母 else if(ch >= 'a' && ch <='z') //如果ch是小写字母 ch = ch - 'a' + 'A'; //小写字母转换为大写字母 putchar(ch); //输出转换后的字符 }
printf(\}
运行结果:input characters: Reold 123? rEOLD 123?
其中( ch = getchar()) != ?\\n?是一个关系表达式,运算符 != 的左侧是赋值表达式。运算时,先计算赋值表达式( ch = getchar()),把输入的字符赋给变量ch,同时该赋值表达式的值就是变量ch的值;然后再和 ? \\ n ? 比较。这样,用一个表达式就实现了输入和比较两种运算。
( ch = getchar() ) != ? \\n ? 和 ch = getchar() != ? \\ n ? 不等价
因为赋值运算符=的优先级低于关系运算符 !=,所以不能省略 ( ch = getchar() ) != ? \\ n ? 中的括号。表达式 ch = getchar() != ? \\ n ?等价于 ch = ( getchar() != ? \\ n ? ),它是一个赋值表达式,运算时,先计算关系表达式getchar() != ? \\ n ?,其值是0或1,再赋给ch。故ch中存放的不是输入的字符,而是关系运算的结果0或1。
22
练 习:
(1)a && ( b || c )等价于 a && b || a && c (2)a || ( b && c )等价于 ( a || b ) && ( a || c ) (3)! ( a && b )等价于 ! a || !b (4)! ( a || b )等价于 ! a && ! b
(5)输入一行字符,统计出其中的英文字母、空格、数字和其他字符的个数
(6)输入一行字符,统计其中单词的个数。各单词之间用空格分隔,空格数可以是多个
23