小程序
传感搜
传感圈

【C语言进阶】面试题:请使用宏定义实现字节对齐

2022-07-11
关注

1 前言

最近博主在后台收到一位朋友的咨询,说他最近参加了一场技术面试,有这么一道笔试题:

请使用C语言的宏定义实现一个功能,求得某个整型数M在N字节对齐的时,它的值大小。

说明:
1.M是一个非负整数;
2.N是2的整数倍,值可能是1,2,4,8,16等等。

要求:
1.不得使用除法(/);
2.不能使用函数实现,只能用宏实现;
3.自行设计测试用例,明确得出测试用例执行成功与否。

2 代码实现

刚好,今天比较清闲,茶余饭后,顺手撸了一把代码:

#include 
#include 

/* max test number for aligned */
#define MAX_TEST_NUM                         1000

/* default for 8 bytes */
#define DEF_ALIGNED_BYTES                     8

/* n = 2/4/6/8/16/... */
#define GET_ALIGNED_2_POWER_NUM(num, n)        (((num) + (n) - 1) & (~((n) - 1))) 

int main(int argc, const char *argv[])
{
    int i = 0;
    int max_cnt = MAX_TEST_NUM;
    int aligned_bytes = DEF_ALIGNED_BYTES;
    int aligned_num;

    if (argc > 1) {
        aligned_bytes = atoi(argv[1]);
        if (aligned_bytes < 0) {
            printf("error aligned_bytes input !\r\n");
            return -1;
        }
    }

    /* test cases start */
    for (i = 0; i < max_cnt; i++) {
        aligned_num = GET_ALIGNED_2_POWER_NUM(i, aligned_bytes);
        //printf("%-4d ALIGNED %d => %-4d\r\n", i, aligned_bytes, aligned_num);
        if (aligned_num % aligned_bytes != 0) {
            printf("error aligned_num get: %-4d ALIGNED %d => %-4d\r\n", i, aligned_bytes, aligned_num);
            printf("test cases (0 ~ %d) ALIGNED %d [ FAIL ] !\r\n", max_cnt, aligned_bytes);
            return -1;
        }
    }

    printf("test cases (0 ~ %d) ALIGNED %d [ OK ] !\r\n", max_cnt, aligned_bytes);

    return 0;
}

3 代码验证

ubuntu下面使用gcc编译,得到可执行文件:

gcc -o test main.c

跑了下测试用例:

recan@ubuntu:~/llc/aligned_macro_test$ ./test 2
test cases (0 ~ 1000) ALIGNED 2 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 4
test cases (0 ~ 1000) ALIGNED 4 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 8
test cases (0 ~ 1000) ALIGNED 8 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 16
test cases (0 ~ 1000) ALIGNED 16 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 32
test cases (0 ~ 1000) ALIGNED 32 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 64
test cases (0 ~ 1000) ALIGNED 64 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 128
test cases (0 ~ 1000) ALIGNED 128 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 256
test cases (0 ~ 1000) ALIGNED 256 [ OK ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 3
error aligned_num get: 1    ALIGNED 3 => 1   
test cases (0 ~ 1000) ALIGNED 3 [ FAIL ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 5
error aligned_num get: 1    ALIGNED 5 => 1   
test cases (0 ~ 1000) ALIGNED 5 [ FAIL ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 7
error aligned_num get: 1    ALIGNED 7 => 1   
test cases (0 ~ 1000) ALIGNED 7 [ FAIL ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 167
error aligned_num get: 1    ALIGNED 167 => 1   
test cases (0 ~ 1000) ALIGNED 167 [ FAIL ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ ./test 79
error aligned_num get: 1    ALIGNED 79 => 1   
test cases (0 ~ 1000) ALIGNED 79 [ FAIL ] !
recan@ubuntu:~/llc/aligned_macro_test$ 
recan@ubuntu:~/llc/aligned_macro_test$ 

从log上看,基本实现了功能,对于非对齐的数值,都能做出准确的判断。

大家记住这个宏定义吧!

/* n = 2/4/6/8/16/... */
#define GET_ALIGNED_2_POWER_NUM(num, n)        (((num) + (n) - 1) & (~((n) - 1))) 

4 题外话

题外话,如果把题目中的N改为【任意非负整数】呢?

又该如何改造这个宏定义呢?

下次有时间,我们再试试看!

5 更多分享

欢迎关注我的github仓库01workstation,日常分享一些开发笔记和项目实战,欢迎指正问题。

同时也非常欢迎关注我的专栏:有问题的话,可以跟我讨论,知无不答,谢谢大家。

您觉得本篇内容如何
评分

评论

您需要登录才可以回复|注册

提交评论

电子发烧友

这家伙很懒,什么描述也没留下

关注

点击进入下一篇

安卓权限中要掌握的三大模块 原创

提取码
复制提取码
点击跳转至百度网盘