C系列語言中.c&&.h檔案內容的區分

誰不小心的發表於2013-10-15

摘要:在開始寫C程式的時候,我們往往很納悶程式的什麼部分需要放在C檔案中,什麼部分需要放在h檔案中。本文主要從軟體工程的角度,並結合一個示例,解答這個問題,並解釋為什麼要這樣做。


本文來源:C系列語言中.c&&.h檔案內容的區分http://blog.csdn.net/trochiluses/article/details/12746985

1)函式宣告放在.h中,函式定義放在C中

原因:h檔案往往說明的是一個一些列函式和資料的介面,如果我們把宣告放在C中,那麼我們要想在其他檔案中引用這些函式,那麼我們就需要使用include<name.c>,這不符合我們的習慣。另外,如果我們把函式或者資料的定義放在h檔案中,那麼當這個標頭檔案被多次引用的時候,必然會引發“重定義”的錯誤。當然,這涉及到C程式編譯的原理,因為include<name.h>的意義,就是在預處理的時候將這個檔案的所有內容都copy進來,所以如果h檔案中含有定義的話,多次引用必然會出現重定義錯誤。


2)資料型別的宣告放在h中,變數定義放在C中

原因:同上,有時,我們需要在標頭檔案中包含全域性變數,此時,也需要將全域性變數的宣告放在h檔案中,定義放在C檔案中


3)h是介面,C是實現

.h 中應該都是一些巨集定義和變數、函式宣告,告訴別人你的程式“能幹什麼、該怎麼用”
.c 中是所有變數和函式的定義,告訴計算機你的程式“該怎麼實現”

注意:變數的定義放在C中,資料型別的定義要放在h中,因為資料型別是可以存在於多個C檔案之中的


4)不是所有的宣告都放在.h之中,只有需要被外部呼叫的宣告才放在.h之中

一般來說,一個C檔案應該是一個模組
如果你的程式僅僅有一個模組(僅僅一個C檔案),就可以不用建立H檔案了。

否則你的模組肯定不是獨立的,你的模組裡面的實現要被別的模組呼叫。這個時候你最好生成一個標頭檔案(H檔案),在標頭檔案裡面可以宣告你的那些函式是公共的。當別的模組包含你的標頭檔案後,就可以使用你的公共宣告瞭。


舉個例子:

我們才學習資料結構的時候,編寫了一些堆疊stack資料結構,此時將pop和push這些操作都製作成自己的庫,以後只需要呼叫這些函式就ok,那麼此時我們需要用h檔案宣告stack的定義和相關操作,在c檔案中實現這些操作就行了。

stack.h:

#ifndef MAXSTACKSIZE
#define MAXSTACKSIZE 200
#endif
typedef int StackDataType;
typedef struct mystack{
  int top;
  StackDataType data[MAXSTACKSIZE];
}Stack,*StackPointer;
extern int IsEmpty(Stack s);
extern int Push(StackPointer s, StackDataType element);
extern StackDataType Pop(StackPointer s);


stack.c:

#include"stack.h"
#include<stdlib.h>
#include<stdio.h>
StackDataType Pop(StackPointer s){ 
  if(s->top==-1){
    printf("the stack is already empty!\n");
    exit(1);
  }

  --(s->top);
  return s->data[s->top+1];
}

int IsEmpty(Stack s){ 
  if(s.top==-1){
    return 1;
  }
  else{
    return 0;
  }
}

int Push(StackPointer s,StackDataType element){
  if(s->top >= MAXSTACKSIZE-1){
    printf("the stack is over flow!\n");
    return 0;
  }
  ++(s->top);
  s->data[s->top]=element;
  return 1;
}


相關文章