2012年12月9日 星期日

C語言:結構的宣告&定義


struct

結構 / 結構體


struct 其實就是使用者自訂型態。(利用基本型態再組合成一個自訂型態)

struct sName;  //結構宣告

結構宣告:只是宣告存在一個叫做 sName 的 struct
還沒有表明 struct 具體內容長得如何

struct sName {  //結構定義
    int i;
    double d;
    char c;
};

結構定義:表明了 struct 的具體內容、具體結構
但是尚未分配記憶體空間

定義好了 struct ,就可以把它當成一個型態來使用,例如:
int var1;
struct sName var2; //定義實體var2
struct sName array1[10];
struct sName *ptr;

可以把「struct sName」看成是一種型態
此時系統才會分配記憶體空間
我們把分配了記憶體空間的這些,例如:var2、array1 通稱為「實體」






如果把結構定義寫在.c

我們把變數和函式的宣告寫在.h檔,定義寫在.c檔
可是結構的定義卻建議寫在.h檔,為什麼?
寫在.c檔也可以啦,但是你在每個用到結構的.c都要寫一份結構定義,否則是編譯不會過的

s.h
//s.h
struct s;     //結構宣告

extern struct s entity;  //結構實體宣告

s.c
//s.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

struct s entity;     //定義了結構實體

source1.c
//source1.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function1(void)
{
    entity.integer = 1;
  //需要結構定義
    return;
}


source2.c
//source2.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function2(void)
{
    entity.integer = 2; //需要結構定義
    return;
}


source3.c
//source3.c
#include "s.h"    

struct s {        //結構定義
    int integer;
    float f;
};

void function3(void)
{
    entity.integer = 3; //需要結構定義
    return;
}



用到 struct 都要寫一份同樣的結構定義,將來若要修改這個 struct 要一個一個改,若漏掉沒改到 struct 就不一致了,將產生問題









【標題】結構的定義寫在 .h 要注意:
先說在一個.c檔內 struct 定義也必須是唯一的。
所以例如試試看 struct s { int i }; 寫兩次,編譯是不會過的。
// file.c
struct s { int i };
struct s { int i }; //重複定義

為了避免寫在 .h 檔以後,經過多重的引用以後可能出現"重複定義"的錯誤,
我們使用稱為 header guard 的寫法
,把它加上巨集防範 (#include 防範)

// file.h
#ifndef _FILE_H_
#define _FILE_H_
 內容
 。
 。
 。
#endif

_FILE_H_ 必須確保此名稱是『唯一的』,名稱重複就沒救了,所以我們常用檔名加底線做為唯一名稱
ifndef 意思是 if not define 如果沒定義過 _FILE_H_,也就是第一次碰到就做中間的內容,第二次再碰到就會跳過不做,就樣就可以避免重複定義






完整 struct 寫法

// s.h
#ifndef _S_H_
#define _S_H_

struct s {
     // 結構定義寫在 .h 檔
    int integer;
    float f; 
};

extern struct s entity;  // entity實體宣告

#endif


// s.c
#include "s.h"

struct s entity;  // entity實體定義 (為entity分配空間)


// file.c
#include "s.h"
#include <stdio.h>

void function( void )
{
    entity.integer = 123;
    printf("i=%d\n", entity.integer);
    return;
}

.........
參考

http://stackoverflow.com/questions/6316987/should-struct-definitions-go-in-h-or-c-file

沒有留言: