目錄
- 二進制介紹
- 二進制
- 2進制轉10進制
- 10進制轉2進制數字
- 2進制轉8進制和16進制
- 2進制轉8進制
- 2進制轉16進制
- 原碼、反碼、補碼
- 移位操作符
- 左移操作符
- 右移操作符
- 位操作符:&、|、^
- 逗號表達式
二進制介紹
在初學計算機時我們常常會聽到2進制、8進制、10進制、16進制…這些聽著非常高級的詞語,其實8進制、10進制、16進制幾乎和2進制非常相似,只是稍微有一些不同,下面我們對這些進行較詳細的介紹
二進制
我們舉一個例子,比如用不同進制形式來表示數值15:
15的2進制:1111
15的8進制:17
15的10進制:15
15的16進制:F
我們還是先從熟悉的10進制開始講解:
在我們學過的加減法中我們常常用這樣的方式進行計算:
由于個位數字相加滿10于是向十位數進1,而十位數也滿十于是向百位數進1
因此我們從這里可以得知,所謂的十進制其實是滿10進1,并且每位數字是不能超過10的
其實其他進制也相同,比如2進制
?2進制為滿2進1
?2進制的數字每?位都是0~1的數字組成
所以1011就是15的二進制數了
2進制轉10進制
10進制的123表示的值是?百二十三,為什么是這個值呢?其實10進制的每一位是權重的,10進制的數字從右向左是個位、十位、百位…,分別每一位的權重是10^0 , 10^1 , 10^2 …
如下圖:
2進制和10進制是類似的,只不過2進制的每?位的權重,從右向左是:2^0 , 2^1 , 2 ^2…
如果是2進制的1101,該怎么理解呢?
10進制轉2進制數字
方法如圖:
我們只需要對125不斷的除2即可得到125在2進制中的數字(其實這里我還沒有完全理解為什么這樣就可以得出結果,所以后期如果我想通了會在這里加上自己的理解)
2進制轉8進制和16進制
2進制轉8進制
8進制的數字每一位是0~ 7的,0~7的數字,各自寫成2進制,最多有3個2進制位就足夠了,比如7的二進制是111,所以在2進制轉8進制數的時候,從2進制序列中右邊低位開始向左每3個2進制位會換算?個8進制位,剩余不夠3個2進制位的直接換算
如:2進制的01101011,換成8進制:0153,0開頭的數組,會被當做8進制
2進制轉16進制
16進制的數字每?位是0~ 9,a~ f(10~15 )的數字,各自寫成2進制,最多有4個2進制位就足夠了
比如f的二進制是1111,所以在2進制轉16進制數的時候,從2進制序列中右邊低位開始向左每4個2進制位會換算?個16進制位,剩余不夠4個二進制位的直接換算
如:2進制的01101011,換成16進制:0x6b,16進制表示的時候前面加0x
原碼、反碼、補碼
整數的2進制表示方法有三種,即原碼、反碼和補碼
三種表示方法均有符號位和數值位兩部分,符號位都是用0表示“正”,用1表示“負”,而數值位最高位的?位是被當做符號位,剩余的都是數值位。
正整數的原、反、補碼都相同。
負整數的三種表示方法各不相同。
原碼:直接將數值按照正負數的形式翻譯成二進制得到的就是原碼。
反碼:將原碼的符號位不變,其他位依次按位取反就可以得到反碼。
補碼:反碼+1就得到補碼
對于整形來說:數據存放內存中其實存放的是補碼
因為在計算機系統中,數值?律用補碼來表示和存儲。原因在于,使用補碼,可以將符號位和數值域統?處理同時,加法和減法也可以統?處理(CPU只有加法器)此外,補碼與原碼相互轉換,其運算過程是相同的,不需要額外的硬件電路
移位操作符
操作符號如下:
<<左移操作符
>>右移操作符
注:移位操作符的操作數只能是整數(因為原碼、反碼、補碼中提到的是整數的2進制,如果是小數的話不能表示)(但是我記得好像有小數表示的方法只不過不知道能不能用在這里,可能是我沒搞清楚)
左移操作符
右移操作符
移位規則:首先右移運算分兩種:
1.邏輯右移:左邊用0填充,右邊丟棄
2.算術右移:左邊用原該值的符號位填充,右邊丟棄
特別提醒:對于移位運算符,不要移動負數位,這個是標準未定義的(而且也沒有必要這樣)
比如:
int num = 10;
num>>-1;//error
位操作符:&、|、^
位操作符有:
1.& //按位與 對應位同時為“1”時才為“1”,否則為0
2.| //按位或 對應位只要有一個為1就為1
3.^ //按位異或 對應位相同為 0,不同為 1。
注:他們的操作數必須是整數
代碼如下:
#include <stdio.h>
int main()
{int num1 = -3;int num2 = 5;num1 & num2;num1 | num2;num1 ^ num2;
return 0;
}
下面有?道面試題:
不能創建臨時變量(第三個變量),實現兩個數的交換
法一:
可能有很多人都會這樣做
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a+b;
b = a-b;
a = a-b;
printf("a = %d b = %d\n", a, b);
return 0;
}
這種做法有一個缺陷,就是如果a+b過大就會導致出錯,因為int有范圍限制,所以這種方法也要分情況用
我們看看法二:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;
a = a^b;
printf("a = %d b = %d\n", a, b);
return 0;
}
這種方法就很難想到了,但是也有缺陷,就是如果是有負數的話,結果就會有問題,因此這方法僅適用于正數
例題:編寫代碼實現:求?個整數存儲在內存中的二進制中1的個數:
//?法1
#include <stdio.h>
int main()
{
int num = 10;
int count= 0;//計數
while(num)
{
if(num%2 == 1)
count++;
num = num/2;
}
printf("?進制中1的個數 = %d\n", count);
return 0;
}
//?法2:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//計數
for(i=0; i<32; i++)
{
if( num & (1 << i) )
count++;
}
printf("?進制中1的個數 = %d\n",count);
return 0;
}
//?法3:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//計數
while(num)
{
count++;
num = num&(num-1);
}
printf("?進制中1的個數 = %d\n",count);
return 0;
}
逗號表達式
逗號表達式,就是用逗號隔開的多個表達式。
逗號表達式,從左向右依次執行。整個表達式的結果是最后一個表達式的結果。(如果左邊表達式為假就不用執行右邊的表達式了)
//代碼1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗號表達式
//代碼2
if (a =b + 1, c=a / 2, d > 0)
while (a = get_val(), count_val(a), a>0)
{
..........
}