天天看点

嵌入式软件工程师笔试面试指南-问题答疑(持续更新中)

文章目录

    • 为什么-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字节对齐需要填充的字节数。