侵权投诉

C语言头文件组织作用与包含原则详解

嵌入式ARM 2020-11-12 17:49 次阅读

说明

本文假定读者已具备基本的C编译知识。

如非特殊说明,文中“源文件”指*.c文件,“头文件”指*.h文件,“引用”指包含头文件。

一、头文件作用

C语言里,每个源文件是一个模块,头文件为使用该模块的用户提供接口。接口指一个功能模块暴露给其他模块用以访问具体功能的方法。

使用源文件实现模块的功能,使用头文件暴露单元的接口。用户只需包含相应的头文件就可使用该头文件中暴露的接口。

通过头文件包含的方法将程序中的各功能模块联系起来有利于模块化程序设计:

1)通过头文件调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制库即可。用户只需按照头文件中的接口声明来调用库功能,而不必关心接口如何实现。编译器会从库中提取相应的代码。

2)头文件能加强类型安全检查。若某个接口的实现或使用方式与头文件中的声明不一致,编译器就会指出错误。这一简单的规则能大大减轻程序员调试、改错的负担。

在预处理阶段,编译器将源文件包含的头文件内容复制到包含语句(#include)处。在源文件编译时,连同被包含进来的头文件内容一起编译,生成目标文件(.obj)。

如果所包含的头文件非常庞大,则会严重降低编译速度(使用GCC的-E选项可获得并查看最终预处理完的文件)。因此,在源文件中应仅包含必需的头文件,且尽量不要在头文件中包含其它头文件。

二、头文件组织原则

源文件中实现变量、函数的定义,并指定链接范围。头文件中书写外部需要使用的全局变量、函数声明及数据类型和宏的定义。

建议组织头文件内容时遵循以下原则:

1)头文件划分原则:类型定义、宏定义尽量与函数声明相分离,分别位于不同的头文件中。内部函数声明头文件与外部函数声明头文件相分离,内部类型定义头文件与外部类型定义头文件相分离。

注意,类型和宏定义有时无法分拆为不同文件,比如结构体内数组成员的元素个数用常量宏表示时。因此仅分离类型宏定义与函数声明,且分别置于*.th和*.fh文件(并非强制要求)。

2)头文件的语义层次化原则:头文件需要有语义层次。不同语义层次的类型定义不要放在一个头文件中,不同层次的函数声明不要放在一个头文件中。

3)头文件的语义相关性原则:同一头文件中出现的类型定义、函数声明应该是语义相关的、有内部逻辑关系的,避免将无关的定义和声明放在一个头文件中。

4)头文件名应尽量与实现功能的源文件相同,即module.c和module.h。但源文件不一定要包含其同名的头文件。

5)头文件中不应包含本地数据,以降低模块间耦合度。

即只有源文件自己使用的类型、宏定义和变量、函数声明,不应出现在头文件里。作用域限于单文件的私有变量和函数应声明为static,以防止外部调用。将私有类型置于源文件中,会提高聚合度,并减少不必要的格式外漏。

6)头文件内不允许定义变量和函数,只能有宏、类型(typedef/struct/union/enum等)及变量和函数的声明。特殊情况下可extern基本类型的全局变量,源文件通过包含该头文件访问全局变量。但头文件内不应extern自定义类型(如结构体)的全局变量,否则将迫使本不需要访问该变量的源文件包含自定义类型所在头文件[1]。

7)说明性头文件不需要有对应的源文件。此类头文件内大多包含大量概念性宏定义或枚举类型定义,不包含任何其他类型定义和变量或函数声明。此类头文件也不应包含任何其他头文件。

8)使用#pragmaonce或headerguard(亦称includeguard或macroguard)避免头文件重复包含。#pragmaonce是一种非标准但已被现代编译器广泛支持的技巧,它明确告知预处理器“不要重复包含当前头文件”。而headerguard则通过预处理命令模拟类似行为:

#ifndef_PRJ_DIR_FILE_H//必须确保headerguard宏名永不重名#define_PRJ_DIR_FILE_H//<头文件内容>#endif

使用#pragmaonce相比headerguard具有两个优点:

更快。编译器不会第二次读取标记#pragmaonce的文件,但却会读若干遍使用headerguard的文件(寻找#endif);

更简单。不再需要为每个文件的headerguard取名,避免宏名重名引发的“找不到声明”问题。

缺点则是:

#pragmaonce保证物理上的同一个文件不会被包含多次,无法对头文件中的一段代码作#pragmaonce声明。若某个头文件具有多份拷贝(内容相同的多个文件),pragma不能保证它们不被重复包含。当然,这种重复包含很容易被发现并修正。

9)C++++中要引用C函数时,函数所在头文件内应包含extern"C"。

//.h文件头部#ifdef__cplusplusextern"C"{#endif//<函数声明>//.h文件尾部#ifdef__cplusplus}#endif

被extern"C"修饰的变量和函数将按照C语言方式编译和连接,否则编译器将无法找到C函数定义,从而导致链接失败。

10)头文件内要有面向用户的充足注释,从应用角度描述接口暴露的内容。

三、头文件包含原则

在实际编程中,常常因头文件包含不当而引发编译时报告符号未定义的错误或重复定义的警告。要消除符号未定义的编译错误,只需在引用符号(变量、函数、数据类型及宏等)前确保它已被声明或定义[4]。要消除重复定义的警告,则需合理设计头文件包含顺序和层次。

建议包含头文件时遵循以下原则:

1)源文件内的头文件包含顺序应从最特殊到一般,如:

#include"通用头文件"//内部可能定义本模块数据类型别名#include"源文件同名头文件"#include"本模块其他头文件"#include"自定义工具头文件"#include"第三方头文件"#include"平台相关头文件"#include"C++库头文件"#include"C库头文件"

优点是每个头文件必须include需要的关联头文件,否则会报错。同时,源文件同名头文件置于包含列表前端便于检查该头文件是否自完备,以及类型或函数声明是否与标准库冲突。

2)减少头文件的嵌套和交叉引用,头文件仅包含其真正需要显式包含的头文件。

例如,头文件A中出现的类型定义在头文件B中,则头文件A应包含头文件B,除此以外的其他头文件不允许包含。

头文件的嵌套和交叉引用会使程序组织结构和文件组织变得混乱,同时造成潜在的错误。大型工程中,原有头文件可能会被多个其他(源或头)文件包含,在原有头文件中添加新的头文件往往牵一发而动全身。若头文件中类型定义需要其他头文件时,可将其提出来单独形成一个全局头文件。

3)头文件应包含哪些头文件仅取决于自身,而非包含该头文件的源文件。

例如,编译源文件时需要用到头文件B,且源文件已包含头文件A,而索性将头文件B包含在头文件A中,这是错误的做法。

4)尽量保证用户使用此头文件时,无需手动包含其他前提头文件,即此头文件内已包含前提头文件。

例如,面积相关操作的头文件Area.h内已包含关于点操作的头文件Point.h,则用户包含Area.h后无需再手动包含Point.h。这样用户就不必了解头文件的内在依赖关系。

5)头文件应是自完备的,即在任一源文件中包含任一头文件而不会产生编译错误。

6)源文件中包含的头文件尽量不要有顺序依赖。

7)尽量在源文件中包含头文件,而非在头文件中。且源文件仅包含所需的头文件。

8)头文件中若能前置声明(亦称前向声明[5]),就不要包含另一头文件。仅当前置声明不能满足或过于麻烦时才使用include,如此可减少依赖性方面的问题。示例如下:

structT_MeInfoMap;//前置声明structT_OmciMsg;//前置声明typedefFUNC_STATUS(*OmciChkFunc)(structT_MeInfoMap*ptMeInfo,structT_OmciMsg*ptMsg,structT_OmciMsg*ptAckMsg);//OMCI实体信息typedefstruct{INT16UwMeClass;//实体类别OMCI_ATTR_INFO*pMeAttrInfo;//实体所定义的属性信息指针INT8UucAttrNum;//实体所定义的属性数目INT16UwTotalAttrLen;//实体所有属性所占的总字节数,初始化为0,动态计算INT8U*pszDbName;//实体存库时的数据表名称,建议不要超过DB_NAME_LEN(32)INT16UwMaxRecNum;//实体存库时支持的最大记录数目OmciChkFuncfnCheck;//Omci校验函数指针BOOLbDbCreated;//实体数据表是否已创建}OMCI_ME_INFO_MAP;

如上,在OmciChkFunc函数的实现源文件内包含T_MeInfoMap和T_OmciMsg所在头文件即可。

另举一例如下:

typedefTBL_SET_MODE(*OperTypeFunc)(INT8U*pTblEntry);typedefINT8U(*CmpRecFunc)(VOID*pvCmpData,VOID*pvRecData);//为避免头文件交叉引用,与CompareRecFunc异名同构//表属性信息typedefstruct{INT16UwMaxEntryNum;//表属性最大表项数目(实体记录数目wMaxRecNum*wMaxEntryNum<= MAX_RECORD_NUM)     OperTypeFunc fnGetOperType;  //操作类型函数指针。根据表项数据或外界需求(只读表)解析当前表项操作类型     TBL_KEY_INFO tCmpKeyInfo;    //检索表属性子表记录时的匹配关键字信息(TBL_KEY_INFO)     CmpRecFunc   fnCmpAddKey;    //增加表项时需要检测的关键字匹配函数指针     CmpRecFunc   fnCmpDelKey;    //删除表项时需要检测的关键字匹配函数指针     INT16U wTblEntrySize;        //表属性表项字节数,由外部动态赋值 }TBL_ATTR_INFO;

