C語言經常使用代碼組織形式

1、經常使用的代碼組織形式

將所須要使用的函數分類,整體思想是若是兩個函數操做的是一個資源,完成的是相似的功能,則將這兩個函數劃分在一個模塊中,好比對一個鏈表的的插入和刪除操做而言應該劃分到一個模塊內,在C語言中,一個文件即表明一個模塊。node

其次,若是模塊中的函數是一個函數接口,須要被其餘模塊所引用,則應當定義爲外部函數。若是函數僅在模塊內使用,則應當定義爲static函數。這樣作能夠防止各個模塊中的函數由於重名現象而出現的錯誤。使用static關鍵字定義函數以後,該函數對其餘的模塊來講是透明的,只有本模塊的函數能夠對其進行調用。同理,僅在模塊內使用的全局變量也應當定義爲static。函數

最後,定義一個common.h頭文件,該頭文件包括如下內容:spa

  • 頭文件區:包含全部模塊共同須要的頭文件。例如經常使用的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;
}

2、調試開關

在調試大程序時免不了須要輸出一些當前程序執行的信息,以下例所示:code

#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); ;
#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  /*註釋掉這一行,全部的條件編譯則不會編譯*/

這樣程序就不會輸出任何東西了:io

相關文章
相關標籤/搜索