全面解析《嵌入式程序员应该知道的16个问题》.pdf

上传人:灯火****19 文档编号:135061756 上传时间:2020-06-11 格式:PDF 页数:19 大小:217.29KB
返回 下载 相关 举报
全面解析《嵌入式程序员应该知道的16个问题》.pdf_第1页
第1页 / 共19页
全面解析《嵌入式程序员应该知道的16个问题》.pdf_第2页
第2页 / 共19页
全面解析《嵌入式程序员应该知道的16个问题》.pdf_第3页
第3页 / 共19页
全面解析《嵌入式程序员应该知道的16个问题》.pdf_第4页
第4页 / 共19页
全面解析《嵌入式程序员应该知道的16个问题》.pdf_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《全面解析《嵌入式程序员应该知道的16个问题》.pdf》由会员分享,可在线阅读,更多相关《全面解析《嵌入式程序员应该知道的16个问题》.pdf(19页珍藏版)》请在金锄头文库上搜索。

1、全面解析 嵌入式程序员应该知道的全面解析 嵌入式程序员应该知道的 16 个问题 个问题 1 预处理器 Preprocessor 2 如何定义宏 3 预处理器标识 error 的目的是什么 4 死循环 Infinite loops 5 数据声明 Data declarations 6 关键字 static 的作用是什么 7 关键字 const 有什么含意 8 Volatile 的使用 9 位操作 Bit manipulation 10 访问固定的内存位置 Accessing fixed memory locations 11 中断 Interrupts 12 符号扩展的代码例子 Code exa

2、mples 13 处理器字长导致的数据扩展问题 14 动态内存分配 Dynamic memory allocation 15 用 Typedef 构造复合类型 16 晦涩的语法及代码风格 C 语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法 这些年 我既参加也组织了许多这 种测试 在这过程中我意识到这些测试能为面试者和被面试者提供许多有用信息 此外 撇开面试的压力 不谈 这种测试也是相当有趣的 从被面试者的角度来讲 你能了解许多关于出题者或监考者的情况 这个测试只是出题者为显示其对 ANSI 标准细节的知识而不是技术技巧而设计吗 这是个愚蠢的问题吗 如要你答出某个字符的 ASCII 值

3、这些问题着重考察你的系统调用和内存分配策略方面的能力吗 这标志着出题者也许花时间在微机上而不 是在嵌入式系统上 如果上述任何问题的答案是 是 的话 那么我知道我得认真考虑我是否应该去做这份 工作 从面试者的角度来讲 一个测试也许能从多方面揭示应试者的素质 最基本的 你能了解应试者 C 语 言的水平 不管怎么样 看一下这人如何回答他不会的问题也是满有趣 应试者是以好的直觉做出明智的 选择 还是只是瞎蒙呢 当应试者在某个问题上卡住时是找借口呢 还是表现出对问题的真正的好奇心 把这看成学习的机会呢 我发现这些信息与他们的测试成绩一样有用 有了这些想法 我决定出一些真正针对嵌入式系统的考题 希望这些令

4、人头痛的考题能给正在找工作 的人一点帮助 这些问题都是我这些年实际碰到的 其中有些题很难 但它们应该都能给你一点启迪 这个测试适于不同水平的应试者 大多数初级水平的应试者的成绩会很差 经验丰富的程序员应该有 很好的成绩 为了让你能自己决定某些问题的偏好 每个问题没有分配分数 如果选择这些考题为你所用 请自行按你的意思分配分数 1 预处理器 预处理器 Preprocessor 用预处理指令 define 声明一个常数 用以表明 1 年中有多少秒 忽略闰年问题 define SECONDS PER YEAR 60 60 24 365 UL 大小写都行 常量后面可以加此标志 宏的命名风 格要大写 多

