移位操作符
左移:形式为 << 右移:形式为 >>
#include<stdio.h>
void main() {
int a = 3;
int b = a << 1;
printf("%d" , b);
}
可以看到左移,是在二进制数的基础上进行的;而结果显示的是十进制,这一点不要忽略;同时,需要明确:
- 左移操作符:左边抛弃、右边补0
- 首先右移运算分两种:
2.1.逻辑移位:左边用0填充,右边丢弃 2.2 算术移位:左边用原该值的符号位填充,右边丢弃
位操作符
位操作符包括:按位与(&),按位或(|),按位异或(^),按位取反(~) 位操作符的对象必须是整型!
#include<stdio.h>
void main() {
int a = 3;
int b = 5;
int c = a & b;
int d = a | b;
int e = ~d;
int f = a ^ b;
printf("a b按位与 = %d\n", c);
printf("a b按位或 = %d\n", d);
printf("b按位取反 = %d\n", e);
printf("a b按位异或 = %d\n", f);
}
这路异或比较容易搞混:其代表相同位0 相异为1
下面引入一个思考 :怎样在不创建临时变量的条件下交换两个数 以一段代码来分析:
#include<stdio.h>
void main() {
int a = 3;
int b = 5;
printf("a = %d , b = %d \n",a,b);
int c = a ^ b;
b = c ^ b;
a = c ^ a;
printf("a = %d , b = %d \n", a, b);
}
可以看到两个数异或后的结果,再与其中一个数异或,就会得到另一个数,根据这个规律,就可以后期无脑实现交换两个数的操作。 同时,c = a ^ b; c ^ b =a ; 也就是 a ^ b ^ b =a ; 可以 发现一个数和自己异或就等于0;0和任何整数异或都是整数自己;
sizeof和数组
提前还是需要重点强调的是:sizeof(arr)中的arr代表的是数组名,表示整个数组!而传参过去的arr,不是传了整个数组而是传指针,代表数组首元素的地址!
#include <stdio.h>
void test1(int arr[])
{
printf("%d ", sizeof(arr));
}
void test2(char ch[])
{
printf("%d ", sizeof(ch));
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d ", sizeof(arr));
printf("%d ", sizeof(ch));
test1(arr);
test2(ch);
return 0;
}
}
逗号表达式
逗号表达式,就是用逗号隔开的多个表达式。 逗号表达式,从左向右依次执行。 整个表达式的结果是最后一个表达式的结果。
#include <stdio.h>
int main()
{
int a = 5;
int b = 7;
int c = (a * b, a / b, a - b, a + b);
printf("C 等于 %d\n",c);
return 0;
}
可以看到, “,”表达式只有效最后一个表达式 !
练习题
1. 考察 前置++ 和 后置++
#include<stdio.h>
int main()
{
int a, b, c;
a = 5;
c = ++a;
b = ++c, c++, ++a, a++;
b += a++ + c;
printf("a = %d b = %d c = %d\n:", a, b, c);
return 0;
}
结果如下: 2.写一个函数返回参数二进制中 1 的个数。 比如: 15 0000 1111 4 个 1
#inlucde<stdio.h>
int fun(int input);
void main() {
printf("请输入一个数 用来统计其二进制中1的个数\n");
int input = 0;
int res = 0;
scanf_s("%d", &input);
res = fun(input);
printf("input的二进制数中 1 的个数位:%d " , res);
}
int fun(int input) {
int n = 0;
for (int i = 0; i < 32;i++) {
if (((input >> i) & 1)==1) {
n++;
}
}
return n;
}
|