如上,CompareRecFunc函数原型由其他头文件提供,此处为避免头文件交叉引用定义其异名同构原型CmpRecFunc。

在不会引起歧义的前提下,头文件内尽可能使用VOID指针代替非基本类型的值变量或指针,以避免再包含类型定义所在的头文件。但这将影响代码可读性并降低程序执行效率,应权衡利弊。

9)避免包含重量级的平台头文件,如windows.h或d3d9.h等。若仅使用该头文件少量函数,可extern函数到源文件内。如下:

/****************************************************************************************外部函数声明(当外部接口未提供头文件或头文件过于复杂时)****************************************************************************************///因声明所在头文件引用混乱,此处仅extern函数声明。externINT32SDBShmCliInit(VOID);//#include"db_shm_mgr.h"externINT32ScmLockInit(VOID);//#include"common_cmapi.h"

若还使用该头文件某些类型和宏定义,可创建适配性源文件。在该源文件内包含平台头文件,封装新的接口并将其声明在同名头文件内,其他源文件将通过适配头文件间接访问平台接口。如下:

/******************************************************************************************文件名称:Omci_Send_Msg.c*内容摘要:OMCI消息转发接口*其它说明:该头文件封装SEND接口,以避免其他源文件包含支撑api和pid公共头文件导致引用混乱。*****************************************************************************************/#include"Omci_Common.h"#include"Omci_Send_Msg.h"#include"oss_api.h"/**********************************************************************************************函数实现区**********************************************************************************************///向自身进程发送异步消息INT32UOmciAsynSendSelf(INT16UwEvent,VOID*pvMsg,INT16UwMsgLen){PIDdwSelfPid=0;SELF(&dwSelfPid);returnASEND(wEvent,pvMsg,wMsgLen,dwSelfPid);}

10)对于函数库(包括标准库和自定义的公共宏及接口)的头文件,可将其加入到一个通用头文件中。需要控制该头文件的体积(主要是该头文件所包含的所有头文件内容大小),并确保所有源文件首先包含该通用头文件。示例如下:

#ifndef_OMCI_COMMON_H#define_OMCI_COMMON_H/********************************************************************************************说明:*本文件仅应包含与具体通信协议无关的通用数据类型及宏定义。*为简化头文件包含且不失可移植性,本文件内可包含少量C库通用头文件。*因本文件内定义基本数据类型别名,故.c文件中应将本头文件置于包含列表顶端,*否则编译时可能产生类型未定义错误。*******************************************************************************************/#include#include#include#include#include#include"Omci_Byte.h"//

注意,示例头文件内包含C库文件虽能简化包含,但却与规则1冲突。也可另外增加包含库文件列表的通用头文件。

11)若不确定类型、宏定义或函数声明所在头文件具体路径,可在源文件中再次定义或声明,编译器会以redefined警告或conflicting错误给出类型、宏定义或函数声明所在头文件路径。

四、代码文件组织原则

建议C语言项目中代码文件组织遵循以下原则:

1)使用层次化和模块化的软件开发模型。每个模块只能使用所在层和下一层模块提供的接口。

2)每个模块的文件(可能多个)保存在一个独立文件夹中。

模块文件较多时可采用子目录的方式,物理上隔离不同层次的文件。子目录下源文件和头文件应分开存放,如分别置入include和source目录。

3)用于模块裁减的条件编译宏保存在一个独立文件中,便于软件裁减。

4)硬件相关代码和操作系统相关代码与工程代码相对独立保存,以便于软件移植。

5)按相同功能或相关性组织源文件和头文件。同一文件内的聚合度要高,不同文件中的耦合度要低。

在对既有工程做单元测试时,耦合度低的文件布局非常便于搭建环境。

6)声明和定义分开,使用头文件暴露模块需要提供给外部的类型、宏、变量和函数。尽量做到模块对外部透明,用户在使用模块功能时无需了解具体的实现。

7)作为对外接口的头文件一经发布,应保持稳定。修改时一定要慎重。

8)文件夹和文件命名要能够反映出模块的功能。

9)正式版本和测试版本使用统一文件,使用宏控制是否产生测试输出。