5、个之间用下划线 我在这想看到几件事情 1 define 语法的基本知识 例如 不能以分号结束 括号的使用 表达式 参数等要括起来 等等 2 懂得预处理器将为你计算常数表达式的值 难道不是替换么 先算再替 会将常数合并 因此 直接写 出你是如何计算一年中有多少秒而不是计算出实际的值 是更清晰而没有代价的 3 意识到这个表达式将使一个 16 位机的整型数溢出 因此要用到长整型符号 L 告诉编译器这个常数是的长 整型数 4 如果你在你的表达式中用到 UL 表示无符号长整型 那么你有了一个好的起点 记住 第一印象很重 要 2 如何定义宏 如何定义宏 写一个 标准 宏 MIN 这个宏输入两个参数并返回较

6、小的一个 考点 表达式 参数等要括起来 define MIN A B A B A B 这个测试是为下面的目的而设的 1 标识 define 在宏中应用的基本知识 这是很重要的 因为在嵌入 inline 操作符变为标准 C 的一部分之前 宏是方便产生嵌入代码的唯一方法 对于嵌入式系统来说 为了能达到要求的性能 当然主要是实时性哦 牺牲代码空间换取时间效率 嵌入代码经常是必须的方法 2 三重条件操作符的知识 这个操作符存在 C 语言中的原因是它使得编译器能产生比 if then else 存在条 件转移会中断指令流水线 更优化的代码 了解这个用法是很重要的 3 懂得在宏中小心地把参数用括号括起来

7、4 我也用这个问题开始讨论宏的副作用 例如 当你写下面的代码时会发生什么事 least MIN p b 此处考点 inline 函数和宏的区别 宏只是将参数完全替换 即 MIN p b 进行宏展开后为 p b p b 如果 p b 成立 则表达式的值为 p 但由于在 p b 判断过程中改变 了 p 的值 使得此时的 p 非 p b 中的值了 违背了 号表达式的原意 但是内联 inline 函数将进行参数检查 求出参数的值后再将此值带入函数中 因此 A B A B 中的 A 是一致的 第一部分 宏 为什么要使用宏呢 因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址 将函数的

8、程序内容执行 完后 再返回到转去执行该函数前的地方 这种转移操作要求在转去执行前要保存现场并记忆执行的地址 转回后要恢复现场 并按原来保存地址继续执行 因此 函数调用要有一定的时间和空间方面的开销 于 是将影响其效率 而宏只是在预处理的地方把代码展开 不需要额外的空间和时间方面的开销 所以调用一个宏比调用一个 函数更有效率 但是宏也有很多的不尽人意的地方 1 宏不能访问对象的私有成员 2 宏的定义很容易产生二意性 3 宏定义的常量在代码区 很多调试器不能够对其调试 我们举个例子 define square x x x 避免这些错误的方法 一是给宏的参数都加上括号 二是采用内联函数的方式 def

9、ine square x x x 第二部分 内联函数 从上面的阐述 可以看到宏有一些难以避免的问题 怎么解决呢 内联函数是代码被插入到调用者代码处的函数 如同 define 宏 内联函数通过避免被调用的开销来提高 执行效率 尤其是它能够通过调用 过程化集成 被编译器优化 内联函数和宏很类似 而本质区别在于 宏是由预处理器对宏进行替代 而内联函数是通过编译器控制来 实现的 而且内联函数是真正的函数 只是在需要用到的时候 内联函数像宏一样的展开 所以取消了函 数的参数压栈 减少了调用的开销 你可以象调用函数一样来调用内联函数 而不必担心会产生于处理宏 的一些问题 声明内联函数看上去和普通函数非常相

10、似 void f int i char c 当你定义一个内联函数时 在函数定义前加上 inline 关键字 并且将定义放入头文件 inline void f int i char c 内联函数必须是和函数体的定义申明在一起 才有效 像这样的申明 inline function int i 是没有效果的 编译器只是把函数作为普通的函数申明 我们必须定义函 数体 inline int function int i return i i 这样我们才算定义了一个内联函数 我们可以把它作为一般的函数一样调用 但是执行速度确比一般函数 的执行速度要快 在 C 中 在类的内部定义了函数体的函数 被默认为是内

