這里寫目錄標題
- 例題一
- 題目解析
- 例題二
- 題目解析
- 例題三
- 方法一
- 方法二
- 方法三
- 例題四
- 例題五
感謝各位大佬對我的支持,如果我的文章對你有用,歡迎點擊以下鏈接
🐒🐒🐒 個人主頁
🥸🥸🥸 C語言
🐿?🐿?🐿? C語言例題
🐣🐓🏀 python
例題一
下面代碼的結果是:( )
#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;
}
A.a = 8 b = 23 c = 8
B.a = 9 b = 23 c = 8
C.a = 9 b = 25 c = 8
D.a = 9 b = 24 c = 8
答案 B
題目解析
c=++a是先執行++a,也就是a=a+1=6(注意這里是永久改變a的值),然后再執行c=a=6
b=++c,c++,++a,a++這里要注意對于b我們是只算b=++c,所以先執行c=c+1=7
b=c=7,然后再執行后面的c++,++a,a++(后面還是會執行的,只不過和b就沒關系了),最終c=8.a=8
b+=a++ +c先變成b=b+a++ +c再執行a=a+1=9,b=b+a+c=7+8+8=23
最終a=9 b=23 c=8
例題二
不允許創建臨時變量,交換兩個整數的內容
題目解析
我們需要用到按位異或的方法去解決,按位異或在之前我有寫到操作符詳解上(非常詳細)
#include <stdio.h>
int main()
{int a = 10;int b = 20;printf("交換前:a = %d b = %d\n", a,b);a = a^b;b = a^b;a = a^b;printf("交換后:a = %d b = %d\n", a,b);return 0;
}
按位異或就是相同為0不同為1,并且滿足數學的交換規律
對于
一式a=a^b ,二式b=a^b, 三式a=a^b
我們將一式帶入二式,b=a^ b^b,由于b ^b=1,那么最后b=a
而三式a=a^b其實就是a=a ^b ^a,其中a ^b是一式帶入的,利用交換律我們就可以變成a=a ^a ^b,所以最后a=b
例題三
統計二進制中1的個數
代碼解析:
方法一
*/
int NumberOf1(int n)
{int count = 0;while(n){if(n%2==1)count++;n = n/2;//每次除2然后循環判斷}return count;
}
/*
上述方法缺陷:進行了大量的取模以及除法運算,取模和除法運算的效率本來就比較低。
我們看看另外一個思路
一個int類型的數據,對應的二進制一共有32個比特位,可以采用位運算的方式一位一位的檢測,具體如下
方法二
*/
int NumberOf1(unsigned int n)
{int count = 0;int i = 0;for(i=0; i<32; i++){if(((n>>i)&1) == 1)count++;}return count;
}int NumberOf1(int n ) {int j=0;for(int i=1;i<=32;i++){if(n%2)//如果n%2為1就代表個位是1(這里不用判斷十位百位){n=n>>1;j++;}else(如果個位是0就直接右移)n=n>>1;}printf("%d",j);return j;
}/*優點:用位操作代替取模和除法運算,效率稍微比較高缺陷:不論是什么數據,循環都要執行32次
方法三
思路:采用相鄰的兩個數據進行按位與運算
舉例:?
第一次循環:n=9999
n=n&(n-1)=9999&9998=9998
(10 0111 0000 1111)
(10 0111 0000 1110)
=(10 0111 0000 1110)
第二次循環:n=9998 n=n&(n-1)=9998&9997= 9996(10 0111 0000 1110) (10 0111 0000 1101) =(10 0111 0000 1100)
第三次循環:n=9996
n=n&(n-1)=9996&9995= 9992
(10 0111 0000 1100)
(10 0111 0000 1011)
=(10 0111 0000 1000)
第四次循環:n=9992
n=n&(n-1)=9992&9991= 9984
(10 0111 0000 1000)
(10 0111 0000 0111)
=(10 0111 0000 0000)
第五次循環:n=9984
n=n&(n-1)=9984&9983= 9728
(10 0111 0000 0000)
(10 0110 1111 1111)
=(10 0110 0000 0000)
第六次循環:n=9728
n=n&(n-1)=9728&9727= 9216
(10 0110 0000 0000)
(10 0101 1111 1111)
=(10 0100 0000 0000)
第七次循環:n=9216
n=n&(n-1)=9216&9215= 8192
(10 0100 0000 0000)
(10 0011 1111 1111)
=(10 0000 0000 0000)
第八次循環:n=8192
n=n&(n-1)=8192&8191= 0
(10 0000 0000 0000)
(01 1111 1111 1111)
=(00 0000 0000 0000)可以觀察到:此種方式,數據的二進制比特位中有幾個1,循環就循環幾次
而且中間采用了位運算,處理起來比較高效
*/
int NumberOf1(int n)
{int count = 0;while(n){n = n&(n-1);count++;}return count;
}
例題四
打印整數二進制的奇數位和偶數位
代碼解析:
/*
思路:
1. 提取所有的奇數位,如果該位是1,輸出1,是0則輸出0
2. 以同樣的方式提取偶數位置檢測num中某一位是0還是1的方式:1. 將num向右移動i位2. 將移完位之后的結果與1按位與,如果:結果是0,則第i個比特位是0結果是非0,則第i個比特位是1
*/
void Printbit(int num)
{for(int i=31; i>=1; i-=2){printf("%d ", (num>>i)&1);}printf("\n");for(int i=30; i>=0; i-=2){printf("%d ", (num>>i)&1);}printf("\n");
}
例題五
求兩個數二進制中不同位的個數
#include <stdio.h>int main() {int a, b,sum=0;scanf("%d %d",&a,&b);for(int i=0;i<32;i++){int c=a>>i; int d=b>>i;if((c&1)==(d&1))判斷個位是否相同;elsesum++;}printf("%d",sum);return 0;
}
/*
思路:
1. 先將m和n進行按位異或,此時m和n相同的二進制比特位清零,不同的二進制比特位為1
2. 統計異或完成后結果的二進制比特位中有多少個1即可
*/
#include <stdio.h>
int calc_diff_bit(int m, int n)
{int tmp = m^n;//找出相同的位int count = 0;while(tmp){tmp = tmp&(tmp-1);//和上一題的方法三相同count++;}return count;
}
int main()
{int m,n;while(scanf("%d %d", &m, &n) == 2){printf("%d\n", calc_diff_bit(m, n));}return 0;
}