zoukankan      html  css  js  c++  java
  • 我的C语言编程风格

     前几天看别人的代码,真是的看的头昏脑涨,基本没有注释、乱起的变量名字,还要费尽心思去解读作者的意思。突然感觉高效的程序注释说明和良好的编程风格是多么的重要。

    为了不让别人在看到我的代码时在背后骂我,也为了更高效持久的开发,我想也应该是时候特别规定一下自己的编程风格了。

    1、文件/文件夹命名

      文件命名要精确,文件名要准确反映文件内容。

      文件命名一律使用小写字母,如keyboard.c。

      如有缩写单词,则必须大写,如flash_LED.c、UART.c。其中LED是Light-Emitting Diode(发光二极管)的缩写,UART是Universal Asynchronous Receiver/Transmitter(通用异步收发器,也就是串口)的缩写。对于有约定俗成缩写的单词,就使用缩写词汇。

      文件名应使用名词,而不应该使用动词。如果文件内容是数据采集,应该命名为data_collection.c而非data_collect.c。

    2、标识符命名

         C语言中,可以定义各种标识符作为变量名、数组名、函数名、标号及用户定义对象的名称。ANSI C规定标识符必须由字母和下划线开始,随后可以出现字母、下划线和数字。

    1)变量命名

         变量命名一律小写,缩写词汇用大写,且全部使用名词,可以使用形容词修饰,用“_”表从属关系。因为变量名作为一个变量的名字,就应该是一个名词。

         局部循环体控制变量用i,j,k。如for(i=0;i<100;i++)。

         指针变量用“p_”开头,后面接指向内容。如指向高度变量的指针,命名为“*p_height”。请读者自行区分指针和指针变量的区别。

         局部变量尽量用一个单词表达清其含义。

         全局变量命名时首先写所属模块名称。例如如一个传感器文件sensor.c里面的一个全局变量要代表温度,则命名为sensor_temperature。又例如LCD(液晶显示屏)文件LCD.c中表示LCD状态的全局变量命名为LCD_status。因为全局变量往往跨文件调用,如不写清变量定义位置,当程序庞大,而IDE又不支持一键定位时,查找起来很麻烦。即使IDE支持一键定位,一个清楚明白的命名,能让人瞬间读懂该变量的含义。

    2)数组命名

         数组命名各单词首字母大写,其他同变量。

    读者可能会有疑问,数组名后面会有[]符号,与变量区别明显,为什么要用首字母大写的方式。实际上,在数组名作为实参传递数组首地址时,往往会省略[]符号,应该数组名就是数组的首地址。例如:

      unsigned char string[]=”abcdefg”;

       printf(“%s”,string);

      在以上代码中,string是一个8位数组(为什么是8位?),在使用printf()函数输出时,只写了数组名,显然这种方式是被允许的。而此时就没有写[],在这种情况下,并不能瞬间知道string是变量还是数组,而需要参考前面的格式控制符“%s”。在其他函数中,或许没有“%s”这样的格式控制符帮助我们判断string到底是数组还是变量,我们只有找到函数的声明或定义才能知道答案,严重影响阅读。因此有必要对数组和变量加以区分。

    3)函数命名

      函数命名各单词首字母大写,写成主谓语形式,主语用名词,谓语用动词,缩写词汇用大写,用“_”表从属关系。主语通常为模块名,而谓语是描述模块的动作。因为函数本身就是用来执行一系列的动作的, 结合函数参数,可以表达通顺的语句。举个简单的例子:延时函数。定义一个ms级延时函数为:

      void Delay(unsigned int ms);

      当然,函数命名中必要时可以出现宾语。这种情况多出现在函数没有参数的情况下。如一个函数的功能是LCD显示时间,而时间是全局变量,因此这个函数就不需要参数,此时直接定义成void      LCD_Display_Time(void)(其实是声明,因为没写函数体)。

    4)标号命名

      由于在硬件编程中标号可以用循环来代替,所以很少用到。我们规定标号的命名格式基本同变量,使用全部小写的名词,但是只用一个单词表示即可。因为标号时候的时候或者前面加了goto,或者后面加了“:”,很容易与变量区分开。况且只是一个定位标志,所以一个单词足够了。

    5)自定义类型命名

      自定义类型命名主要指使用typedef定义的新类型名,以及结构体类型、共用体类型的类型名(而非该类型的变量名)。

      自定义的新类型名,只用一个单词,首字母大写。但是定义这种新类型的变量时,命名规则与变量命名规则完全相同。

      请自行体会新类型名与新类型变量的区别。

    6)宏定义命名

      宏定义命名全部使用大写字母,单词数不限。可以加入数字和下划线,但是数字不能开头 。

      由于宏定义的特殊性,对其使用名词或动词不作规定。因为宏定义一个函数时,应该是动词性质,而宏定义一个常数时,应该是名词性质。

    3、表达式的书写

      操作数与运算符之间要有空格隔开,以便于区分。

    4、文件编写

      (1)、文件按模块划分,函数按功能划分。

      (2)、

    源文件(.c)

    头文件(.h)

    头文件包含指令(#include)

    头文件包含指令(#include)

     

    宏定义(#define)

    所有函数定义(必须有函数体,即{ })

    内部函数声明(static,不能有函数体)

    外部函数声明(extern,不能有函数体)

    外部变量定义(必须赋初值)

    静态外部变量定义(static,必须赋初值)

    外部变量声明(extern,不能赋值)

     

     

    自定义类型(typedef)

    外部数组定义

    静态内部数组定义(static)

    外部数组声明(const)

    条件编译

    条件编译

    由上表可以看出,h文件内存放的都是对外可见的变量、函数数组等的声明,宏定义则是对内对外都可以使用,放在这里主要为了修改方便。

    在定义外部变量、数组和函数时,不需要写extern,因为缺省时默认extern。而声明外部变量、数组和函数时,必须用extern显式声明,这样是为了让代码更直观。

      (3)、函数头部注释格式

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

    *        称: function(int par)

    *        能:**

    *入口参数:**

    *出口参数:**

    *        明:

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

    借鉴了一些良好的编程风格:http://www.cnblogs.com/foxsay/p/5331388.html

  • 相关阅读:
    [Exception] 当前 TransactionScope 已完成
    C# Lazy<T>(转)
    C# 基础概念之延迟加载
    .Net语言中关于AOP 的实现详解
    DataReader、Table、DataSet和Entity相互转化
    ASP.NET Core 2.0 : 五.服务是如何加载并运行的, Kestrel、配置与环境(转)
    ASP.NET Core 2.0 : 四. _Layout与_ViewStart(转)
    ASP.NET Core 2.0 : 三. 项目结构(转)
    ASP.NET Core 2.0 : 二. 开发环境(转)
    ASP.NET Core 2.0 : 一. 概述(转)
  • 原文地址:https://www.cnblogs.com/qsyll0916/p/9142477.html
Copyright © 2011-2022 走看看