10 嵌入式软件面试 — 代码检查

10.1 编写代码

问题1:写出float x与“零值”比较的if语句

if(x > -0.000001 && x < 0.000001); 

解读:因为计算机在处理浮点数的时候是有误差的,所以不能将浮点型变量用“==”或“!=”与数字比较,应该设法转化成“>”或“<”此类形式。

问题2:强制类型转换

给了一个地址a,分别强转类型为:int变量、int指针、数组指针、指针数组、函数指针。

(int) a;          //int变量
(int *)a;         //int指针
(int (*)[])a;     //数组指针
(int *[])a;       //指针数组
(int (*)(int))a;  //函数指针

10.2 代码输出

问题3:代码输出1

void foo(void)   
{   
    unsigned int a = 6;   
    int b = -20;   
    (a + b > 6)? printf("> 6") : printf(" <= 6");   
}   

答案:输出是 “>6”。

解读:当运算表达式中存在有符号数和无符号数时,有符号数隐式转换成了无符号数(即底层的补码不变,但是此数从有符号数变成了无符号数)。注意,正数的补码为其本身,负数的补码为其反码+1。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果 ”>6”。

问题4:代码输出2

#include<stdio.h>  
#define N 500  
void main()  
{  
    unsigned char count;  
    for(count = 0; count < N; count++)  
    {  
        printf("---%d---\n", count);  
    }  
}

答案:进入不断打印count值的死循环。

解读:因为unsigned char 类型变量的最大值为255,所以count只能从0一直增加到255,然后又恢复为0,无法退出for循环。

问题5:代码输出3

int foo(void)  
{  
    int i;  
    char c = 0x80;   
    i = c;  
    if(i > 0)  
        return 1;  
    return 2;  
} 

答案:返回值为2。

解读:在C语言中,char 类型是有符号的,所以

0x80 被解释为一个负数,二进制表示为 10000000,最高位是符号位。表示的负数值可以通过以下步骤计算:

首先,将除了最高位之外的其他位取反,得到01111111。然后,将取反后的结果加1,得到10000000,所以为-128。

问题6:给定的位域结构体,它在内存中占用多少字节(32位编译器)?

struct A   
{         
     char t : 4;        // 4位         
     char k : 4;        // 4位         
     unsigned short i : 8;  // 8位               
     unsigned long m;     // 4字节  
}; 

根据结构体内存对齐原则,共占用8字节。

问题7:在32位系统中,有如下结构体,那么sizeof(fun)的数值是?

#pragma pack(1)  
struct fun  
{  
    int i;   // 4字节  
    double d;  // 8字节  
    char c;  // 1字节  
}; 

答案:sizeof(fun)得到的结果是13。

解读:因为预处理语句 ”#prama pack(1)” 将编译器的字节对齐数改为1了,根据结构体内存对齐原则,该结构体占用的字节数为13。

问题8:代码输出4

#include<stdio.h>  
void main()  
{  
    int a[5] = {1, 2, 3, 4, 5};  
    int *ptr = (int *)(&a + 1);  
    printf("%d, %d", *(a + 1), *(ptr - 1));  
}  

答案:输出为2, 5。

解读: a是数组首元素地址,所以*(a + 1)就是第二个元素a[1]。&a是数组地址,所以&a + 1是整个数组结尾的下一个地址,*(ptr - 1)就是a[4]。

问题9:代码输出5

#include<stdio.h>  
void main()   
{   
     char *str[] = {"ab", "cd", "ef", "gh", "ij", "kl"};  //指针数组  
     char *t;   
     t = (str + 4)[-1];    
     printf("%s", t);    
} 

答案:输出"gh"。

解读:str表示数组首元素地址,str + 4表示数组第五个元素地址,(str + 4)[-1]表示在第五个元素地址的基础上往前移一个元素并解引用,因此输出是第四个元素。

问题10:代码输出6

unsigned int a = 1;  
int b = 0;   
int c = 0;  
c = a + b > 0 ? 1 : 2;  

答案:c的值是1。

解读:有符号数与无符号数一起运算时,有符号数转为无符号数。有符号数int b = 0的在内存中的补码是0,因此转为无符号数之后依然是0,a + b == 1 > 0,c == 1。

10.3 检查错误

问题11:检查错误1

#include<stdio.h>  
void main()  
{  
    char *s = "AAA";  
    s[0] = 'B';  
    printf("%s", s);  
}

AAA"是字符串常量,s是指针,指向这个字符串常量,所以声明s的时候就有问题,应该是const char* s="AAA"。

字符串字面量(如 "AAA")是存储在只读内存区域,尝试修改这些字面量的字符(如 s[0] = 'B';)会导致未定义行为,通常是程序崩溃。

问题12:判断下列表达式正确与否?

char str[2][3] = {“a”, “b”};         // 正确,str是一个可存放两个字符串的字符串数组  
char str[2][3] = {{1, 2}, {3, 4}, {5, 6}};  // 错误,行列不匹配  
char str[] = {“a”, “b”};           // 错误,字符数组不能存放两个字符串  
char str[2] = {“a”, “b”};          // 错误,字符数组不能存放两个字符串

答案:以注释形式展示。

注意:在C语言中字符用’’括起来,而字符串用””括起来。

嵌入式软件面试宝典 文章被收录于专栏

嵌入式软件面试宝典包含简历制作、笔试准备、面试八股文、企业真题等。

全部评论

相关推荐

就用这个吧:支持多益再加一个空气使用费
点赞 评论 收藏
分享
评论
点赞
4
分享

创作者周榜

更多
牛客网
牛客企业服务