2019独角兽企业重金招聘Python工程师标准>>>

一、常用的代码组织形式

将所需要使用的函数分类,总体思想是如果两个函数操作的是一个资源,完成的是类似的功能,则将这两个函数划分在一个模块中,比如对一个链表的的插入和删除操作而言应该划分到一个模块内,在C语言中,一个文件即代表一个模块。

其次,如果模块中的函数是一个函数接口,需要被其他模块所引用,则应当定义为外部函数。如果函数仅在模块内使用,则应当定义为static函数。这样做可以防止各个模块中的函数因为重名现象而出现的错误。使用static关键字定义函数之后,该函数对其他的模块来说是透明的,只有本模块的函数可以对其进行调用。同理,仅在模块内使用的全局变量也应当定义为static。

最后,定义一个common.h头文件,该头文件包括以下内容:

  • 头文件区:包含所有模块共同需要的头文件。例如常用的stdio.h、stdlib.h等
  • 全局宏区:包含所有模块公用的宏定义,例如调试开关,一些缓冲区的大小等
  • 全局变量区:包含所有非static全局变量的声明
  • 函数接口区:包含所有模块的函数接口

有了该common.h头文件后,各个模块的头文件只要包含该头文件,就可以应用函数接口和全局变量,包含所需要的头文件和宏定义。

下面是一个经过组织的链表处理程序:

