4.两个int(32位)整数m和n的二进制表达中,有多少个bit位不同?
编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
输入例子:
1999 2299
输出例子:7
方法1:m和n两者分别&1得到其二进制位最低位进行比较
int main() { int m = 0; int n = 0; int i = 0; scanf("%d %d", &m, &n); int count = 0; for (i = 0; i < 32; i++) { if (((m >> i)&1)!= ((n >> i)&1))//这里不能把&1省略了 { count++; } } printf("%d\n", count); return 0; }
把&1是否省略的区别在于:
- 移位之后&1得到的是二进制序列里面的最低位,若没有&1,比较的时候是两个数字本身
- 相对的是有&1,是在比最低位,无,是比较所有位对应的数字
图解:
像这样无论怎么移都count都不会++的,因为它们不是全部bit位对应相等
方法2:异或之后使用:n=n&(n-1)
#include<stdio.h> int main() { int m = 0; int n = 0; int i = 0; scanf("%d %d", &m, &n); int count = 0; //异或 - 相同为0,相异为1 //010 //001 //011 int ret = m ^ n;//m和n不同的bit位会得到结果二进制的1 while (ret)//这里是为了得到1所消失的次数,1消失了几次,就说明有几个1,而1又是区分不同bit位的标志 { ret = ret & (ret - 1); count++; } printf("%d\n", count); return 0; }
思想:如何判断一个数是不是 2 的幂次方?
🚀🚀🚀
2 的幂次方 的数:二进制中只有1个1
2 - 10
4 - 100
8 - 1000
...
n&(n-1) == 0
当&的结果为0,可以证明这个数就是2^n数
反例:
3
👇
0011
0010--结果为0010,不是2^n数
算术转换
1.编译器导致结果差异
下面代码的结果是:10 or 12?
#include <stdio.h> int main() { int i = 1; int ret = (++i)+(++i)+(++i); printf("ret = %d\n", ret); return 0; }
答:程序错误
原因:在vs环境底下是12,在gcc环境底下是10
2.sizeof的返回值类型
下面代码的结果是:
#include <stdio.h> int i; int main() { i--; if (i > sizeof(i)) { printf(">\n"); } else { printf("<\n"); } return 0; }
3.有序数列的合并
注意:是有序数组
#include<stdio.h> int main() { int n = 0; int m = 0; scanf("%d %d", &n, &m); int arr1[n]; int arr2[m]; int arr3[n + m]; int i = 0; for (i = 0; i < n; i++) { scanf("%d", &arr1[i]); } for (i = 0; i < m; i++) { scanf("%d", &arr2[i]); } i = 0; int j = 0; //遍历arr2数组 int k = 0; //放到第三个数组中去 while (i < n && j < m) { if (arr1[i] < arr2[j]) { arr3[k] = arr1[i]; i++; k++; } else { arr3[k] = arr2[j]; j++; k++; } } if (i == n) { for (; j < m; j++) { arr3[k] = arr2[j]; k++; } } if (j == m) { for (; i < n; i++) { arr3[k] = arr1[i]; k++; } } for (k = 0; k < n + m; k++) { printf("%d ", arr3[k]); } }
图解:
执行:
4.小乐乐走台阶
#include<stdio.h> int Upstairs(int n) { if (n == 1) return 1; else if (n == 2) return 2; else return Upstairs(n - 1) + Upstairs(n - 2); } int main() { int n; scanf("%d", &n); int ret=Upstairs(n); printf("%d", ret); return 0; }
跟青蛙跳台阶类似
5.变种水仙花
#include <stdio.h> #include<math.h> int main() { int i = 0; int n = 0; //sum定义的时候不能放在循环最外层循环外面,因为每次再回到j循环那sum没有得到重置,导致程序错误 for (i = 10000; i < 99999; i++) { int j = 0; int sum = 0; for (j = 1; j <= 4; j++) { n = (int)pow(10, j);//pow函数返回的是double类型,所以需要强制转换成int sum = sum + (i / n) * (i % n); } if (sum == i) { printf("%d ", sum); } } }
6.三角形的判断
#include <stdio.h> int main() { int a = 0; int b = 0; int c = 0; while (scanf("%d %d %d", &a, &b, &c) == 3) { if (a + b > c && a + c > b && b + c > a)//这里先把判断三角形的条件写在最外层循环,那么在内层循环就不用都添加这个条件了 { if (a == b && a == c && b == c)//等边 { printf("Equilateral triangle!\n"); } else if ((a == b && a != c) || (a == c && a != b) || (b == c && b != a))//等腰 { printf("Isosceles triangle!\n"); } else//普通三角形 { printf("Ordinary triangle!\n"); } } else { printf("Not a triangle!\n"); } } return 0; }