知识点
先上运算符优先级的图
位运算符
| 运算符 | 含义 | 优先级 |
|---|---|---|
| ~ | 按位取反 | 1(高) |
| << | 左移 | 2 |
| >> | 右移 | 2 |
| & | 按位与 | 3 |
| ^ | 按位异或 | 4 |
| | | 按位或 | 5(低) |
1.按位取反
运算符~时位运算符中唯一的单目运算符,运算对象应置于运算符的右边,其运算功能是把运算对象的内容按位取反,就用来对一个二进制数按位取反,每一位上的0变1,1变0。
#include <stdio.h>
#include <stdlib.h>
void toTwo(int a){
char s[40];
itoa(a,s,2); //itoa为转二进制的函数,具体内容暂时不需在意
printf("%s\n",s);
}
int main(){
int a =7;
toTwo(a); //以二进制的形式输出a
a = ~a; //将a按位取反
toTwo(a);
return 0;
}
输出结果:
111
11111111111111111111111111111000
由于前几位的0 被省略,我给他补上,能看的明确一些
00000000000000000000000000000111
11111111111111111111111111111000
2.左移
左移运算符是双目运算符。运算符左边是位移对象,右边是整型表达式,代表左移的位数。用来将一个数的各二进制位全部左移N位,右端(低位)补0。
打个比方:
将00001111左移2位,右边空出的位补0,左边溢出的位舍弃。得到00111100。
#include <stdio.h>
#include <stdlib.h>
void toTwo(int a){ //toTwo函数接下来不再重复写了
char s[40];
itoa(a,s,2); //itoa为转二进制的函数,具体内容暂时不需在意
printf("%s\n",s);
}
int main(){
int a = 63;
toTwo(a); //以二进制的形式输出a
int b = a<<1;
toTwo(b);
int c = a<<2;
toTwo(c);
return 0;
}
输出结果:
111111
1111110
11111100
3.右移
右移运算符的使用方法与左移运算符一样,所不同的而是移位方向相反。(暂不考虑负数的右移)
右
int main(){
int a = 63;
toTwo(a); //以二进制的形式输出a
int b = a>>1;
toTwo(b);
int c = a>>2;
toTwo(c);
return 0;
}
输出结果:
111111
11111
1111
4.按位与
运算符 &的作用是吧:参加运算的两个运算符按对应的二进制位分别进行"与"运算,运算方式为:当两个相应的位都为1时,该位的结果为1;否则结尾零。·
4.按位与
运算符 &的作用是吧:参加运算的两个运算符按对应的二进制位分别进行"与"运算,运算方式为:当两个相应的位都为1时,该位的结果为1;否则为 0。
int main(){
int a = 57;
toTwo(a); //以二进制的形式输出a
int b = 45;
toTwo(b);
int c = a & b;
toTwo(c);
return 0;
}
输出结果
111001
101101
101001
5.按位异或
按位异或的规则是,参与运算的两个运算数中相应的二进制位上:
- 若数相同:结果为0 ( 比如都是0,或者都是1)
- 若数不同:结果为1(比如一个是1,一个是0)
int main(){
int a = 57;
toTwo(a); //以二进制的形式输出a
int b = 45;
toTwo(b);
int c = a ^ b;
toTwo(c);
return 0;
}
结果:
111001
101101
10100
注意:结果是中的c 的最前面的 0 省略了,让我们理解更容易我们把她加上:
111001
101101
010100
6.按位或
运算规则是,参与运算的两个运算数中:
- 只要两个相应的二进制位中有一个为1,该位的运算结果即为1
- 只有当两个相应为的数都为0时,该位的运算结果才位0
int main(){
int a = 58;
toTwo(a); //以二进制的形式输出a
int b = 42;
toTwo(b);
int c = a | b;
toTwo(c);
return 0;
}
输出结果:
111010
101010
111010
习题
1.字符串s 的长度是()
char s = "\"1\43\n2\x11\" ";
- A 7
- B 8
- C 11
- D 16
解析:本题给出的字符串含有的字符依次是: ’ \’‘ ‘、'1'、’\43'、‘\n’、‘2’、‘\x11’、‘ \‘’ ’
一共是7个字符
2.下列表达式中,值为1的表达式是()
A 3 % 5
B 3 / 5.0
C 3 / 5
D 3 < 5
3.设整型变量a、b均为2,计算经过下列表达式后,a的值为()
b = (a -= 1), a = a != b;
- A. -1
- B. 0
- C. 1
- D. 2
解析:先计算b = (a -= 1), 其中a -= 1 的结果是1,变量a的值是1,所以变量b的值也是1。然后计算 a = a != b,由于"!="优先级高于 ”=“,所以先计算a != b,从前面可知a、b均为1,所以该表达式值为0(假),这个 0 将赋值给变量 a ,所以变量a的值为 0
4.设整型变量 m 的值为0,表达式 !!!+ + m 的值是 ( )
- A. -1
- B. 0
- C. 1
- D. 2
解析:由于 !和 ++ 是同级别的运算符,结合性是自右向左的,所以题目中的表达式相当于 “!(!(!(+ + m) ) ) ” ,以此计算 ++ m 的值为1,!(+ + m)的值为 0,!(!(+ + m) ) 的值为1,!(!(!(+ + m) ) ) 的值为0
5.下列说法中,错误的是
- A.表达式计算中,数据长度短的数据将自动转换乘数据长度长的数据
- B.(int)3.9 + 2.8 的运算结果是整型
- C.字符串的长度不等于字符串在内存中占用的字节数
- D.赋值时的自动转换规则是将右边表达式的数据类型改变为左边变量的类型
解析:强制类型转换时,(数据类型符)仅对气候的单个数据或圆括号括住的表达式进行,即仅对”3.9“进行,转换成整数 3。然后再计算” 3 + 2.8 “,结果是5.8,并不是整型。
6.按照C语言规定的命令规则,不能出现在变量名中的是()
- A.大写字母
- B.连接符
- C.数字字符
- D.下划线
7.以下不合法的数值常量是()
- A.001
- B.1 el
- C.8. 0E05
- D.0xabcd
解析:C语言的语法规定,字母E之前必须有数字,且E后面的指数必须是整数,而选项C中,E后面的指数是小数。
8.设变量已正确定义并赋值,以下正确的表达式是 ()
- A.x = y * 5 = x + z
- B.int (15.8 % 5)
- C.x = y + z + 5 , ++y
- D.x = 25 % 5.0
解析:选项A中等号左边不能为运算式 y * 5 = x + z 错误,选项B 和 D 中,取余运算符的两边必须是整数,错误。
9.以下古纳于long、int、short类型数据占用内存大小的叙述中正确的是()
- A.均占 4 个 字节
- B.根据数据的大小里决定所占用的字节数
- C.由用户自己定义
- D.由C语言编译系统决定
10.若变量均已正确定义并赋值,以下合法的C语言赋值语句是()
- A. x = y == 5;
- B. x = n % 2.5;
- C. x + n = i;
- D. x = 5 = 4 + 1;
解析:D选项,5作为常数,不能出现在表达式的左边。
11.以下选项中,当 x 为大于1的奇数时,值为0的表达式是()
- A. x % 2 = 1
- B. x / 2
- C. x % 2 != 0
- D. x % 2 = 0
解析:x 为大于1 的奇数,所以 x % 2 的值为 1 ,故关系表达式 ”x % 2 = 0 “ 为假,即表达式的值为0
12.若变量 x、y 已正确定义并赋值,以下符合C语言语法的表达式是 ()
- A. ++x, y = x --
- B. x + 1 = y
- C. x = x + 10 = x + y
- D. double(x) / 10
13.有以下程序的运行结果是
int main(){
int y = 9;
for (; y > 0; y--) {
if (y % 3 == 0) {
printf("%d",--y);
}
}
return 0;
}
- A.741
- B.963
- C.852
- D.875421
14.设有定义:int k = 0; 以下选项的四个表达式中与其他三个表达式的值不同的是()
- A. k++
- B. k += 1
- C. ++k
- D. k+1
15.程序运行后的输出结果是()
int main(){
int x, y, z;
x = y = 1;
z = x++, y++, ++y;
printf("%d,%d,%d\n",x,y,z);
return 0;
}
- A. 2,3,3
- B. 2,3,2
- C. 2,311
- D. 2,2,1
解析:z = x ++是先把 x 的值 1 赋给 z,所以 z = 1,然后再把 x + 1 赋给 x,所以x = 2,y++ 后 y = 2,++y 后 y +1所以 y = 3
16.程序执行后的输出结果是
int main(){
int k = 5;
while (--k) {
printf ("%d",k-=3);
}
printf("\n");
return 0;
}
- A.1
- B.2
- C.4
- D.死循环
解析:第一次while判断时 k 已经-- 为 4,执行 k -= 3 后,k 的值为1;下一次while判断时 --k,k的值为0,循环结束。
17.程序执行后的输出结果是
fun(int x, int y) {
return (x + y);
}
int main() {
int a = 1, b = 2, c = 3, sum;
sum = fun((a++, b++, a+b), c++);
printf("%d\n",sum);
return 0;
}
- A.6
- B.7
- C.8
- D.9
解析:c++,先把3赋值给y,y的值为3,然后c自增为4,a++后的值为2,b++后的值为3,a+b的值为5。所以 x 的接收到的值为5,return (3+5),最后返回的值为8,所以 sum为 8
18.变量 a 中的数据用二进制表示的形式是01011101,变量 b 中的数据用二进制表示的形式是 11110000 ,若要求将 a 的高4位取反,低4位不变,所要执行的运算是()
- A. a^b
- B. ab
- C. a&b
- D. a << 4
解析:应当进行异或运算
19.有以下程序
int main(){
int a = 1, b = 2, c = 3, x;
x = (a^b) & c;
printf("%d\n",x);
return 0;
}
运行的结果是 ()
- A. 0
- B. 1
- C. 2
- D. 3
解析:a、b、c的二进制分别为01,10,11
a ^ b = 01 ^ 10 =11
11 & c = 11 & 11 = 11
二进制11 也就是 十进制的3,故x为 3
20.程序的输出结果是()
int main(){
unsigned char a = 2, b = 4, c = 5, d;
d = a | b;
d &= c;
printf("%d\n",d);
return 0;
}
- A.3
- B.4
- C.5
- D.6
解析:d = a | b = 0010 | 0100 = 0110,
d = d & c = 0110 & 0101 = 0100
把二进制 0100 转换为十进制 则为 4 所以最后d的值为 4
21.若变量已正确定义,则以下语句的输出结果是 ()
s = 32;
s^ = 32;
printf("%d",s);
- A. -1
- B. 9
- C. 1
- D. 32
解析:s^= 32,s的值本身就是32,相当于s自身按位异或运算,结果肯定为 0
22.设int a = 10, b = 20, c = 30; 条件表达式 a < b ? a = 5 : c 的值是()
- A.5
- B.10
- C.20
- D.30
23.设有条件表达式(x) ? 1: 2,则和表达式(x) 作用相同的表达式时()
- A.(x == 0)
- B.(x != 0)
- C.(x == 1)
- D.(x != 1)
24.设有宏定义#defint R 2+3 则 R * R 的宏替换结果正确的是()
- A. (2+3) * (2+3)
- B. 2 + 3 * 2 + 3
- C. 5 * 5
- D. 5.0 * 5.0
填空题
1.设整型变量 a 的值为6,b的值为10,则表达式1.0 + a/b的值为()
2.设int 变量 m 的值为 9 ,表达式 m++/2/5的值为()