天天看點

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

這篇部落客要介紹移位操作符與位操作符,在介紹這兩個操作符之前,先簡要講一下了解這兩個操作符需要的基礎知識——也就是二進制和原反補碼!

1.進制

進制是人為規定的一種進位方法,有很多種。比如,我們日常使用的數字即為十進制。十進制逢十進一,所有數字均由0-9組成。八進制逢八進一,所有數字均由0-7組成。二進制逢二進一,所有數字均由0、1組成。十六進制逢十六進一,所有數字由0-9,a-f組成。

在日常生活中也有很多進制的例子,例如星期,逢七進一,七進制;月份逢十二進一,十二進制;小時數,逢二十四進一,二十四進制。

而計算機是一個二進制系統,資料在計算機中以二進制的形式儲存。

2.整數的二進制表示

整數的二進制表示有三種,分别為原碼、補碼與反碼。正整數的原碼、補碼與反碼相同,而負整數的原碼、補碼與反碼是需要計算的。

整數在記憶體中一般以int類型存儲,int類型資料在記憶體中占四個位元組,32個比特位,即32個二進制位。

原碼是根據整數直接寫出的序列。值得注意的是,二進制序列的最高位是符号位,0代表是正數,1代表是負數。

例如:7。

7的原碼很簡單可以寫出:00000000 00000000 00000000 00000111

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

由于7為正整數,7的反碼、補碼與原碼相同。

例如:-7

由于-7為負數,是以-7二進制序列的符号位為1,即二進制序列的最高位為1。

是以,-7的原碼為:10000000 00000000 00000000 00000111

負數的補碼與反碼是需要計算的。

反碼:原碼的符号位不變,其他位按位取反即為反碼。

按位取反:每一個二進制位,原值為0,則改為1;原值為1,則改為0。

是以,-7的反碼:11111111 11111111 11111111 11111000

補碼:反碼加1即為補碼。

是以,-7的補碼:11111111 11111111 11111111 11111001

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

而整數在記憶體中是以補碼存儲的!!!

至此,基礎的小知識就說完啦!

3.移位操作符

移位操作符移的就是我們上文所講的二進制位!

移位操作符分為(<<)左移操作符和(>>)右移操作符。

注意:1.移位操作符的操作對象隻能為整數!

           2.對于移位操作符,不要移動負數位(eg. int b=a>>-1),這個是标準未定義的,不同的編譯器下可能會産生不同的結果。

1.左移操作符

左移操作符:左邊丢棄,右邊補0(操作對象為在記憶體中存儲的補碼)。

例如,

int main()
{
	int a = 7;
	int b = a << 1;

	printf("a = %d\n", a);
	printf("b = %d\n", b);

	return 0;
}
           

a左移1位指派給b,即下圖:

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

是以,代碼輸出結果為:

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

a左移一位後,a本身不會發生變化,隻會将左移一位後所得的值指派給b。

左移之後,之前的二進制碼均高了一位。是以,<<1其實有乘二的效果!

但它與乘2不同的是:<<1不會出現溢出現象,而某一個數字直接乘2所得的值可能會超過int型的範圍,産生溢出現象!

2.右移操作符

右移操作符有兩種移位規則,分别為邏輯移位與算術移位。

邏輯移位:左邊用0填充,右邊丢棄。

算術移位:左邊用該原值的符号位填充,右邊丢棄。

通常編譯器中采用的是算術移位!

右移一位相當于将這個數除以2!

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

 是以,-7右移一位後補碼為:11111111 11111111 11111111 11111100

補碼減1後得反碼,即:11111111 11111111 11111111 11111011

除符号位按位取反得原碼,即:10000000 00000000 00000000 00000100

是以,-7右移一位後得-4。

代碼及輸出結果為:

進制、原反補碼、移位操作符與位操作符~~~1.進制2.整數的二進制表示3.移位操作符 4.位操作符5.位操作符與移位操作符的幾個應用完結撒花!!!

 同樣,a右移一位後,a本身不會發生變化,隻會将右移一位後所得的值指派給b。

 4.位操作符

位操作符中的位同樣為二進制位!同時,位操作符操作數必須為整數!

位操作符有以下三種:

&:按位與

|:按位或

^:按位異或

1.按位與&

兩數的補碼對應二進制位均為1時,為1;有0時,則為0。

2.按位或

 兩數的補碼對應二進制位均為0時,為0;有1時,則為1。

3.按位異或

兩數的補碼對應二進制位相同為0,相異為1。

按位異或有如下特點:

1. a^a=0;

2. 0^a=a;

3.按位異或運算支援交換律。例如:3^3^4=3^4^3=4。

4.按位異或應用

下面說明了按位異或的兩個基本小應用。

1.翻轉特定的二進制位

例如:

若想将a的第二位與第四位翻轉,可以将a與00001010(前三個位元組省略了)進行按位異或。

2.在不使用臨時變量的情況下,交換兩個變量的值。

 例如:

#include <stdio.h>

int main()
{
	int a = 3;
	int b = 5;
	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;
}
           

a首先被指派為3^5,b=a^b=3^5^5=3,a=a^3=3^5^3=5,至此完成兩個變量值的交換。

5.位操作符與移位操作符的幾個應用

1.統計二進制位中1的個數

//統計二進制中1的個數
#include <stdio.h>

int main()
{
	int num = 0;
	int i = 0;
	int sum = 0;
	printf("請輸入一個數字:->");
	scanf("%d", &num);
	for (i = 0; i < 32; i++)
	{
		sum += (num >> i) & 1;
	}
	printf("%d中二進制中1的個數為%d\n",num,sum);

	return 0;
}
           

2.列印二進制位的奇數位和偶數位

#include <stdio.h>

int main()
{
	int num = 0;
	int i = 0;
	printf("請輸入一個整數:->");
	scanf("%d", &num);
	for (i = 31; i >=0; i -= 2)
	{
		printf("%d", (num>>i) & 1);
	}
	printf("\n");
	for (i = 30; i>=0; i -= 2)
	{
		printf("%d", (num >> i) & 1);
	}
	printf("\n");

	return 0;
}
           

3.求兩個數二進制位不同的個數

//求兩個數二進制中不同位的個數
#include <stdio.h>

int main()
{
	int num1 = 0;
	int num2 = 0;
	int ret = 0;
	int i = 0;
	int sum = 0;
	printf("請輸入兩個整數:->");
	scanf("%d %d", &num1, &num2);
	ret = num1 ^ num2;
	for (i = 1; i <= 32; i++)
	{
		sum += ret & 1;
		ret >>= 1;
	}
	printf("%d", sum);
	return 0;
}
           

完結撒花!!!

繼續閱讀