c语言的组织形式,C语言常用代码组织形式

一、常用的代码组织形式

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

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

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

头文件区:包含所有模块共同需要的头文件。例如常用的stdio.h、stdlib.h等

全局宏区:包含所有模块公用的宏定义,例如调试开关,一些缓冲区的大小等

全局变量区:包含所有非static全局变量的声明

函数接口区:包含所有模块的函数接口

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

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

/**

* common_list.h 总领头文件

*

*/

/* 头文件区 */

#include

#include

/* 全局定义区 */

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

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;

}

运行结果:

95e0471ef43568de8bfa23f43e042398.png

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

#include

#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); ;

#endif

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;

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 /*注释掉这一行,所有的条件编译则不会编译*/

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

e02b8b5c1ef1c20d3f88d59e56ab7790.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值