11、联函数 而不管你是否有 inline 关键字 当然 内联函数也有一定的局限性 就是函数中的执行代码不能太多了 如果 内联函数的函数体过大 一般的编译器会放弃内联方式 而采用普通的方式调用函数 这样 内联函数就和普通函数执行效率一样 了 有上面的两者的特性 我们可以用内联函数完全取代预处理宏 3 预处理器标识 预处理器标识 error 的目的是什么 的目的是什么 编译程序时 只要遇到 error 就会跳出一个编译错误 既然是编译错误 要它干嘛呢 其目的就是保证程 序是按照你所设想的那样进行编译的 如果你不知道答案 请看参考文献 1 这问题对区分一个正常的伙计和一个书呆子是很有用的 只有书呆子 才

12、会读 C 语言课本的附录去找出象这种问题的答案 当然如果你不是在找一个书呆子 那么应试者最好希 望自己不要知道答案 指令 用途 空指令 无任何效果 include 包含一个源代码文件 define 定义宏 undef 取消已定义的宏 if 如果给定条件为真 则编译下面代码 ifdef 如果宏已经定义 则编译下面代码 ifndef 如果宏没有定义 则编译下面代码 elif 如果前面的 if 给定条件不为真 当前条件为真 则编译下面代码 endif 结束一个 if else 条件编译块 error 停止编译并显示错误信息 4 死循环 死循环 Infinite loops 嵌入式系统中经常要用到无限

13、循环 你怎么样用 C 编写死循环呢 这个问题用几个解决方案 我首选的方案是 while 1 一些程序员更喜欢如下方案 for 此处的判断效率要低的多 在汇编代码中看看 这个实现方式让我为难 因为这个语法没有确切表达到底怎么回事 如果一个应试者给出这个作为方案 我将用这个作为一个机会去探究他们这样做的基本原理 如果他们的基本答案是 我被教着这样做 但从 没有想到过为什么 这会给我留下一个坏印象 很多时候面试官关注你思考问题的方式 是否留意某 些东西善于思考 可能并没有对错 只是偏好而已 比如 memset 和 memcopy以及 strcpy 都能拷贝字符串 到底有什么区别呢 看你是否善于比较是

14、否关注细节 memset 主要应用是初始化某个内存空间 memcpy是用于 COPY 源空间的数据到目的空间中 strcpy 用于字符串 COPY 遇到 0 将结束 strcpy 原型 extern char strcpy char dest char src 用法 include 功能 把 src 所指由 NULL 结束的字符串复制到 dest 所指的数组中 说明 src 和 dest 所指内存区域不可以重叠且 dest 必须有足够的空间来容纳 src 的字符串 返回指向 dest 的指针 memcpy 原型 extern void memcpy void dest void src uns

15、igned int count 用法 include 功能 由 src 所指内存区域复制 count 个字节到 dest 所指内存区域 说明 src 和 dest 所指内存区域不能重叠 函数返回指向 dest 的指针 memset 原型 extern void memset void buffer int c int count 用法 include 功能 把 buffer 所指内存区域的前 count 个字节设置成字符 c 说明 返回指向 buffer 的指针 第三个方案是用 goto goto 语句在 C 中是应该尽量避免的 只在处理错误代码时用 Loop goto Loop 应试者如给出

16、上面的方案 这说明或者他是一个汇编语言程序员 这也许是好事 或者他是一个想进入新 领域的 BASIC FORTRAN 程序员 5 数据声明 数据声明 Data declarations 用变量 a 给出下面的定义 a 一个整型数 An integer b 一个指向整型数的指针 A pointer to an integer c 一个指向指针的的指针 它指向的指针是指向一个整型数 A pointer to a pointer to an integers d 一个有 10 个整型数的数组 An array of 10 integers e 一个有 10 个指针的数组 该指针是指向一个整型数的 An array of 10 pointers to integers f 一个指向有 10 个整型数数组的指针 A pointer to an array of 10 integers g 一个指向函数的指针 该函数有一个整型参数并返回一个整型数 A pointer to a function that takes an integer as an argument and returns an

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号