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

本文整理了嵌入式软件工程师面试中常见问题,包括-n=~(n-1)=~n+1的补码运算解释,以及结构体占用字节数的计算,涉及位运算技巧和内存对齐。通过实例代码验证了位运算的正确性,并指出结构体在不同系统下的字节布局差异。
摘要由CSDN通过智能技术生成

鉴于有些问题,大家有些疑惑。我会把大家问到的问题,整理在这个文章中,方便大家观看。

为什么-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 intintunsigned intfloatdoublelonglong longunsigned long
32位1424448484
64位1824448888

这位粉丝估计是把数据类型所占字节数记错了。

对于32位系统:4+4+2+1+(1)+10+(2)=24

对于64位系统:8+8+2+1+(1)+10+(2)=32

括号中的数字,表示的是为了保证4字节对齐需要填充的字节数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式与Linux那些事

您的鼓励将使我写出更好的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值