精华内容
下载资源
问答
  • 当你开始编写C程序时,你可能对C语言的一些基本问题感到困惑,如C语言所使用约定、关键字和术语等。本章将回答这方面你经常会遇到一些问题。 例如,switch语句是最常用一种C语言构件,本章将回答与它有关...
  • 1、背景:用一个丢骰子简单案例熟悉了C语言多文件编程该咋写2、格式(1)主函数文件main.c//文件头part1:所有要使用函数#include;#include;#includ...

    1、背景:

    用一个丢骰子的简单案例熟悉了C语言多文件编程该咋写

    2、格式

    (1)主函数文件main.c

    //文件头part1:所有要使用的函数#include ;#include ;#include ;//文件头part2:放所有函数原型的文件#inlucde "main.h"//文件头part3:各个要使用的子文件#include "funciton1.c"#inlucde "function2.c"int main(){
      function1();   //在function1.c
      function2();   //在function2.c
      return 0;}

    (2)乘放所有函数原型、全局变量的文件main.h

    void function1(void);void function2(void);/*
    这里有2个知识点或者说优秀编程规范
    1、对全局数据使用const,防止暴露数据
    2、头文件方案可以偷懒而不使用“一个文件中定义式声明,其他文件使用extern引用式声明”对方案,但是必须加static。不然file1.c和file2.c都包含main.h,那么这2个文件就都有一个相同的定义式声明,大多数编译器不允许这么做
    */static const int a = 10;static const double b = 20'

    (3) 放各个函数的子文件(示例:function1.c)

    void function1(void){
            具体函数逻辑}

    3、案例:丢骰子

    (1)主函数

    #include #include #include "main.h"#include "random.c"#include "roll.c"/*
    1、要求用户输入骰子数、骰子的面数;输出掷出的结果;
    2、随机数的生成种子基于time()生成真随机数
    3、支持循环输入
    4、能处理以下错误情况:
    (1)side小于1
    (2)输入类型不匹配
    (3)遇到EOF
    *//*伪算法:
    int main(){
        输入函数:骰子数(报错处理)、面数(报错处理)
        循环(当不报错的时候){
            丢骰子函数(骰子数、骰子的面数);
            输入函数;
        }
    }
    
    丢骰子函数(骰子数、骰子的面数){
        while(<骰子数){
            随机数函数(骰子的面数)
        }
        数组存储(所有随机数结果);
        对数组求和;
        输出结果(骰子数、骰子的面数、数组求和结果)
    }
    
    随机数函数(骰子的面数){
        种子 = (时间函数返回的某个数)
        输出结果 = 种子  % 骰子的面数
    }
    */int main(){
        int rolls,sides,result;
        //输入函数部分
        printf("please input the num of rolls you wanna use:");
        if(scanf("%d",&rolls) !=  1){
            printf("you should have input one num.\n");
        };
        if(rolls = 1){
            printf("you use %d rolls with %d sides, and your result is %d\n",rolls,sides,roll(rolls,sides));
    
            printf("Another??? please input the num of rolls you wanna use:");
            if(scanf("%d",&rolls) !=  1){
                printf("you should have input one num.\n");
            };
            if(rolls < 1){
                printf("you should use 1 roll at least\n");
            }
    
            printf("How many sides a roll have?  ");
            if(scanf("%d",&sides) !=  1){
                printf("you should have input one num.\n");
            };
            if(sides < 1){
                printf("you should use 1 sides at least\n");
            }       
        }
        
        
        //-test输入函数
        return 0;}

    (2)main.h

    //这里存放丢骰子函数的函数声明//丢骰子函数int roll(int rolls,int sides);//随机数函数int my_random(int sides);

    (3)丢骰子函数

    int roll(int rolls,int sides){
        int result = 0;
        int list[rolls];
        for(int i = 0; i < rolls;i++){
            list[i] = my_random(sides);
        }
        for(int i = 0 ;i < rolls;i++){
            result += list[i];
        }
        return result;}/*
    丢骰子函数(骰子数、骰子的面数){
        while(<骰子数){
            随机数函数(骰子的面数)
        }
        数组存储(所有随机数结果);
        对数组求和;
        输出结果(骰子数、骰子的面数、数组求和结果)
    }
    */

    (4)随机数函数

    /*
    随机数函数(骰子的面数){
        种子 = (时间函数返回的某个数)
        输出结果 = 种子  % 骰子的面数
    }
    */int my_random(int sides){
        int seed = (unsigned int)time(0);
        seed = seed % sides + 1;
        return seed;}
    nk:href="#ic-like">

    来源:https://www.jianshu.com/p/4ce2ed1a0764

    展开全文
  • C语言编程基本规范

    2017-09-02 16:00:05
    C语言编程基本规范 为了提高源程序质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进行程序设计时必须遵循规范。本规范主要针对单片机编程语言和08编译器而言,包括...
                                                      C语言编程基本规范

    为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进行程序设计时必须遵循的规范。本规范主要针对单片机编程语言和08编译器而言,包括排版、注释、命名、变量使用、代码可测性、程序效率、质量保证等内容。 
    1.基本规则 
    格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度的可扩展性、单片机编程规范-标识符命名 
    2.标识符命名 2.1 命名基本原则 
    (1)命名清晰明了,有明确含义,使用完整单词或约定俗成的缩写。通常,较短的单词可通过去掉元音字母形成缩写;较长的单词可取单词的头几个字母形成缩写。即"见名知意"。(2)命名风格要自始至终保持一致。 
    (3)命名中若使用特殊约定或缩写,要有注释说明。
    (4)同一软件产品内模块之间接口部分的标识符名称之前加上模块标识。
    2.2 宏和常量命名 
    宏和常量用全部大写字母来命名,词与词之间用下划线分隔。对程序中用到的数字均应用有意义的枚举或宏来代替。
    2.3 变量命名 
    变量名用小写字母命名,每个词的第一个字母大写。类型前缀(u8\s8 etc.)全局变量另加前缀g_。
    局部变量应简明扼要。局部循环体控制变量优先使用i、j、k等;局部长度变量优先使用len、num等;临时中间变量优先使用temp、tmp等。
    2.4 函数命名 
    函数名用小写字母命名,每个词的第一个字母大写,并将模块标识加在最前面。
    2.5 文件命名 
    一个文件包含一类功能或一个模块的所有函数,文件名称应清楚表明其功能或性质。
    每个.c文件应该有一个同名的.h文件作为头文件。 
    3.注释 3.1 注释基本原则 
    有助于对程序的阅读理解,说明程序在"做什么",解释代码的目的、功能和采用的方法。
    一般情况源程序有效注释量在30%左右。
    注释语言必须准确、易懂、简洁。
    边写代码边注释,修改代码同时修改相应的注释,不再有用的注释要删除。
    汇编和C中都用"//",取消";" 不使用段注释" /* */ "(调试时可用) 
    3.2 文件注释 
    文件注释必须说明文件名、函数功能、创建人、创建日期、版本信息等相关信息。
    修改文件代码时,应在文件注释中记录修改日期、修改人员,并简要说明此次修改的目的。所有修改记录必须保持完整。
    文件注释放在文件顶端,用"/*……*/"格式包含。
    注释文本每行缩进4个空格;每个注释文本分项名称应对齐。
    /***********************************************************
    文件名称:
    作 者:
    版 本:
    说 明:
    修改记录:
    ***********************************************************/
    3.3 函数注释 
    3.3.1 函数头部注释
    函数头部注释应包括函数名称、函数功能、入口参数、出口参数等内容。如有必要还可增加作者、创建日期、修改记录(备注)等相关项目。
    函数头部注释放在每个函数的顶端,用"/*……*/"的格式包含。其中函数名称应简写为Name(),不加入、出口参数等信息。
    /***********************************************************
    函数名称:
    函数功能:
    入口参数:
    出口参数:
    备 注:
    ***********************************************************/
    3.3.2 代码注释
    代码注释应与被注释的代码紧邻,放在其上方或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开。一般少量注释应该添加在被注释语句的行尾,一个函数内的多个注释左对齐;较多注释则应加在上方且注释行与被注释的语句左对齐。
    函数代码注释用"//…//"的格式。
    通常,分支语句(条件分支、循环语句等)必须编写注释。其程序块结束行"}"的右方应加表明该程序块结束的标记"end of ……", 尤其在多重嵌套时。
    3.4 变量、常量、宏的注释 
    同一类型的标识符应集中定义,并在定义之前一行对其共性加以统一注释。对单个标识符的注释加在定义语句的行尾。
    全局变量一定要有详细的注释,包括其功能、取值范围、哪些函数或过程存取它以及存取时的注意事项等。
    注释用"//…//"的格式。 
    4.函数 4.1 函数设计原则 
    函数的基本要求: 
    1)封装性
    1) 正确性:程序要实现设计要求的功能。
    2) 稳定性和安全性:程序运行稳定、可靠、安全。
    3) 可测试性:程序便于测试和评价。
    4) 规范/可读性:程序书写风格、命名规则等符合规范。
    5) 扩展性:代码为下一次升级扩展留有空间和接口。
    6) 全局效率:软件系统的整体效率高。
    7) 局部效率:某个模块/子模块/函数的本身效率高。
    编制函数的基本原则:
    1) 单个函数的规模尽量限制在200行以内(不包括注释和空行)。一个函数只完成一个功能。
    2) 函数局部变量的数目一般不超过5~10个。
    3) 函数内部局部变量定义区和功能实现区(包含变量初始化)之间空一行。
    4) 函数名应准确描述函数的功能。通常使用动宾词组为执行某操作的函数命名。
    5) 函数的返回值要清楚明了,尤其是出错返回值的意义要准确无误。
    6) 不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方式作为返回值返回。
    7) 减少函数本身或函数间的递归调用。
    8) 尽量不要将函数的参数作为工作变量。
    4.2 函数定义 
    1) 函数若没有入口参数或者出口参数,应用void明确申明。
    2) 函数名称与出口参数类型定义间应该空一格且只空一格。
    3) 函数名称与括号()之间无空格。
    4) 函数形参必须给出明确的类型定义。
    5) 多个形参的函数,后一个形参与前一个形参的逗号分割符之间添加一个空格。
    6) 函数体的前后花括号"{}" 各独占一行。
    4.3 局部变量定义 
    1) 同一行内不要定义过多变量。
    2) 同一类的变量在同一行内定义,或者在相邻行定义。
    3) 先定义data型变量,再定义idtata型变量,再定义xdata型变量.(?)
    4) 数组、指针等复杂类型的定义放在定义区的最后。
    5) 变量定义区不做较复杂的变量赋值。
    4.4 功能实现区规范 
    1) 一行只写一条语句。
    2) 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。
    3) 各程序段之间使用一个空行分隔,加以必要的注释。程序段指能完一个较具体的功能的一行或多行代码。程序段内的各行代码之间相互依赖性较强。(1、2、3方式)
    4) 不要使用难懂的技巧性很高的语句。
    5) 源程序中关系较为紧密的代码应尽可能相邻。
    6) 完成简单功能、关系非常密切的一条或几条语句可编写为函数或定义为宏。 
    5. 单片机编程规范-排版 
    5.1 缩进 
    代码的每一级均往右缩进4个空格的位置。不使用Tab键 
    5.2 分行 
    每行语句(?????超过80个字符)要分成多行书写;长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进适当的缩进,使排版整齐,语句可读。避免把注释插入分行中。
    5.3 空行 
    1) 文件注释区、头文件引用区、函数间应该有且只有一行空行。
    2) 相邻函数之间应该有且只有一行空行。
    3) 函数体内相对独立的程序块之间可以用一行空行或注释来分隔。
    4) 函数注释和对应的函数体之间不应该有空行。
    5) 文件末尾有且只有一行空行。
    5.4 空格 
    1) 函数语句尾部或者注释之后不能有空格。
    2) 括号内侧(即左括号后面和右括号前面)不加空格,多重括号间不加空格。
    3) 函数形参之间应该有且只有一个空格(形参逗号后面加空格)。
    4) 同一行中定义的多个变量间应该有且只有一个空格(变量逗号后面加空格)。
    5) 表达式中,若有多个操作符连写的情况,应使用空格对它们分隔:
    6) 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符前后均加一个空格;在两个以上的关键字、变量、常量进行非对等操作时,其前后均不应加空格;
    7) 逗号只在后面加空格;
    8) 双目操作符,如比较操作符, 赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位操作符"<<"、"^"等,前后均加一个空格;
    9) 单目操作符,如"!"、"~"、"++"、"-"、"&"(地址运算符)等,前后不加空格;
    10) "->"、"."前后不加空格;
    11) if、for、while、switch等关键字与后面的括号间加一个空格;
    5.5 花括号 
    1) if、else if、else、for、while语句无论其执行体是一条语句还是多条语句都必须加花括号,且左右花括号各独占一行。
    2) do{}while()结构中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。
    if ( ) do
    { {
    } }while( );
    else
    {
    }
    嵌套越少越好,{}不准超过3层
    5.6 switch语句 
    1) 每个case和其判据条件独占一行。
    2) 每个case程序块需用break结束。特殊情况下需要从一个case块顺序执行到下一个case块的时候除外,但需要花括号在交界处明确注释如此操作的原因,以防止出错。
    3) case程序块之间空一行,且只空一行。
    4) 每个case程序块的执行语句保持4个空格的缩进。
    5) 一般情况下都应该包含default分支。
    Switch ( )
    {
    case x:
    break;
    case x:
    break;
    default:
    break;
    }
    6.程序结构 6.1 基本要求 
    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。
    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。
    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。
    在.c文件中:

    define FILE_FLAG

    在.h文件中:&
    6.程序结构 6.1 基本要求 
    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。
    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。
    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。
    在.c文件中:

    define FILE_FLAG

    在.h文件中:

    ifdef FILE_FLAG

    define XXX

    else

    define XXX extern

    endif

    4) 对于确定只被某个.c文件调用的定义可以单独列在一个头文件中、单独调用。
    6.2 可重入函数 
    可重入函数中若使用了全局变量,应通过关中断、信号量等操作手段对其加以保护。
    6.3 函数的形参 
    1) 由函数调用者负责检查形参的合法性。
    2) 尽量避免将形参作为工作变量使用。
    6.4 循环 
    1) 尽量减少循环嵌套层数
    2) 在多重循环中,应将最忙的循环放在最内层
    3) 循环体内工作量最小
    4) 尽量避免循环体内含有判断语句
    7.工程中所包含的文件 7.1 头文件 
    7.1.1 头文件的形式
    MCU程序中的头文件包括面向硬件对象头文件、公共头文件和总头文件。
    MCU C工程编程是面向硬件对象的。例如,要用MCU控制电机(Motor),在这样一个系统中,“面向硬件对象”概念体现在,工程中会创建“Motor.c”的源程序文件专门用于电机控制。相应的,也要创建一个同名头文件“Motor.h”,用于控制电机的MCU引脚定义、相关宏定义和电机控制函数声明等。像这样的头文件,就是面向硬件对象头文件。与之同名的“*.c”文件可以包含它,来完成控制此硬件对象的MCU引脚定义和相关宏定义;调用该硬件对象控制函数的文件也可以通过调用它来进行函数声明。
    还有一类头文件不是专门针对于特定的硬件对象的,而是有一定的通用性。这类头文件被称为公共头文件。如工程中包含的“Type.h”文件,该文件用于C语言中类型的别名定义,用户还可以根据自己的需要,随时在该文件中添加条目。在工程的任一文件中,需要用到这些别名时,都要包含“Type.h”。可见公共头文件并不拘泥于具体的硬件对象,它是为整个工程的和谐运作而建立的。
    总头文件(includes.h)是一个较特殊的头文件。它只被主函数文件包含,用于包含主函数文件中需要的头文件,宏定义,函数声明等。它使得主函数文件能够尽量避免改动,结构更加清晰。
    7.1.2 头文件的命名
    总的来说头文件的命名应尽量做到简短易懂,见名知意。
    面向硬件对象头文件的名称一定要与相应的硬件对象驱动文件同名。例???
    公共头文件,如果对应于相应的源程序文件而建立,必须与之同名。如,“GeneralFun.c”
    是工程中的通用函数定义文件,(像内存数据移动函数,延时函数都属于通用函数),其他文件在用到这些函数之前,必须进行函数原型声明,从而建立与之同名的“GeneralFun.h”文件,专门用于相应的函数声明。其它的公共头文件没有同名要求,只要表清文件含义即可,如“Type.h”,“GP32C.h”等。
    总头文件在一个工程中只有一个,它的名称较为固定,一般取为“Includes.h”。
    7.1.3 头文件注意事项
    1) 为了防止重复定义需要使用伪指令 #ifndef VarType ……
    例:

    ifndef VarType

    define VarType

    typedef unsigned char INT8U; //无符号8位数
    typedef signed char INT8S; //有符号8位数
    typedef unsigned int INT16U; //无符号16位数
    typedef signed int INT16S; //有符号16位数
    typedef unsigned long INT32U; //无符号32位数
    typedef signed long INT32S; //有符号32位数
    typedef float FP32; //单精度浮点数
    typedef double FP64; //双精度浮点数

    endif

    2) 对于一个项目中的头文件与芯片相关的寄存器映像文件不可擅自改动,如果的确存在需要改动的地方另外开辟头文件。
    3) typedef和#define的用法
    ① typedef的用法
    在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:
    typedef int INT;
    typedef int ARRAY[10];
    typedef (int*) pINT;
    typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。
    ② #define的用法

    define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

    define INT int

    define TRUE 1

    define Add(a,b) ((a)+(b));

    define Loop_10 for (int i=0; i<10; i++)

    ③ typedef与#define的区别
    从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。
    宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:
    typedef (int*) pINT;
    以及下面这行:

    define pINT2 int*

    效果相同?实则不同!实践中见差别:
    pINT a,b;的效果同int *a; int *b;
    表示定义了两个整型指针变量。
    而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。
    注意:两者还有一个行尾;号的区别哦!(???)
    7.2 源程序文件 
    源程序文件包括主函数文件、通用函数文件、硬件对象控制文件、芯片初始化文件、中断向量定义文件和中断使能文件。
    源程序文件的分类和命名类同于头文件,但也有它自己的特点。
    7.2.1 主程序文件
    (Main.s 或 Main.c)(?????)
    工程中有且仅有一个主程序文件,它包含了工程的主处理流程。
    主函数文件中包含:
    (1)工程描述
    ①工程名
    工程名中每个意义单词(或单词缩写)的首字母大写,后缀为.prj。
    ②硬件连接索引
    工程所要控制的硬件对象索引,详细描述在相应的硬件对象控制文件中给出。
    ③工程的功能、目的和说明
    ④注意要点
    可以注明编程要点和心得
    ⑤日期
    注明工程完成日期
    (2)总头文件
    (3)主函数

    展开全文
  • 为了提高源程序质量和可维护性,从而最终...1.基本规则格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度可扩展性、单片机编程规范-标识符...

    为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进行程序设计时必须遵循的规范。本规范主要针对单片机编程语言和08编译器而言,包括排版、注释、命名、变量使用、代码可测性、程序效率、质量保证等内容。

    1.基本规则

    格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度的可扩展性、单片机编程规范-标识符命名

    2.标识符命名 2.1 命名基本原则

    (1)命名清晰明了,有明确含义,使用完整单词或约定俗成的缩写。通常,较短的单词可通过去掉元音字母形成缩写;较长的单词可取单词的头几个字母形成缩写。即"见名知意"。(2)命名风格要自始至终保持一致。

    (3)命名中若使用特殊约定或缩写,要有注释说明。

    (4)同一软件产品内模块之间接口部分的标识符名称之前加上模块标识。

    2.2 宏和常量命名

    宏和常量用全部大写字母来命名,词与词之间用下划线分隔。对程序中用到的数字均应用有意义的枚举或宏来代替。

    2.3 变量命名

    变量名用小写字母命名,每个词的第一个字母大写。类型前缀(u8\s8 etc.)全局变量另加前缀g_。

    局部变量应简明扼要。局部循环体控制变量优先使用i、j、k等;局部长度变量优先使用len、num等;临时中间变量优先使用temp、tmp等。

    2.4 函数命名

    函数名用小写字母命名,每个词的第一个字母大写,并将模块标识加在最前面。

    2.5 文件命名

    一个文件包含一类功能或一个模块的所有函数,文件名称应清楚表明其功能或性质。

    每个.c文件应该有一个同名的.h文件作为头文件。

    3.注释 3.1 注释基本原则

    有助于对程序的阅读理解,说明程序在"做什么",解释代码的目的、功能和采用的方法。

    一般情况源程序有效注释量在30%左右。

    注释语言必须准确、易懂、简洁。

    边写代码边注释,修改代码同时修改相应的注释,不再有用的注释要删除。

    汇编和C中都用"//",取消";"  不使用段注释" /*  */ "(调试时可用)

    3.2 文件注释

    文件注释必须说明文件名、函数功能、创建人、创建日期、版本信息等相关信息。

    修改文件代码时,应在文件注释中记录修改日期、修改人员,并简要说明此次修改的目的。所有修改记录必须保持完整。

    文件注释放在文件顶端,用"/*……*/"格式包含。

    注释文本每行缩进4个空格;每个注释文本分项名称应对齐。

    /***********************************************************

    文件名称:

    作 者:

    版 本:

    说 明:

    修改记录:

    ***********************************************************/

    3.3 函数注释

    3.3.1 函数头部注释

    函数头部注释应包括函数名称、函数功能、入口参数、出口参数等内容。如有必要还可增加作者、创建日期、修改记录(备注)等相关项目。

    函数头部注释放在每个函数的顶端,用"/*……*/"的格式包含。其中函数名称应简写为Name(),不加入、出口参数等信息。

    /***********************************************************

    函数名称:

    函数功能:

    入口参数:

    出口参数:

    备 注:

    ***********************************************************/

    3.3.2 代码注释

    代码注释应与被注释的代码紧邻,放在其上方或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开。一般少量注释应该添加在被注释语句的行尾,一个函数内的多个注释左对齐;较多注释则应加在上方且注释行与被注释的语句左对齐。

    函数代码注释用"//…//"的格式。

    通常,分支语句(条件分支、循环语句等)必须编写注释。其程序块结束行"}"的右方应加表明该程序块结束的标记"end of ……", 尤其在多重嵌套时。

    3.4 变量、常量、宏的注释

    同一类型的标识符应集中定义,并在定义之前一行对其共性加以统一注释。对单个标识符的注释加在定义语句的行尾。

    全局变量一定要有详细的注释,包括其功能、取值范围、哪些函数或过程存取它以及存取时的注意事项等。

    注释用"//…//"的格式。

    4.函数 4.1 函数设计原则

    函数的基本要求:

    1)封装性

    1) 正确性:程序要实现设计要求的功能。

    2) 稳定性和安全性:程序运行稳定、可靠、安全。

    3) 可测试性:程序便于测试和评价。

    4) 规范/可读性:程序书写风格、命名规则等符合规范。

    5) 扩展性:代码为下一次升级扩展留有空间和接口。

    6) 全局效率:软件系统的整体效率高。

    7) 局部效率:某个模块/子模块/函数的本身效率高。

    编制函数的基本原则:

    1) 单个函数的规模尽量限制在200行以内(不包括注释和空行)。一个函数只完成一个功能。

    2) 函数局部变量的数目一般不超过5~10个。

    3) 函数内部局部变量定义区和功能实现区(包含变量初始化)之间空一行。

    4) 函数名应准确描述函数的功能。通常使用动宾词组为执行某操作的函数命名。

    5) 函数的返回值要清楚明了,尤其是出错返回值的意义要准确无误。

    6) 不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方式作为返回值返回。

    7) 减少函数本身或函数间的递归调用。

    8) 尽量不要将函数的参数作为工作变量。

    4.2 函数定义

    1) 函数若没有入口参数或者出口参数,应用void明确申明。

    2) 函数名称与出口参数类型定义间应该空一格且只空一格。

    3) 函数名称与括号()之间无空格。

    4) 函数形参必须给出明确的类型定义。

    5) 多个形参的函数,后一个形参与前一个形参的逗号分割符之间添加一个空格。

    6) 函数体的前后花括号"{}" 各独占一行。

    4.3 局部变量定义

    1) 同一行内不要定义过多变量。

    2) 同一类的变量在同一行内定义,或者在相邻行定义。

    3) 先定义data型变量,再定义idtata型变量,再定义xdata型变量.(?)

    4) 数组、指针等复杂类型的定义放在定义区的最后。

    5) 变量定义区不做较复杂的变量赋值。

    4.4 功能实现区规范

    1) 一行只写一条语句。

    2) 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。

    3) 各程序段之间使用一个空行分隔,加以必要的注释。程序段指能完一个较具体的功能的一行或多行代码。程序段内的各行代码之间相互依赖性较强。(1、2、3方式)

    4) 不要使用难懂的技巧性很高的语句。

    5) 源程序中关系较为紧密的代码应尽可能相邻。

    6) 完成简单功能、关系非常密切的一条或几条语句可编写为函数或定义为宏。

    5. 单片机编程规范-排版

    5.1 缩进

    代码的每一级均往右缩进4个空格的位置。不使用Tab键

    5.2 分行

    每行语句(?????超过80个字符)要分成多行书写;长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进适当的缩进,使排版整齐,语句可读。避免把注释插入分行中。

    5.3 空行

    1) 文件注释区、头文件引用区、函数间应该有且只有一行空行。

    2) 相邻函数之间应该有且只有一行空行。

    3) 函数体内相对独立的程序块之间可以用一行空行或注释来分隔。

    4) 函数注释和对应的函数体之间不应该有空行。

    5) 文件末尾有且只有一行空行。

    5.4 空格

    1) 函数语句尾部或者注释之后不能有空格。

    2) 括号内侧(即左括号后面和右括号前面)不加空格,多重括号间不加空格。

    3) 函数形参之间应该有且只有一个空格(形参逗号后面加空格)。

    4) 同一行中定义的多个变量间应该有且只有一个空格(变量逗号后面加空格)。

    5) 表达式中,若有多个操作符连写的情况,应使用空格对它们分隔:

    6) 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符前后均加一个空格;在两个以上的关键字、变量、常量进行非对等操作时,其前后均不应加空格;

    7) 逗号只在后面加空格;

    8) 双目操作符,如比较操作符, 赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位操作符"<

    9) 单目操作符,如"!"、"~"、"++"、"-"、"&"(地址运算符)等,前后不加空格;

    10) "->"、"."前后不加空格;

    11) if、for、while、switch等关键字与后面的括号间加一个空格;

    5.5 花括号

    1)  if、else if、else、for、while语句无论其执行体是一条语句还是多条语句都必须加花括号,且左右花括号各独占一行。

    2)  do{}while()结构中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。

    if ( ) do

    { {

    } }while( );

    else

    {

    }

    嵌套越少越好,{}不准超过3层

    5.6 switch语句

    1) 每个case和其判据条件独占一行。

    2) 每个case程序块需用break结束。特殊情况下需要从一个case块顺序执行到下一个case块的时候除外,但需要花括号在交界处明确注释如此操作的原因,以防止出错。

    3) case程序块之间空一行,且只空一行。

    4) 每个case程序块的执行语句保持4个空格的缩进。

    5) 一般情况下都应该包含default分支。

    Switch ( )

    {

    case x:

    break;

    case x:

    break;

    default:

    break;

    }

    6.程序结构 6.1 基本要求

    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。

    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。

    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。

    在.c文件中:

    #define FILE_FLAG

    在.h文件中:&

    6.程序结构 6.1 基本要求

    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。

    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。

    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。

    在.c文件中:

    #define FILE_FLAG

    在.h文件中:

    #ifdef FILE_FLAG

    #define XXX

    #else

    #define XXX extern

    #endif

    4)  对于确定只被某个.c文件调用的定义可以单独列在一个头文件中、单独调用。

    6.2 可重入函数

    可重入函数中若使用了全局变量,应通过关中断、信号量等操作手段对其加以保护。

    6.3 函数的形参

    1) 由函数调用者负责检查形参的合法性。

    2) 尽量避免将形参作为工作变量使用。

    6.4 循环

    1) 尽量减少循环嵌套层数

    2) 在多重循环中,应将最忙的循环放在最内层

    3) 循环体内工作量最小

    4) 尽量避免循环体内含有判断语句

    7.工程中所包含的文件 7.1 头文件

    7.1.1  头文件的形式

    MCU程序中的头文件包括面向硬件对象头文件、公共头文件和总头文件。

    MCU C工程编程是面向硬件对象的。例如,要用MCU控制电机(Motor),在这样一个系统中,“面向硬件对象”概念体现在,工程中会创建“Motor.c”的源程序文件专门用于电机控制。相应的,也要创建一个同名头文件“Motor.h”,用于控制电机的MCU引脚定义、相关宏定义和电机控制函数声明等。像这样的头文件,就是面向硬件对象头文件。与之同名的“*.c”文件可以包含它,来完成控制此硬件对象的MCU引脚定义和相关宏定义;调用该硬件对象控制函数的文件也可以通过调用它来进行函数声明。

    还有一类头文件不是专门针对于特定的硬件对象的,而是有一定的通用性。这类头文件被称为公共头文件。如工程中包含的“Type.h”文件,该文件用于C语言中类型的别名定义,用户还可以根据自己的需要,随时在该文件中添加条目。在工程的任一文件中,需要用到这些别名时,都要包含“Type.h”。可见公共头文件并不拘泥于具体的硬件对象,它是为整个工程的和谐运作而建立的。

    总头文件(includes.h)是一个较特殊的头文件。它只被主函数文件包含,用于包含主函数文件中需要的头文件,宏定义,函数声明等。它使得主函数文件能够尽量避免改动,结构更加清晰。

    7.1.2  头文件的命名

    总的来说头文件的命名应尽量做到简短易懂,见名知意。

    面向硬件对象头文件的名称一定要与相应的硬件对象驱动文件同名。例???

    公共头文件,如果对应于相应的源程序文件而建立,必须与之同名。如,“GeneralFun.c”

    是工程中的通用函数定义文件,(像内存数据移动函数,延时函数都属于通用函数),其他文件在用到这些函数之前,必须进行函数原型声明,从而建立与之同名的“GeneralFun.h”文件,专门用于相应的函数声明。其它的公共头文件没有同名要求,只要表清文件含义即可,如“Type.h”,“GP32C.h”等。

    总头文件在一个工程中只有一个,它的名称较为固定,一般取为“Includes.h”。

    7.1.3  头文件注意事项

    1) 为了防止重复定义需要使用伪指令 #ifndef VarType ……

    例:

    #ifndef VarType

    #define VarType

    typedef unsigned char  INT8U;         //无符号8位数

    typedef signed   char  INT8S;         //有符号8位数

    typedef unsigned int   INT16U;        //无符号16位数

    typedef signed   int   INT16S;        //有符号16位数

    typedef unsigned long  INT32U;        //无符号32位数

    typedef signed   long  INT32S;        //有符号32位数

    typedef float          FP32;          //单精度浮点数

    typedef double         FP64;          //双精度浮点数

    #endif

    2) 对于一个项目中的头文件与芯片相关的寄存器映像文件不可擅自改动,如果的确存在需要改动的地方另外开辟头文件。

    3)  typedef和#define的用法

    ① typedef的用法

    在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

    typedef int INT;

    typedef int ARRAY[10];

    typedef (int*) pINT;

    typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

    ② #define的用法

    #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

    #define INT int

    #define TRUE 1

    #define Add(a,b) ((a)+(b));

    #define Loop_10 for (int i=0; i<10; i++)

    ③ typedef与#define的区别

    从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

    宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:

    typedef (int*) pINT;

    以及下面这行:

    #define pINT2 int*

    效果相同?实则不同!实践中见差别:

    pINT a,b;的效果同int *a; int *b;

    表示定义了两个整型指针变量。

    而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。

    注意:两者还有一个行尾;号的区别哦!(???)

    7.2 源程序文件

    源程序文件包括主函数文件、通用函数文件、硬件对象控制文件、芯片初始化文件、中断向量定义文件和中断使能文件。

    源程序文件的分类和命名类同于头文件,但也有它自己的特点。

    7.2.1 主程序文件

    (Main.s 或 Main.c)(?????)

    工程中有且仅有一个主程序文件,它包含了工程的主处理流程。

    主函数文件中包含:

    (1)工程描述

    ①工程名

    工程名中每个意义单词(或单词缩写)的首字母大写,后缀为.prj。

    ②硬件连接索引

    工程所要控制的硬件对象索引,详细描述在相应的硬件对象控制文件中给出。

    ③工程的功能、目的和说明

    ④注意要点

    可以注明编程要点和心得

    ⑤日期

    注明工程完成日期

    (2)总头文件

    (3)主函数

    如:

    7.2.2  芯片初始化文件(“SetUp.c”或 “SetUp.s”)

    该文件与具体的芯片型号有关,并且只包含一个芯片初始化函数,若想由编译器自动调用芯片初始化函数,其函数名必须为"_HC08Setup",否则编译器会自动建立并调用一个空的"__HC08Setup"汇编子程序,而不理会用户创建的芯片初始化函数。为了统一,将该函数起名为"MCUInit",并在主函数中调用该函数。

    7.2.3  通用函数头文件和通用函数文件

    通用函数头文件和通用函数文件,“GenneralFun.h”和“GeneralFun.c”。

    //[GenneralFun.h]通用函数头文件---------------------------------------------#i nclude"Type.h"      //类型别名定义void Delay(INT16U);   //延时函数声明

    “GenneralFun.h”中包含:

    (1)文件名

    (2)通用函数所需用到的头文件

    (3)通用函数用到的宏定义

    (4)通用函数声明

    外部函数要用到通用函数时,可包含这个头文件进行函数声明。

    7.2.4  对象控制文件

    7.2.5  中断处理函数和中断向量表文件

    9. 硬件封装的思想

    1) 与硬件相关的程序文件

    与某个硬件相关的子程序放到1个程序文件中,该硬件的头文件放到一个文件中。

    程序文件的开始处是有关说明:本文件所包含的子程序及简要的功能说明,子程序分为内部调用和外部调用;硬件的连接说明。

    2) 中断的开放和禁止

    使用宏定义方式开放或禁止中断,宏定义语句放在EnDisInt.h头文件中。宏名的定义方法:

    开放中断以Enable标识,宏名中包含中断名,宏名最后以Int结束。如:开放串行接收中断的宏名为:EnableSCIReInt。

    禁止中断以Disable标识,宏名中包含中断名,宏名最后以Int结束。如:禁止串行接收中断的宏名为:DisableSCIReInt。

    开放所有中断宏名:EnableMCUInt。

    禁止所有中断宏名:DisableMCUInt。

    699ba7046c51816a17b33a7caa85f179.png

    13

    展开全文
  • 为了提高源程序质量和可维护性,从而最终提高软件产品生产力,特编写...格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度可扩展性、单片机编...

     

    为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进行程序设计时必须遵循的规范。本规范主要针对单片机编程语言和08编译器而言,包括排版、注释、命名、变量使用、代码可测性、程序效率、质量保证等内容。 
    1.基本规则 
    格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度的可扩展性、单片机编程规范-标识符命名 
    2.标识符命名

    2.1 命名基本原则 
    (1)命名清晰明了,有明确含义,使用完整单词或约定俗成的缩写。通常,较短的单词可通过去掉元音字母形成缩写;较长的单词可取单词的头几个字母形成缩写。即"见名知意"。(2)命名风格要自始至终保持一致。 
    (3)命名中若使用特殊约定或缩写,要有注释说明。
    (4)同一软件产品内模块之间接口部分的标识符名称之前加上模块标识。
    2.2 宏和常量命名 
    宏和常量用全部大写字母来命名,词与词之间用下划线分隔。对程序中用到的数字均应用有意义的枚举或宏来代替。
    2.3 变量命名 
    变量名用小写字母命名,每个词的第一个字母大写。类型前缀(u8\s8 etc.)全局变量另加前缀g_。
    局部变量应简明扼要。局部循环体控制变量优先使用i、j、k等;局部长度变量优先使用len、num等;临时中间变量优先使用temp、tmp等。
    2.4 函数命名 
    函数名用小写字母命名,每个词的第一个字母大写,并将模块标识加在最前面。
    2.5 文件命名 
    一个文件包含一类功能或一个模块的所有函数,文件名称应清楚表明其功能或性质。
    每个.c文件应该有一个同名的.h文件作为头文件。 
    3.注释 3.1 注释基本原则 
    有助于对程序的阅读理解,说明程序在"做什么",解释代码的目的、功能和采用的方法。
    一般情况源程序有效注释量在30%左右。
    注释语言必须准确、易懂、简洁。
    边写代码边注释,修改代码同时修改相应的注释,不再有用的注释要删除。
    汇编和C中都用"//",取消";" 不使用段注释"/* */ "(调试时可用) 
    3.2 文件注释 
    文件注释必须说明文件名、函数功能、创建人、创建日期、版本信息等相关信息。
    修改文件代码时,应在文件注释中记录修改日期、修改人员,并简要说明此次修改的目的。所有修改记录必须保持完整。
    文件注释放在文件顶端,用"/*……*/"格式包含。
    注释文本每行缩进4个空格;每个注释文本分项名称应对齐。
    /***********************************************************
    文件名称:
    作 者:
    版 本:
    说 明:
    修改记录:
    ***********************************************************/
    3.3 函数注释 
    3.3.1 函数头部注释
    函数头部注释应包括函数名称、函数功能、入口参数、出口参数等内容。如有必要还可增加作者、创建日期、修改记录(备注)等相关项目。
    函数头部注释放在每个函数的顶端,用"/*……*/"的格式包含。其中函数名称应简写为Name(),不加入、出口参数等信息。
    /***********************************************************
    函数名称:
    函数功能:
    入口参数:
    出口参数:
    备 注:
    ***********************************************************/
    3.3.2 代码注释
    代码注释应与被注释的代码紧邻,放在其上方或右方,不可放在下面。如放于上方则需与其上面的代码用空行隔开。一般少量注释应该添加在被注释语句的行尾,一个函数内的多个注释左对齐;较多注释则应加在上方且注释行与被注释的语句左对齐。
    函数代码注释用"//…//"的格式。
    通常,分支语句(条件分支、循环语句等)必须编写注释。其程序块结束行"}"的右方应加表明该程序块结束的标记"end of……", 尤其在多重嵌套时。
    3.4 变量、常量、宏的注释 
    同一类型的标识符应集中定义,并在定义之前一行对其共性加以统一注释。对单个标识符的注释加在定义语句的行尾。
    全局变量一定要有详细的注释,包括其功能、取值范围、哪些函数或过程存取它以及存取时的注意事项等。
    注释用"//…//"的格式。 
    4.函数 4.1 函数设计原则 
    函数的基本要求: 
    1)封装性
    1) 正确性:程序要实现设计要求的功能。
    2) 稳定性和安全性:程序运行稳定、可靠、安全。
    3) 可测试性:程序便于测试和评价。
    4) 规范/可读性:程序书写风格、命名规则等符合规范。
    5) 扩展性:代码为下一次升级扩展留有空间和接口。
    6) 全局效率:软件系统的整体效率高。
    7) 局部效率:某个模块/子模块/函数的本身效率高。
    编制函数的基本原则:
    1) 单个函数的规模尽量限制在200行以内(不包括注释和空行)。一个函数只完成一个功能。
    2) 函数局部变量的数目一般不超过5~10个。
    3) 函数内部局部变量定义区和功能实现区(包含变量初始化)之间空一行。
    4) 函数名应准确描述函数的功能。通常使用动宾词组为执行某操作的函数命名。
    5) 函数的返回值要清楚明了,尤其是出错返回值的意义要准确无误。
    6) 不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方式作为返回值返回。
    7) 减少函数本身或函数间的递归调用。
    8) 尽量不要将函数的参数作为工作变量。
    4.2 函数定义 
    1) 函数若没有入口参数或者出口参数,应用void明确申明。
    2) 函数名称与出口参数类型定义间应该空一格且只空一格。
    3) 函数名称与括号()之间无空格。
    4) 函数形参必须给出明确的类型定义。
    5) 多个形参的函数,后一个形参与前一个形参的逗号分割符之间添加一个空格。
    6) 函数体的前后花括号"{}" 各独占一行。
    4.3 局部变量定义 
    1) 同一行内不要定义过多变量。
    2) 同一类的变量在同一行内定义,或者在相邻行定义。
    3) 先定义data型变量,再定义idtata型变量,再定义xdata型变量.(?)
    4) 数组、指针等复杂类型的定义放在定义区的最后。
    5) 变量定义区不做较复杂的变量赋值。
    4.4 功能实现区规范 
    1) 一行只写一条语句。
    2) 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。
    3) 各程序段之间使用一个空行分隔,加以必要的注释。程序段指能完一个较具体的功能的一行或多行代码。程序段内的各行代码之间相互依赖性较强。(1、2、3方式)
    4) 不要使用难懂的技巧性很高的语句。
    5) 源程序中关系较为紧密的代码应尽可能相邻。
    6) 完成简单功能、关系非常密切的一条或几条语句可编写为函数或定义为宏。 
    5. 单片机编程规范-排版 
    5.1 缩进 
    代码的每一级均往右缩进4个空格的位置。不使用Tab键 
    5.2 分行 
    每行语句(?????超过80个字符)要分成多行书写;长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进适当的缩进,使排版整齐,语句可读。避免把注释插入分行中。
    5.3 空行 
    1) 文件注释区、头文件引用区、函数间应该有且只有一行空行。
    2) 相邻函数之间应该有且只有一行空行。
    3) 函数体内相对独立的程序块之间可以用一行空行或注释来分隔。
    4) 函数注释和对应的函数体之间不应该有空行。
    5) 文件末尾有且只有一行空行。
    5.4 空格 
    1) 函数语句尾部或者注释之后不能有空格。
    2) 括号内侧(即左括号后面和右括号前面)不加空格,多重括号间不加空格。
    3) 函数形参之间应该有且只有一个空格(形参逗号后面加空格)。
    4) 同一行中定义的多个变量间应该有且只有一个空格(变量逗号后面加空格)。
    5) 表达式中,若有多个操作符连写的情况,应使用空格对它们分隔:
    6) 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符前后均加一个空格;在两个以上的关键字、变量、常量进行非对等操作时,其前后均不应加空格;
    7) 逗号只在后面加空格;
    8) 双目操作符,如比较操作符, 赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位操作符"<<"、"^"等,前后均加一个空格;
    9) 单目操作符,如"!"、"~"、"++"、"-"、"&"(地址运算符)等,前后不加空格;
    10) "->"、"."前后不加空格;
    11) if、for、while、switch等关键字与后面的括号间加一个空格;
    5.5 花括号 
    1) if、else if、else、for、while语句无论其执行体是一条语句还是多条语句都必须加花括号,且左右花括号各独占一行。
    2) do{}while()结构中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。
    if ( ) do
    { {
    } }while( );
    else
    {
    }
    嵌套越少越好,{}不准超过3层 
    5.6 switch语句 
    1) 每个case和其判据条件独占一行。
    2) 每个case程序块需用break结束。特殊情况下需要从一个case块顺序执行到下一个case块的时候除外,但需要花括号在交界处明确注释如此操作的原因,以防止出错。
    3) case程序块之间空一行,且只空一行。
    4) 每个case程序块的执行语句保持4个空格的缩进。
    5) 一般情况下都应该包含default分支。
    Switch ( )
    {
    case x:
    break;
    case x:
    break;
    default:
    break;
    }
    6.程序结构 6.1 基本要求 
    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。
    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。
    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。
    在.c文件中:
    #define FILE_FLAG
    在.h文件中:&
    6.程序结构 6.1 基本要求 
    1) 有main()函数的.c文件应将main()放在最前面,并明确用void声明参数和返回值。
    2) 对由多个.c文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内,供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件采用双撇号″″标志文件名。
    3) 每个.c文件有一个对应的.h文件,.c文件的注释之后首先定义一个唯一的文件标志宏,并在对应的.h文件中解析该标志。
    在.c文件中:
    #define FILE_FLAG
    在.h文件中:
    #ifdef FILE_FLAG
    #define XXX
    #else
    #define XXX extern
    #endif
    4) 对于确定只被某个.c文件调用的定义可以单独列在一个头文件中、单独调用。
    6.2 可重入函数 
    可重入函数中若使用了全局变量,应通过关中断、信号量等操作手段对其加以保护。
    6.3 函数的形参 
    1) 由函数调用者负责检查形参的合法性。
    2) 尽量避免将形参作为工作变量使用。
    6.4 循环 
    1) 尽量减少循环嵌套层数
    2) 在多重循环中,应将最忙的循环放在最内层
    3) 循环体内工作量最小
    4) 尽量避免循环体内含有判断语句
    7.工程中所包含的文件 7.1 头文件 
    7.1.1 头文件的形式
    MCU程序中的头文件包括面向硬件对象头文件、公共头文件和总头文件。
    MCU C工程编程是面向硬件对象的。例如,要用MCU控制电机(Motor),在这样一个系统中,“面向硬件对象”概念体现在,工程中会创建“Motor.c”的源程序文件专门用于电机控制。相应的,也要创建一个同名头文件“Motor.h”,用于控制电机的MCU引脚定义、相关宏定义和电机控制函数声明等。像这样的头文件,就是面向硬件对象头文件。与之同名的“*.c”文件可以包含它,来完成控制此硬件对象的MCU引脚定义和相关宏定义;调用该硬件对象控制函数的文件也可以通过调用它来进行函数声明。
    还有一类头文件不是专门针对于特定的硬件对象的,而是有一定的通用性。这类头文件被称为公共头文件。如工程中包含的“Type.h”文件,该文件用于C语言中类型的别名定义,用户还可以根据自己的需要,随时在该文件中添加条目。在工程的任一文件中,需要用到这些别名时,都要包含“Type.h”。可见公共头文件并不拘泥于具体的硬件对象,它是为整个工程的和谐运作而建立的。
    总头文件(includes.h)是一个较特殊的头文件。它只被主函数文件包含,用于包含主函数文件中需要的头文件,宏定义,函数声明等。它使得主函数文件能够尽量避免改动,结构更加清晰。
    7.1.2 头文件的命名
    总的来说头文件的命名应尽量做到简短易懂,见名知意。
    面向硬件对象头文件的名称一定要与相应的硬件对象驱动文件同名。例???
    公共头文件,如果对应于相应的源程序文件而建立,必须与之同名。如,“GeneralFun.c”
    是工程中的通用函数定义文件,(像内存数据移动函数,延时函数都属于通用函数),其他文件在用到这些函数之前,必须进行函数原型声明,从而建立与之同名的“GeneralFun.h”文件,专门用于相应的函数声明。其它的公共头文件没有同名要求,只要表清文件含义即可,如“Type.h”,“GP32C.h”等。
    总头文件在一个工程中只有一个,它的名称较为固定,一般取为“Includes.h”。
    7.1.3 头文件注意事项
    1) 为了防止重复定义需要使用伪指令 #ifndef VarType……
    例:
    #ifndef VarType
    #define VarType
    typedef unsigned char INT8U; //无符号8位数
    typedef signed char INT8S; //有符号8位数
    typedef unsigned int INT16U; //无符号16位数
    typedef signed int INT16S; //有符号16位数
    typedef unsigned long INT32U; //无符号32位数
    typedef signed long INT32S; //有符号32位数
    typedef float FP32; //单精度浮点数
    typedef double FP64; //双精度浮点数
    #endif 
    2) 对于一个项目中的头文件与芯片相关的寄存器映像文件不可擅自改动,如果的确存在需要改动的地方另外开辟头文件。
    3) typedef和#define的用法
    ① typedef的用法
    在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:
    typedef int INT;
    typedef int ARRAY[10];
    typedef (int*) pINT;
    typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。
    ② #define的用法
    #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:
    #define INT int
    #define TRUE 1
    #define Add(a,b) ((a)+(b));
    #define Loop_10 for (int i=0; i<10; i++)
    ③ typedef与#define的区别
    从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。
    宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:
    typedef (int*) pINT;
    以及下面这行:
    #define pINT2 int*
    效果相同?实则不同!实践中见差别:
    pINT a,b;的效果同int *a; int *b;
    表示定义了两个整型指针变量。
    而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。
    注意:两者还有一个行尾;号的区别哦!(???)
    7.2 源程序文件 
    源程序文件包括主函数文件、通用函数文件、硬件对象控制文件、芯片初始化文件、中断向量定义文件和中断使能文件。
    源程序文件的分类和命名类同于头文件,但也有它自己的特点。
    7.2.1 主程序文件
    (Main.s 或 Main.c)(?????)
    工程中有且仅有一个主程序文件,它包含了工程的主处理流程。
    主函数文件中包含:
    (1)工程描述
    ①工程名
    工程名中每个意义单词(或单词缩写)的首字母大写,后缀为.prj。
    ②硬件连接索引
    工程所要控制的硬件对象索引,详细描述在相应的硬件对象控制文件中给出。
    ③工程的功能、目的和说明
    ④注意要点
    可以注明编程要点和心得
    ⑤日期
    注明工程完成日期
    (2)总头文件
    (3)主函数
    如:
    7.2.2 芯片初始化文件(“SetUp.c”或 “SetUp.s”)
    该文件与具体的芯片型号有关,并且只包含一个芯片初始化函数,若想由编译器自动调用芯片初始化函数,其函数名必须为"_HC08Setup",否则编译器会自动建立并调用一个空的"__HC08Setup"汇编子程序,而不理会用户创建的芯片初始化函数。为了统一,将该函数起名为"MCUInit",并在主函数中调用该函数。
    7.2.3 通用函数头文件和通用函数文件
    通用函数头文件和通用函数文件,“GenneralFun.h”和“GeneralFun.c”。 
    //[GenneralFun.h]通用函数头文件---------------------------------------------#include"Type.h" //类型别名定义voidDelay(INT16U); //延时函数声明 
    “GenneralFun.h”中包含:
    (1)文件名
    (2)通用函数所需用到的头文件
    (3)通用函数用到的宏定义
    (4)通用函数声明
    外部函数要用到通用函数时,可包含这个头文件进行函数声明。
    7.2.4 对象控制文件
    7.2.5 中断处理函数和中断向量表文件

    9. 硬件封装的思想
    1) 与硬件相关的程序文件
    与某个硬件相关的子程序放到1个程序文件中,该硬件的头文件放到一个文件中。
    程序文件的开始处是有关说明:本文件所包含的子程序及简要的功能说明,子程序分为内部调用和外部调用;硬件的连接说明。

    2) 中断的开放和禁止
    使用宏定义方式开放或禁止中断,宏定义语句放在EnDisInt.h头文件中。宏名的定义方法:
    开放中断以Enable标识,宏名中包含中断名,宏名最后以Int结束。如:开放串行接收中断的宏名为:EnableSCIReInt。
    禁止中断以Disable标识,宏名中包含中断名,宏名最后以Int结束。如:禁止串行接收中断的宏名为:DisableSCIReInt。
    开放所有中断宏名:EnableMCUInt。
    禁止所有中断宏名:DisableMCUInt。

    展开全文
  • 第2篇 C语言编程入门 第3章 迎战:选择结构设计 3.1 入门选择结构简介 3.2 选择结构设计实现—if语句 3.2.1 if结构语法 3.2.2 if结构程序实例 3.3 选择结构设计实现—if…else法 3.3.1 if…else结构语法 3.3.2 if...
  • c语言if语句用法有哪些C语言中if语句基本的有三种格式,在此基础上可以扩展一些其它格式,下面我们来看看c语言if语句用法。1、 if……形式一般格式:if(表达式) 语句;语义是:如果表达式值为真,则执行其后...
  • 该国最大的共享,等待您下载....掌握使用VC输入源程序,编译,连接和运行该程序的基本过程. 3.练习C调试程序. ,精通表达式,例如赋值运算和算术运算. ,熟练使用各种数据类型的标准输入,输出功能和格式说明符. 二...
  • 摘要:对流扩散方程是一类基本的运动方程,是描述粘性流体非线性方程线性化模型方程,它可以用来描述河流污染,大气污染,核废物污染中污染物质分布,流体流动和流体中热传导等众多物理现象.科学技术中关于...
  • C语言编程实例3

    2020-06-01 08:49:14
    (1) 、使用 for 语句对3种鸡数先在事先确定好范围内进行穷举并判断,对满足条件3种鸡数量按指定格式输出,否则进行下次循环。 (2)、 程序代码如下: #include <stdio.h> int main() { int cock,hen...
  • C语言编程-顺序结构

    2020-12-15 20:02:37
    c语言的基本输出格式打印下列内容: 100 A 3.140000 #include <stdio.h> int geshi(int a,char b,float c){ printf("%d\n",a); printf("%c\n",b); printf("%f\n",c); } int main(){ int a=100; char b='...
  • 中文名:C语言编程:一本全面C语言入门教程(第三版) 格式:PDF 完整程度:完整 包含中文版PDF,英文版PDF和习题答案 英文名:Programming in C:A Complete introduction to the C programming language,Third ...
  • printf,sprintf和fprintf都是C语言的输出语句,都是把格式字符串输出。那么这三者有什么区别,下面本篇文章就来认识一下printf,sprintf和fprintf,介绍它们之间区别,希望对大家有所帮助。printfprintf函数...
  • 单片机C语言基本编程规范详解本标准规定了程序设计人员进行程序设计时必须遵循规范。本规范主要针对单片机编程语言和08编译器而言,包括排版、注释、命名、变量使用、代码可测性、程序效率、质量保证等内容。1....
  • ASCII是计算机中最基本的“协议”。无论什么编程语言,其所使用关键字,运算符,都依赖于ASCII编码字符。为了与ASCII兼容,UTF-8使用远远多于UTF-16。ASCII是7位,所以共有128个码位,其中前32个是控制字符,...
  • C语言编程笔记-02

    2014-10-09 20:51:24
    C语言的基本格式如下: #include  int main (void) {  printf("输出的文件\n");  return 0; }  说明:首先要创建一个.c的空文件,利用命令touch name.c创建;要定义一个main的主函数,主函数下定义...
  • 本问先讲述makefile文件的基本格式,然后用以个实例来验证制作一个makefile文件编译工程 注意:一般我们通过条件编译技巧来避免重复包含头文件(见实例的#ifndef等命令) makefile 文件的基本结构是
  • **解决方法:**牢记else与离其最近一个if配对,不与其他if连用,并规范代码书写格式,使其看起来跟加清晰明了。 2,while语句用法while (循环条件) {循环语句;}**注意事项:**while比较好用,基本上所有循.....
  • C语言编程100例精选源码

    热门讨论 2009-10-29 01:31:44
    共分为8篇,包括基础篇、数值计算与数据结构篇、文本屏幕与文件操作篇、病毒与安全篇、图形篇、系统篇、游戏篇、综合篇,基本涵盖了目前C语言编程的各个方面。  全部以实例为线索展开讲解,注重对实例的分析、对...
  • 为了提高源程序质量和可维护性,从而最终...1.基本规则格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效率高、适度可扩展性、单片机编程规范-标识符...
  • C语言编程实例(一)

    2021-03-15 17:31:29
    (1) 使用 for 语句对 3 种鸡数嫌在事先确定好范围内进行穷举并判断,对满足条件 3 种鸡数量按指定格式输出,否则进行下次循环。 (2) 程序代码如下: ```c #include <stdio.h> int main() { int cock...
  • 移动端.epub格式技术书籍,分享给更多想学习编程语言人,手机端阅读客户端基本都支持格式,eg :iBook...
  • 十分有趣的c语言例程,对于初学者掌握基本语法,初步了解算法和编程思想很有帮助
  • 1.2 用C语言编程的基本注意事项 6 1.3 主流C语言编译器介绍 8 1.4 关于GNU规范的语法扩展 10 1.5 用C语言构建一个可执行程序的流程 11 1.6 本章小结 12 第2章 学习C语言的预备知识 /14 2.1 计算机体系结构简介...
  • C语言图形编程

    2020-05-07 22:38:24
    C语言图形编程 二3 基本贴图3.1 声明一个存储图片变量3.2 图片路径3.3 显示图片 3 基本贴图 3.1 声明一个存储图片变量 格式: IMAGE img; //类型 变量名(你要贴图片名) 3.2 图片路径 格式: loadimage(&...
  • C语言细节 编程机制

    2020-08-11 21:07:23
    C编程的基本策略是:用程序把源代码文件转换为可执行文件(其中包含可直接运行的机器语言代码) 典型的C实现是通过编译和链接这2个步骤来完成这一过程的 编译器把源代码转换成中间代码;链接器把中间代码和其他代码合并,...
  • 不过由于本人耐性欠佳,对文章里面格式基本上没有修改,请大家将就着阅读! 另外一点我是在没联系前作者前提下制作,如果原作者看到本PDF 后能有什么意见请 跟我联系,我邮箱 wangzihao[AT]gmail[DOT]com 或者...
  •  全文共分为四篇,全面、系统地讲述了C语言各个方面的知识点和程序设计的基本方法,以及编写程序过程中值得注意的地方,内容深入浅出,通俗易懂。对于C语言的初学者来说,这是一本绝对好的入门教材,对于有经验的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 652
精华内容 260
关键字:

c语言编程的基本格式

c语言 订阅