C 语言学习-02【编程习惯】

1、命名规则

  • 标识符的命名要清晰直观,有明确的含义

    fine:

    c 复制代码
    int error_number;
    int number_of_completed_connection

    awful:

    c 复制代码
    int n;
    int nerr;
    int n_comp_conns;
  • 标识符的长度应当符合"最短长度"和"最多信息"的原则

  • 程序中不要出现仅靠大小写区分的相似的标识符

    c 复制代码
    int x, X;
    void foo(int x);
    void FOO(float x);
  • 程序中不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误,但会让人误解

  • 用正确的反义词组命名具有互斥意义的变量或相反动作的函数等

    c 复制代码
    int minValue;
    int maxValue;
    int SetValue(...);
    int GetValue(...);
  • 尽量避免名字中出现数字编号,处分逻辑上的确需要编号

    awful:

    c 复制代码
    #define EXAMPLE_)_TEST_
    #define EXAMPLE_!_TEST_

    fine:

    c 复制代码
    #define EXAMPLE_UNIT_TEST_
    #define EXAMPLE_ASSERT_TEST_
  • 变量和参数用小写字母开头的单词组合而成,常量全用大写的字母,用下划线分割单词

    c 复制代码
    BOOL flag;
    int drawMode;
    const int MAX = 100;
    const int MAX_LENGTH = 100;
  • 如果不得一需要全局变量,则是全局变量加前缀g_(表示 global)

    c 复制代码
    int g_howManyPeople;
    int g_howManyMoney;
  • 变量的名字应当使用"名词"或者"形容词 + 名词"

    c 复制代码
    float value;
    float oldValue;
    float newValue;
  • 函数命名应以函数要执行的动作命名,一般采用"动词"或者"动词 + 名词"的结构

    c 复制代码
    // 找到当前进程的当前目录
    DWORD GetCurrentDiretory(DWORD BufferLength, LPTSTR Buffer);
  • 对于数值或者字符串等常量的定义,建议采用全大写字母,且单词之间加下划线"_"的方式命名

    c 复制代码
    #define PI_ROUNDES 3.14

2、if 语句

  • 整型变量与 0 进行比较操作是,应当将整型变量用"=="或"!="直接与 0 比较

    fine:

    c 复制代码
    if (value == 0);
    if (value != 0);

    awful:

    c 复制代码
    if (value);
    if (!value);
  • 不可将浮点变量用"=="或"!="与任何数字比较,应该设法转化成">="或"<="形式

    awful:

    c 复制代码
    if (x == 0.0);

    fine:

    c 复制代码
    if ((x >= - EPSINON) && (x <= EPSINON));
    // EPSINON 是允许的误差(即精度)
  • 判断一个指针变量是否为空时,应当将指针变量用"=="或"!="与 NULL 比较

    c 复制代码
    if (p == NULL);
    if (p != NULL);

3、循环语句

  • 在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的放在最外层,以减少 CPU 跨且循环层的次数
  • 如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体外面

4、宏和常量

  • 使用宏定义表达式时,要使用完备的括号

    awful:

    c 复制代码
    #define RECTANGLE_AREA(a, b) a * b
    #define RECTANGLE_AREA(a, b) (a * b)
    #define RECTANGLE_AREA(a, b) (a) * (b)

    fine:

    c 复制代码
    #define RECTANGLE_AREA(a, b) ((a) * (b))

    better:

    c 复制代码
    #define FOO(x) do { \
    	printf("arg is %s\n", x); \
    	do_something_useful(x); \
    } while(0)
  • 使用宏时,不允许参数发生变化

5、参数的规则

  • 参数的书写要完整,如果函数没有参数,则用 void 填充

    c 复制代码
    void SetValue(int width, int height); // fine
    void SetValue(int, int); // awful
    float GetValue(void); // fine
    float GetValue(); // awful
  • 参数命名要恰当,顺序要合理

    awful:

    c 复制代码
    void StringCopy(char *str1, char *str2);

    fine:

    c 复制代码
    void StringCopy(char *strDestination, const char *strSource);

6、函数内部实现的规则

  • return 语句不可返回指向"栈内存"的"指针",因为该内存在函数体结束时被自动销魂

    c 复制代码
    char *Func(void) {
        char str[] = "hello world";
        ...
        return str;
    }

7、断言的使用

内存复制函数:(如果 assert 的参数为假,那么程序就会终止,并出现提示对话,说明在某个地方引发了 assert)

c 复制代码
void *memcpy(void *pvTo, const void *pvFrom, size_t size) {
    assert((pvTo != NULL) && (pvFrom != NULL)); // 使用 assert
    byte *pbTo = (byte*)pvTo; // 防止改变 pvTo 的地址
    byte *pbFrom = (byte*)pvFrom; // 防止改变 pvFrom 的地址
    while (size-- > 0) {
        *pvTo++ = *pbFrom++;
        return pvTo;
    }
}

8、内存管理

  • 用 malloc 申请内存之后,应该立即检查指针值是否为 NULL,防止使用指针值为 NULL 的内存
  • 不要忘记为数组和动态内存赋初值,防止将未被初始化的内存作为右值使用
  • 避免数组或指针的下标越界,特别要当心发生"多1"或者:少1"操作
  • 动态内存的申请与释放必须配对,防止内存泄露
  • 用 free 释放了内存之后,立即将指针设置为 NULL,防止产生"野指针"
相关推荐
嵌入式科普16 分钟前
十三、从0开始卷出一个新项目之瑞萨RZN2L串口DMA接收不定长
c语言·stm32·瑞萨·e2studio·rzn2l
biter008821 分钟前
opencv(15) OpenCV背景减除器(Background Subtractors)学习
人工智能·opencv·学习
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
小林熬夜学编程2 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
QQ同步助手2 小时前
如何正确使用人工智能:开启智慧学习与创新之旅
人工智能·学习·百度
流浪的小新2 小时前
【AI】人工智能、LLM学习资源汇总
人工智能·学习
A懿轩A3 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
半盏茶香3 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
字节高级特工4 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++