/*** common_list.h  总领头文件* *//* 头文件区 */
#include <stdio.h>
#include <stdlib.h>/* 全局定义区 */
typedef struct node * Node;  //结点指针
/*** 链表结点结构*   val:结点的值*   next:下个结点的指针*/
struct node{int val;Node next;
};/* 全局变量声明 */
extern Node head;/* 函数接口声明区 */
extern int insert(int val);
extern void print();
extern void destroy();
/*** list.c  定义所有操作链表的函数*/#include "list.h"Node head;//链表头//插入结点函数
int insert(int val)
{Node p, q;p = head;if(p != NULL) { //链表非空while(p->next != NULL) {p = p->next;}}q = (Node)malloc(sizeof(struct node)); //创建新的结点if(q == NULL)return -1;q->next = NULL;q->val = val;if(p == NULL){head = q;return 1;}p->next = q; //结点加入链表return 1;
}//遍历链表,打印每个结点的值
void print()
{Node p = head;while(p != NULL){printf("%d\n", p->val);p = p->next;}
}//遍历链表,删除每一个结点
void destroy()
{Node p = head;while(p != NULL){Node q;q = p;p = p->next;  //指向下一个结点free(q);      //释放该结点}head = NULL;
}
/*** main.c main函数*/#include "list.h"int main(void)
{Node p;int i;printf("insert\n");for(i = 1; i < 8; i++){insert(i);}print();  //遍历链表,打印链表结点printf("destroy\n");destroy();return 0;
}

二、调试开关

在调试大程序时免不了需要输出一些当前程序执行的信息,如下例所示:

#include <stdio.h>void bubble_sort(int a[], int n)
{int i, j, temp;for (j = 0; j < n - 1; j++)for (i = 0; i < n - 1 - j; i++)if(a[i] > a[i + 1]){temp=a[i];a[i]=a[i+1];a[i+1]=temp;}
}int main(void)
{int array[5] = {1, 2, 4, 3, 0};int i;printf("before sort\n");bubble_sort(array, 5);  //调用冒泡排序函数printf("after sort\n");for(i = 0; i < 5; i++){printf("%d\n", array[i]);}return 0;
}

运行结果:

当不需要这些输出信息时,需要注释掉这些语句,这种注释很麻烦,当代码很长的时候这种注释难免会出现问题,这时应当使用条件编译技术,将这些输出信息定义为宏,如下所示:

#include <stdio.h>#define DEBUG 1  //调试开关
#ifdef DEBUG
#define PRINT(str) printf(str)  //输出一个参数的printf函数
#define PRINT_1(str, arg); printf(str, arg);  //两个参数的printf函数
#else
#define PRINT(str)
#define PRINT_1(str, arg); ;
#endifvoid bubble_sort(int a[], int n)
{int i, j, temp;for (j = 0; j < n - 1; j++)for (i = 0; i < n - 1 - j; i++)if(a[i] > a[i + 1]){temp=a[i];a[i]=a[i+1];a[i+1]=temp;}
}int main(void)
{int array[5] = {1, 2, 4, 3, 0};int i;PRINT("before sort\n");bubble_sort(array, 5);  //调用冒泡排序函数PRINT("after sort\n");for(i = 0; i < 5; i++){PRINT_1("%d\n", array[i]);}return 0;
}

在不使用输出信息时,只要关闭调试开关就可以了,如下所示:

//#define DEBUG 1  /*注释掉这一行,所有的条件编译则不会编译*/

这样程序就不会输出任何东西了:

转载于:https://my.oschina.net/daowuming/blog/771566

C语言常用代码组织形式相关推荐

  1. c语言中字符串的子式咋样输出,C语言常用代码

    <C语言常用代码>由会员分享,可在线阅读,更多相关<C语言常用代码(48页珍藏版)>请在人人文库网上搜索. 1.WORD格式-可编辑-#includeusing namespa ...

  2. C语言成绩abc,C语言常用经典代码:求三角形的面积、把百分制成绩转换为ABC等级制、其两个自然数的最大公约数和最小公倍数...

    C语言 经典常用代码 C语言常用经典代码 求三角形的面积. 把百分制成绩转换为ABC等级制. 其两个自然数的最大公约数和最小公倍数. 求输入n个数的平均值. 求一个数各个位上的数字之和. 求n个数的阶 ...

  3. c语言常用的代码,初学C语言常用简单程序代码;

    <初学C语言常用简单程序代码;>由会员分享,可在线阅读,更多相关<初学C语言常用简单程序代码;(16页珍藏版)>请在人人文库网上搜索. 1.初学C语言常用简单程序代码素数的筛选 ...

  4. 【数据结构与算法】程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码

    [数据结构与算法]程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码 文章目录 [数据结构与算法]程序员们常用的10个关键数据结构,包括它们的原理和C语言实现代码 1. 数组 (Arra ...

  5. JavaScript常用代码

    在这存一下JavaScript常用代码: 1.封装输出 1 var log = function() { 2 console.log.apply(console, arguments) 3 } 4 5 ...

  6. WPF第一章(XAML前台标记语言(Chapter02代码讲解))

    XAML前台标记语言(Chapter2代码讲解)     很不好意思,工作有点忙,博客停了两天.相对于一门语言的学习,理论知识和实践必不可少,大多数时间我们要用,对于代码也是,一边不行可以看两遍,实在 ...

  7. Lambda表达式常用代码示例

    Lambda表达式常用代码示例 2017-10-24 目录 1 Lambda表达式是什么 2 Lambda表达式语法 3 函数式接口是什么   3.1 常用函数式接口 4 Lambdas和Stream ...

  8. c语言常用术语,保证让你大开眼界

    c语言常用术语 术语一:预备知识 术语三 :c语言基础 术语:表达式与运算符 术语:函数 术语:指针 术语:位运算 术语:存储管理 术语:文件 术语一:预备知识 机器语言:机器语言是直接用二进制代码指 ...

  9. ABAP语言常用的系统字段及函数

    ABAP语言常用的系统字段及函数 常用的系统变量如下: 1.SY-PAGNO当前页号 2.SY-DATUM当前时间 3.SY-LINSZ当前报表宽度 4.SY-LINCT当前报表长度 5.SPACE空 ...

最新文章

  1. 1078 Hashing (25 分)【难度: 一般 / 知识点: 哈希表二次探测法】
  2. redis api-set
  3. Spring中ApplicationContext和beanfactory区别
  4. 来到博客园 就要好好记录 分享技术
  5. CSS页面重构“鑫三无准则”之“无图片”准则——张鑫旭
  6. JMeter功能不够用?看我的
  7. python所有软件-太牛逼!一款软件几乎可以操作所有的数据库!
  8. conda pip 安装NumPy速度不佳解决方案
  9. JavaScript 函数 对象 数组
  10. 「日常训练」Queue(Codeforces Round 303 Div.2 D)
  11. kubernetes NodeIP、PodIP、ClusterIP的区别和联系
  12. 自适应的设置字体的方式
  13. 麻雀搜索算法——Matlab
  14. Nginx部署前端项目
  15. 汇编语言笔记-ARM架构指令集
  16. 水色物语:清新水彩手绘插画技法
  17. 如何选择适合你的兴趣爱好(十五),油画
  18. PINN深度学习求解微分方程系列一:求解框架
  19. 视频直播APP开发的主要功能
  20. Scheduling restart of crashed service解决方案与源码分析

热门文章

  1. 机房收费系统合作版(二):透过显示上机人数品味如何做到全心全意为人民服务
  2. 中国成全球第二AI医疗交易国,上半年AI制药融资数等于去年全年 | 报告
  3. 不止音箱,百度还发布了这些AI产品,还有参会者的10个小建议
  4. C++中string::find()函数和string::npos函数的使用
  5. 【2018.06.21学习笔记】【linux高级知识 14.1-14.3】
  6. Vue 混合、自定义指令、插件
  7. weka特征选择源码阅读
  8. C#中join 的lambada写法
  9. 逆序链表--递归思路
  10. find a ubuntu featue