更多课程 选择中心

嵌入式培训
达内IT学院

400-996-5531

学习嵌入式C语言要掌握到什么程度?

  • 发布:嵌入式培训
  • 来源:嵌入式问答
  • 时间:2018-01-08 16:30

我在知乎上回答的一个问题,转发到公众号上,给大家分享:

作者:王利涛@宅学部落

跟学英语一样,C语言也算是一门语言。C语言本身很简洁的,除了34个关键字(ANSI标准,但C99标准新增几个关键字及特性,用来定义新的数据类型、变长数组等)、40多个运算符、再明白数据的基本类型、程序的顺序、分支、循环3种基本结构,就OK了,就这点东西。一般,看上一周左右基本上就可以掌握。

但是,掌握了这些,你就觉得自己精通C语言、可以熟练运用C语言进行编程了吗?绝不可能。就像你掌握了英语的六大时态、各种从句语法结构,还是写不出《哈雷波特》、写不出一篇好英语作文一个道理。英语语法就这点东西,你需要进一步学习的是,如何通过英语语言这个工具,去了解英文圈文化、历史文化、法律政治、西方人的思维等等,否则你就无法理解西方人说话的一些“梗”,不算掌握一门地道的英语。

学习C语言也是一样,尤其是对于嵌入式底层工程师来说,我们要学习的不仅仅是C语言的基本语法,更重要的是如何通过C语言这个工具,去理解我们的计算机系统、CPU架构:

1)程序到底是如何编译、链接、和运行的?

2)运行时各种代码段、数据段、BSS段、堆栈在内存中如何分布,如何管理的?

3)程序在不同的平台(ARM、X86)、裸机环境或有OS的环境(linux、uc/os等)有何不同?

4)静态链接与动态链接的过程有何差异,为什么要使用动态链接?共享库?

5)不同的开发平台、IDE、编译器,C语言的编程有何差异和不一样的地方,如何做到跨平台、增强程序的可移植性和鲁棒性?

6)各种变量名、函数名、数组名、指针的本质是什么?编译器是如何处理的?

搞懂了这些语言背后计算机系统知识,还远远不够,还要去学习操作系统相关的知识:进程、线程、中断、内存管理

对于嵌入式开发来说,还要学习ARM等处理器架构知识、GCC编译器对C标准的各种扩展,各种生僻的用法,否则你去看linux内核代码、驱动代码,总感觉“怪怪的”,好像哪里不对,跟平时的C语言不太一样,感觉自己学的是一门假C语言......

C语言的精华是内存、存储管理。各种隐藏很深的bug其实也跟内存有关:内存越界、内存泄露、野指针等等,一个不经意的疏漏,就可能阴沟里翻船。就是有多年工作经验的工程师也不敢保证自己写的代码一定没有问题。C语言默认大家都是大牛、计算机专家,可惜现实中往往太多挖坑小能手,太多猪一样的队友。如何养成良好的编程习惯,避免各种bug,也是C语言进阶学习的一个重点。

为了测试一下你对C语言的掌握程度,下面的几个测试题,可以自我测试一下,检测一下自己的C语言水平,是否达到嵌入式工程师(尤其是内核驱动工程师)的要求:

1)你对以下C语言的基本概念是否掌握?是否能用一句话概括出来?

标识符、关键字、预定义标识符、分隔符、语法检查、语义检查、表达式、语句、左值、对象、结合性、左结合右结合、未定义行为

2)一个sizeof(int)引发的思考

•sizeof是函数吗?是关键字?预定义标识符? 后两者有何区别?•在32位和64位的Windows7系统下,结果分别是多少?•在32位和64位X86 CPU系统下,结果分别是多少?•在8位、16位、32位ARM系统环境下运行结果分别是多少?•在Turbo C、keil、GCC-32、GCC-64开发环境下,结果是多少?•使用gcc –m32生成一个32位代码,运行在64位环境下,结果? 使用gcc –m64生成一个64位代码,运行在32位环境下,结果?

3)自增运算符带来的思考

下面一段程序,在不同的编译器上编译,结果是多少,一样吗?为什么?

i=1,j=2; printf(“%d ”,i++*i++); i+++j;

4)代码分析

使用tc、C-free、GCC、VC++6.0、visual studio分别编译下面代码,会出现什么问题?

int main(){ int i; //定义一个变量 int a[0]; printf("hello world! "); int j; for(int k=0;k<10;k++); return 0;}

5)在linux环境下,运行下面代码,会出现什么问题?

int * data_copy ( int *p){ int buffer[8192*1024]; memcpy(buffer,p,8192*1024); return buffer;}

6)下面是linux内核代码的一部分(摘自Linux4.4内核),你能看懂多少?

#define stamp(fmt, args...) pr_debug("%s:%i:" fmt " ", __func__, __LINE__, ## args)#define

container_of(ptr, type, member) ({ const typeof(((type *)0)->member)

* __mptr = (ptr); (type *)((char *)__mptr - offsetof(type, member)); })struct urb { … struct usb_iso_packet_descriptor iso_frame_desc[0]; } urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |URB_DMA_MAP_PAGE );

本文内容转载自网络,来源/作者信息已在文章顶部表明,版权归原作者所有,如有侵权请联系我们进行删除!

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:嵌入式培训靠谱吗?就业好不好?
下一篇:0基础学习嵌入式难吗?多久能学会?

嵌入式培训主要学习哪些内容?好学吗?

大学生参加嵌入式培训班好就业吗

学习嵌入式培训有必要报班吗

嵌入式培训主要培训什么

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省