天天看點

嵌入式軟體工程師筆試面試指南-問題答疑(持續更新中)

文章目錄

    • 為什麼-n=~ (n-1)=~ n+1?
      • 解答
    • 結構體所占位元組數
      • 解答
鑒于有些問題,大家有些疑惑。我會把大家問到的問題,整理在這個文章中,友善大家觀看。

為什麼-n=~ (n-1)=~ n+1?

解答

該問題來源于嵌入式軟體開發面試知識點總結P141(舊版本的,估計很多人手中應該沒有這個版本)。

原問題為:不用除法操作符如何實作兩個正整數的除法。

嵌入式軟體工程師筆試面試指南-問題答疑(持續更新中)

粉絲的疑問在于表達式-n=~ (n-1)=~ n+1 。解決這個問題的核心在于,要知道計算機中是如何存儲數值的。

在計算機系統中,數值一律用補碼來表示(存儲)。主要原因是使用補碼可以将符号位和其他位統一處理;同時,減法也可以按加法來處理。另外,兩個用補碼表示的數相加時,如果最高位(符号位)有進位,則進位被舍棄。

如何求補碼呢?

  1. 正數的補碼

    與原碼相同。

    +9的補碼是00001001。

  2. 負數的補碼

    對其原碼逐位取反,但符号位除外;然後整個數加1。

    -7的原碼為10000111,按位取反為11111000,加1可得11111001。是以-7的補碼是11111001。

補碼表示方式有很多,以上兩個例子都是使用8位的2進制來表示的。此外,還有16位2進制補碼表示形式,以及32位2進制補碼表示形式等。

如何快速求補碼?

從最低位開始至找到的第一個1均不變,符号位不變,這之間的各位“求反”(0變1;1變0)。

原碼:1010 1001 補碼:1101 0111。

舉例

下面,我們舉個例子驗證下上面的等式。假設n = 10,則可以得到下面的各個表達式。

n:10 = 00001010
-n:-10 = 11110110
n-1:9 = 00001001
~(n-1):-10 = 11110110
~n:-11 = 11110101
~n+1 = 11110110
           

代碼驗證

算的對不對呢?可以寫個代碼驗證下。

#include <stdlib.h>
#include <stdio.h>

int PrintBinary(int bi,int len){
	
	int i=0;
	while(i<len){

		int tmp = 1;
		//從最左位開始比較,該位是1
		if((bi & (tmp<<(len-i-1))) != 0){
			printf(" 1 ");
		}
		else{
			printf(" 0 ");
		}
		i++;   
	}
	printf("\n");
        return 0;
}

int main()
{
    int n = 10;
    printf("n=%d\n",n);
	PrintBinary(n,8);
    printf("-n=%d\n",-n);
	PrintBinary(-n,8);
    printf("n-1=%d\n",n-1);
	PrintBinary(n-1,8);
    printf("~(n-1)=%d\n", ~(n-1));
	PrintBinary(~(n-1),8);
    printf("~n=%d\n", ~n);
	PrintBinary(~n,8);
    printf("~n+1=%d\n", ~n+1);
	PrintBinary(~n+1,8);
    return 0;
}
           

結果如下。

n=10
 0  0  0  0  1  0  1  0
-n=-10
 1  1  1  1  0  1  1  0
n-1=9
 0  0  0  0  1  0  0  1
~(n-1)=-10
 1  1  1  1  0  1  1  0
~n=-11
 1  1  1  1  0  1  0  1
~n+1=-10
 1  1  1  1  0  1  1  0
           
常用的位運算技巧
  1. -n=~ (n-1)=~ n+1
  2. 擷取整數n的二進制中最後一個1:n&(-n)或者n&~(n-1)。例如,n=010100,則-n=101100,n&(-n)= 000100。
  3. 去掉整數n的二進制中最後一個1:n&(n-1),如n=010100,n-1=010011,n&(n-1)=010000。

結構體所占位元組數

該問題來源于嵌入式軟體開發面試知識點總結P150(舊版本的,估計很多人手中應該沒有這個版本)。

原問題為:指針進行強制類型轉換後與位址進行加法運算,結果是什麼?

嵌入式軟體工程師筆試面試指南-問題答疑(持續更新中)
struct BBB
{
  long num;
  char *name;
  short int data;
  char ha;
  short ba[5];
}*p;
           

在32位機器下, sizeof(struct BBB)=24。但是粉絲算的是28。

解答

char 指針變量 short int int unsigned int float double long long long unsigned long
32位 1 4 2 4 4 4 8 4 8 4
64位 1 8 2 4 4 4 8 8 8 8

這位粉絲估計是把資料類型所占位元組數記錯了。

對于32位系統:4+4+2+1+(1)+10+(2)=24

對于64位系統:8+8+2+1+(1)+10+(2)=32

括号中的數字,表示的是為了保證4位元組對齊需要填充的位元組數。