10)必要的注释不可缺少。

五、注解

「【注1】全局变量的使用原则」

1)若全局变量仅在单个源文件中访问,则可将该变量改为该文件内的静态全局变量;

2)若全局变量仅由单个函数访问,则可将该变量改为该函数内的静态局部变量;

3)尽量不要使用extern声明全局变量,最好提供函数访问这些变量。直接暴露全局变量是不安全的,外部用户未必完全理解这些变量的含义。

4)设计和调用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题。

「【注2】#pragmaonce的可移植性」

#ifndef由C/C++语言标准支持,不受编译器任何限制;而#pragmaonce仅由编译器提供保证,存在可移植性等问题。

某些gcc编译器版本(如3.2.3)会报告“warning:#pragmaonceisobsolete”的警告,而其他较老版本的编译器可能会报错。但随着gcc3.4的发布,#pragmaonce中的一些问题(主要与符号链接和硬链接有关)得以解决,#pragmaonce命令也标记为“未废弃”。

还有种写法同时使用#pragmaonce和headerguard编写“可移植性”代码,以利用编译器可能支持的#pragmaonce优化。如下:

#pragmaonce#ifndef_PRJ_DIR_FILE_H#define_PRJ_DIR_FILE_H//<头文件内容>#endif

该法似乎兼有两者的优点。但既然使用#ifndef就有宏名重名的风险,也无法避免不支持#pragmaonce的编译器告警或报错,故混用两种方法似乎不能带来更多的好处,反倒让不熟悉的人感到困惑。

注意,如果使用headerguard,理论上可在代码任何地方判断当前是否已经包含某个头文件。但应避免通过该判断来改变后续代码的逻辑走向!

这种做法将使程序依赖于头文件的包含顺序,极不可取。若需要实现“若当前包含HeaderA.h,才加入StructB结构”,可对StructB结构创建HeaderB.h头文件,在HeaderA.h中包含HeaderB.h。

「【注3】extern"C"」

C++语言在编译时为实现函数重载,会结合函数名、参数数目及类型信息而生成一个中间函数名。

例如,C++中函数voidfoo(intx,floaty)编译后在符号库中生成的名字为_foo_int_float(不同编译器可能生成不同函数名,但均采用相同机制,生成的新名字称为”mangledname”);而该函数被C编译器编译后在符号库中的名字为_foo。

C语言中不支持extern"C"声明,在.c文件中包含extern"C"时会出现编译语法错误。

当然编译器也可以为其他语言提供链接说明。例如:extern"FORTRAN"、extern"Ada"等。

「【注4】声明(declaration)与定义(definition)」

全局变量或函数可(在多个编译单元中)有多处声明,但只允许定义一次。全局变量定义时分配空间并赋初始值(如果有);函数定义时提供函数体内容。

声明:externintiGlobal;externintfunc();或intfunc();定义:intiGlobal=0;或intiGlobal;intfunc(){return1;}

在多个源文件中共享变量或函数时,需确保定义和声明的一致性。通常在某个相关的源文件中定义,然后在头文件中进行外部声明。需要使用时包含相应的头文件即可。定义变量的源文件也应包含该头文件,以便编译器检查定义和声明的一致性。

该规则可提供高度的可移植性:它与ANSI/ISOC标准一致,同时也兼顾大多数ANSI前的编译器和链接器。(Unix编译器和链接器常使用允许多重定义的“通用模式”,只要保证最多对一处定义进行初始化即可。

该方式被ANSIC标准称为一种“通用扩展”)。某些很老的系统可能要求显式初始化以区别定义和外部声明。

通用扩展在《深入理解计算机系统》中解释为:多重定义的符号只允许最多一个强符号。函数和定义时已初始化的全局变量是强符号;未初始化的全局变量是弱符号。Unix链接器使用以下规则来处理多重定义的符号:

规则一:不允许有多个强符号。在被多个源文件包含的头文件内定义的全局变量会被定义多次(预处理阶段会将头文件内容展开在源文件中),若在定义时显式地赋值(初始化),则会违反此规则。

规则二:若存在一个强符号和多个弱符号,则选择强符号。

规则三:若存在多个弱符号,则从这些弱符号中任选一个。

当不同文件内定义同名(即便类型和含义不同)的全局变量时,该变量共享同一块内存(地址相同)。若变量定义时均初始化,则会产生重定义(multipledefinition)的链接错误;若某处变量定义时未初始化,则无链接错误,仅在因类型不同而大小不同时可能产生符号大小变化(sizeofsymbol`XXX'changed)的编译警告。

在最坏情况下,编译链接正常,但不同文件对同名全局变量读写时相互影响,引发非常诡异的问题。这种风险在使用无法接触源码的第三方库时尤为突出。

因此,应尽量避免使用全局变量。若确有必要,应采用静态全局变量(无强弱之分,且不会和其他全局符号产生冲突),并封装访问函数供外部文件调用。

「【注5】前向声明(forwarddeclaration)」

结构体类型S在声明之后定义之前是一个不完全类型(incompletetype),即已知S是一个类型,但不知道包含哪些成员。

不完全类型只能用于定义指向该类型的指针,或声明使用该类型作为形参指针类型或返回指针类型的函数。指针类型对编译器而言大小固定(如32位机上为四字节),不会出现编译错误。

假设先后定义两个结构A和B,且两个结构需要互相引用。在定义A时B还没有定义,则要引用B就需要前向声明结构B(structB;)。示例如下:

typedefBOOL(*func)(constDefStruct*ptStrt);typedefstructDefStruct_t{inti;funcf;}DefStruct;

如上在DefStruct中使用回调函数func声明,这样交叉引用必然编译报错。进行前向声明即可:

typedefstructDefStruct_tDefStruct;typedefBOOL(*func)(constDefStruct*ptStrt);structDefStruct_t{inti;funcf;};

注意,在前向声明和具体定义之间涉及标识符(变量、结构、函数等)实现细节的使用都是非法的。若函数被前向声明但未被调用,则编译和运行正常;若前向声明函数被调用但未被定义,则编译正常但链接报错(undefinedreference)。将具体定义放在源文件中可部分避免该问题。

责任编辑:xj

原文标题:C语言头文件组织与包含原则

文章出处:【微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

原文标题:C语言头文件组织与包含原则

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式ARM】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
分享:

评论

相关推荐

【干货】单片机入门到精通之单片机C语言知识分享

学习单片机C语言必要知识点集合,很实用,需要的可以看看,可以有很大提升。 ...
发表于 02-27 11:31 130次 阅读
【干货】单片机入门到精通之单片机C语言知识分享

C语言程序设计实用教程

在各章的讲解穿插典型实例进行说明。本书的写作以基本功能介绍(穿插实例)为主,每章最后以一个比较典型的....
发表于 02-26 16:17 11次 阅读
C语言程序设计实用教程

DSP芯片的应用总结详细资料说明

数字信号处理( Digital Signal Processing ,简称DSP )是一门涉及许多学....
发表于 02-25 11:52 36次 阅读
DSP芯片的应用总结详细资料说明

干货分享:C语言函数大全和C语言程序实例~

对于初学C语言以至于单片机的,很好的例程练习和C语言函数查阅资料,对于程序员笔试题也是很好的借鉴。 ...
发表于 02-25 11:30 132次 阅读
干货分享:C语言函数大全和C语言程序实例~

怎么制作寻迹小车?

智能小车现在差不多是竞赛或者DIY中的主流了,寻迹,壁障,遥控什么的,相信大家也都见得很多了,这次就大家探讨一下寻迹小车...
发表于 02-25 07:26 0次 阅读
怎么制作寻迹小车?

C语言编程的基本规范有哪些?

为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进行程序设计时必须遵循...
发表于 02-24 07:22 0次 阅读
C语言编程的基本规范有哪些?

C与VB语言联合在proteus上仿真实例的工程文件免费下载

本文档的主要内容详细介绍的是C与VB语言联合在proteus上仿真实例的工程文件免费下载。
发表于 02-23 08:00 14次 阅读
C与VB语言联合在proteus上仿真实例的工程文件免费下载

单片机应用编程技巧那些常见的问题有哪些?

C语言和汇编语言在开发单片机时各有哪些优缺点?   C或汇编语言可以用于单片机,C++能吗?   搞单片机...
发表于 02-23 06:10 0次 阅读
单片机应用编程技巧那些常见的问题有哪些?

嵌入式C语言的高级用法

内存管理 我们需要知道——变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都....
的头像 玩转单片机 发表于 02-20 14:25 135次 阅读
嵌入式C语言的高级用法

单片机为什么要使用C语言看了就知道

单片机为什么要使用C语言?
发表于 02-19 06:18 0次 阅读
单片机为什么要使用C语言看了就知道

为什么中断处理函数不能直接调用不可重入函数

1 前言 最近在公司维护的项目中碰到一个解决了定位很久的 bug , bug 找到的时候发现犯了很低....
的头像 strongerHuang 发表于 02-17 09:33 374次 阅读
为什么中断处理函数不能直接调用不可重入函数

STM32中重要的C语言知识点整理

说在前面的话 一位初学单片机的小伙伴让我推荐C语言书籍,因为C语言基础比较差,想把C语言重新学一遍,....
的头像 嵌入式ARM 发表于 02-10 17:31 352次 阅读
STM32中重要的C语言知识点整理

单片机C语言学习架构

单片机C语言学习架构分享
发表于 02-05 07:35 0次 阅读
单片机C语言学习架构

使用单片机C语言程序实现电子秤仿真设计的实例免费下载

本文档的主要内容详细介绍的是使用单片机C语言程序实现电子秤仿真设计的实例免费下载。
发表于 02-04 16:25 117次 阅读
使用单片机C语言程序实现电子秤仿真设计的实例免费下载

C语言开发单片机为啥都是全局变量形式?

全局变量简直就是嵌入式系统的戈兰高地。冲突最激烈的双方是: 1. 做控制的工程师; 2. 做非嵌入式....
发表于 02-04 06:14 37次 阅读
C语言开发单片机为啥都是全局变量形式?

C语言多线程的详细教程资料说明

Windows是一个多任务的系统,如果你使用的是windows 2000及其以上版本,你可以通过任务....
发表于 02-03 17:02 49次 阅读
C语言多线程的详细教程资料说明

51单片机C语言常用模块与综合系统设计实例精讲的PDF电子书免费下载

《51单片机C语言常用模块与综合系统设计实例精讲》全书针对目前最通用流行的51单片机系列,通过大量典....
发表于 02-03 10:40 74次 阅读
51单片机C语言常用模块与综合系统设计实例精讲的PDF电子书免费下载

C语言嵌入式系统编程注意事项

C语言嵌入式系统编程注意事项 C语言嵌入式系统软件架构 单任务程序典型架构 ...
发表于 02-03 07:44 0次 阅读
C语言嵌入式系统编程注意事项

如何在C代码中插入寄存器?

对于逻辑级数较高的路径,常用的方法之一是在其中插入流水寄存器,将路径打断,从而降低逻辑延迟,这在HD....
的头像 Lauren的FPGA 发表于 02-02 17:07 312次 阅读
如何在C代码中插入寄存器?

Verilog数字系统设计教程的PDF电子书免费下载

数字信号处理(DSP)系统的研究人员一直在努力寻找各种优化的算法来解决相关的信号处理问题。当他们产生....
发表于 02-02 16:19 48次 阅读
Verilog数字系统设计教程的PDF电子书免费下载

使用单片机C语言实现步进电机正反转的实例免费下载

本文档的主要内容详细介绍的是使用单片机C语言实现步进电机正反转的实例免费下载。
发表于 02-02 11:19 71次 阅读
使用单片机C语言实现步进电机正反转的实例免费下载

使用单片机C语言实现消防车警报的实例程序和工程文件免费下载

本文档的主要内容详细介绍的是使用单片机C语言实现消防车警报的实例程序和工程文件免费下载。
发表于 02-02 10:48 43次 阅读
使用单片机C语言实现消防车警报的实例程序和工程文件免费下载

使用单片机C语言实现步进电机转动原理的实例程序和工程文件免费下载

本文档的主要内容详细介绍的是使用单片机C语言实现步进电机转动原理的实例程序和工程文件免费下载。
发表于 02-02 10:48 63次 阅读
使用单片机C语言实现步进电机转动原理的实例程序和工程文件免费下载

使用单片机C语言实现音乐播放的实例程序和工程文件免费下载

本文档的主要内容详细介绍的是使用单片机C语言实现音乐播放的实例程序和工程文件免费下载。
发表于 02-02 10:48 40次 阅读
使用单片机C语言实现音乐播放的实例程序和工程文件免费下载

从最底层的内存存储空间开始带你了解C语言指针

一、前言 二、变量与指针的本质 三、指针的几个相关概念 四、指向不同数据类型的指针 五、总结 一、前....
的头像 嵌入式ARM 发表于 02-02 10:40 190次 阅读
从最底层的内存存储空间开始带你了解C语言指针

单片机C语言的学习架构

单片机C语言学习架构分享
发表于 02-02 07:03 0次 阅读
单片机C语言的学习架构

单片机C语言程序设计实例之使用74HC595控制数码管显示四位数字

本文档的主要内容详细介绍的是单片机C语言程序设计实例之使用串入并出芯片74HC595控制数码管显示四....
发表于 02-01 16:45 77次 阅读
单片机C语言程序设计实例之使用74HC595控制数码管显示四位数字

单片机C语言程序设计实例之双向来回的流水灯

本文档的主要内容详细介绍的是单片机C语言程序设计实例之双向来回的流水灯免费下载。
发表于 02-01 16:45 61次 阅读
单片机C语言程序设计实例之双向来回的流水灯

单片机C语言程序设计实例之带日历时钟及温度显示的电子万年历

本文档的主要内容详细介绍的是单片机C语言程序设计实例之带日历时钟及温度显示的电子万年历程序和工程文件....
发表于 02-01 16:45 52次 阅读
单片机C语言程序设计实例之带日历时钟及温度显示的电子万年历

单片机C语言程序设计实例之闪烁的LED

本文档的主要内容详细介绍的是单片机C语言程序设计实例之闪烁的LED程序和工程文件免费下载。
发表于 02-01 16:45 58次 阅读
单片机C语言程序设计实例之闪烁的LED

C51单片机C语言程序设计解析的学习课件免费下载

C语言程序采用函数结构,每个C语言程序由一个或多个函数组成,在这些函数中至少应包含一个主函数main....
发表于 02-01 09:58 66次 阅读
C51单片机C语言程序设计解析的学习课件免费下载

C语言经典算法分享

C语言经典算法
发表于 02-01 07:45 0次 阅读
C语言经典算法分享

手把手教你学51单片机的C语言版PDF电子书免费下载

本书旨在培养和锻炼单片机系统实用开发技能,全书以实践为主线,让读者在一个个实践案例中逐步掌握单片机电....
发表于 01-27 08:00 145次 阅读
手把手教你学51单片机的C语言版PDF电子书免费下载

使用单片机实现LED循环右移的C语言实例免费下载

  本文档的主要内容详细介绍的是使用单片机实现LED循环右移的C语言实例免费下载。
发表于 01-26 17:23 60次 阅读
使用单片机实现LED循环右移的C语言实例免费下载

使用单片机实现LED循环左移的C语言实例免费下载

本文档的主要内容详细介绍的是使用单片机实现LED循环左移的C语言实例免费下载。
发表于 01-26 17:16 51次 阅读
使用单片机实现LED循环左移的C语言实例免费下载

C语言要如何面向对象编程?

一、前言 在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的....
的头像 嵌入式ARM 发表于 01-26 09:58 268次 阅读
C语言要如何面向对象编程?

VHDL硬件描述语言的学习课件免费下载

本文档的主要内容详细介绍的是VHDL硬件描述语言的学习课件免费下载包括了:VHDL概述,VHDL数据....
发表于 01-22 08:00 42次 阅读
VHDL硬件描述语言的学习课件免费下载

HC6800-ES V1.0单片机开发板的实验指导书免费下载

本开发板相对以往开发板的特点是综合性比较高、把短路冒去掉了 省去接线的麻烦更加方便了初学者、是一款性....
发表于 01-21 08:00 49次 阅读
HC6800-ES V1.0单片机开发板的实验指导书免费下载

51单片机的硬件与工作原理的详细资料说明

本文档的主要内容详细介绍的是51单片机的硬件与工作原理的详细资料说明包括了:1、51单片机的硬件与工....
发表于 01-19 17:21 96次 阅读
51单片机的硬件与工作原理的详细资料说明

FPGA的零基础入门教程

本文档的主要内容详细介绍的是FPGA的零基础入门教程免费下载。
发表于 01-18 16:47 89次 阅读
FPGA的零基础入门教程

全局变量简直就是嵌入式系统的戈兰高地

要成为一个资深的嵌入式工程师相当难,一方面要有非常扎实的理论知识,同时也要有相当的那种大型的、高频C....
的头像 MCU开发加油站 发表于 01-18 16:26 642次 阅读
全局变量简直就是嵌入式系统的戈兰高地

C语言与C++相互调用

    1C与C++相互调用 在一个嵌入式系统中大部分的底层和驱动层更多的是采用C语言来进行开发,而....
的头像 strongerHuang 发表于 01-18 11:05 305次 阅读
C语言与C++相互调用

MS8006C参数特性介绍 32位MCU ARM® Cortex®-M0+ 内核

MS8006 是一款内嵌 32 位 ARM® Cortex®-M0+ 内核的超低功耗、Low Pin....
发表于 01-18 09:17 165次 阅读
MS8006C参数特性介绍 32位MCU  ARM® Cortex®-M0+ 内核

MS8005参数特性介绍 通用8051 Core MCU 256 字节 RAM内核

MS8005 是通用型 1T 8051 Core MCU。在同样的系统时钟下,比传统的 8051 运....
发表于 01-18 09:12 256次 阅读
MS8005参数特性介绍 通用8051 Core MCU 256 字节 RAM内核

学习ARM的学习历程和资料说明

说实话,入门真的很痛苦,那种徘徊再门外而不得要领的感觉真的很痛苦, 论坛上大多数教程啊例子什么的都是....
发表于 01-15 17:56 95次 阅读
学习ARM的学习历程和资料说明

51单片机的C语言程序设计学习课件免费下载

本文档的主要内容详细介绍的是51单片机的C语言程序设计学习课件免费下载包括了:C51语言概述,C51....
发表于 01-15 17:56 96次 阅读
51单片机的C语言程序设计学习课件免费下载

DSP芯片的原理及开发应用讲解的PDF电子书免费下载

信号处理( Digital Signal Processing,简称DSP)是一门涉及多学犭领域的新....
发表于 01-15 17:40 106次 阅读
DSP芯片的原理及开发应用讲解的PDF电子书免费下载

基于浮点C语言编程的计算密集DSP算法实现语音识别芯片结构的设计

新加坡Columns公司在便携式语音控制产品应用中起步较早,其中一个产品是执行欧元与其他欧洲货币之间....
的头像 电子设计 发表于 01-14 09:41 743次 阅读
基于浮点C语言编程的计算密集DSP算法实现语音识别芯片结构的设计

C语言中的位域是什么?

位域是什么? 有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关....
的头像 玩转单片机 发表于 01-13 16:23 343次 阅读
C语言中的位域是什么?

OpenCV课程分享 怎么在C#中使用OpenCV

  转自:jsxyhelu  在此特别鸣谢! cnblogs.com/jsxyhelu/p/GOCW....
的头像 新机器视觉 发表于 01-12 16:32 466次 阅读
OpenCV课程分享 怎么在C#中使用OpenCV

哪种编程语言是最难的

【导语】:可能会引起争论,但是我们不怕事儿大!Python难还是其它语言难?这里真的很想和大家讨论究....
的头像 Linux爱好者 发表于 01-11 10:41 446次 阅读
哪种编程语言是最难的

C语言程序设计的学习课件免费下载

本文档的主要内容详细介绍的是C语言程序设计的学习课件免费下载包括了:第一章C语言概述,第二章算法,第....
发表于 01-11 08:00 207次 阅读
C语言程序设计的学习课件免费下载

在计算机软件领域 C语言之父和Linux之父谁更伟大

  前言 在计算机软件领域,做出过重大贡献的神人很多,在这闪耀的明星中,最为闪耀的莫过于「Linus....
的头像 嵌入式ARM 发表于 01-10 09:13 1016次 阅读
在计算机软件领域 C语言之父和Linux之父谁更伟大

单片机的程序开发经常会出现那些错误

这里利用一个实际发生的例子,针对初级工程师经常犯的一个小错误,或者经常要走的一个弯路,做了针对性的纠....
的头像 Wildesbeast 发表于 01-09 10:41 407次 阅读
单片机的程序开发经常会出现那些错误

用哪种编程语言写的应用漏洞最严重 Java还是Python

静态代码分析安全公司 Veracode 近日发布了一份应用程序分析报告,结果发现比起 JavaScr....
的头像 数据分析与开发 发表于 01-06 16:19 398次 阅读
用哪种编程语言写的应用漏洞最严重 Java还是Python

嵌入式C语言的7个关键知识点详细说明

1 void 与 void* void表示的是无类型,不可以采用这个类型声明变量或常量,但是可以把指....
发表于 01-03 18:08 634次 阅读
嵌入式C语言的7个关键知识点详细说明

各种编程语言的能耗对比

  上次跟大家分享了即将淘汰的编程语言,看来大家对于编程语言的好坏,都很有自己的见解啊。 但我们一直....
的头像 嵌入式ARM 发表于 12-30 10:27 474次 阅读
各种编程语言的能耗对比

10个C语言程序设计实训报告资料免费下载

本文档的主要内容详细介绍的是10个C语言程序设计实训报告资料免费下载。
发表于 12-29 08:00 82次 阅读
10个C语言程序设计实训报告资料免费下载

如何提高我国少儿教育质量,少儿编程教育有大优势

“在我们身处的这个世界里,从城市交通、桥梁结构到空气质量、地质演变,再到人际互动和经济活动,无不可以....
发表于 12-28 11:35 140次 阅读
如何提高我国少儿教育质量,少儿编程教育有大优势

C语言和C++的特点与用法详细说明

本文档的主要内容详细介绍的是C语言和C++的特点与用法详细说明。
的头像 Wildesbeast 发表于 12-26 10:58 286次 阅读
C语言和C++的特点与用法详细说明