Lab 2-0: Program Compilation Problem -
include
directive

 
實習目標 了解 #include 的用途, 分辨 compiler 的錯誤和 linker 的錯誤
 
步驟一 #include <stdio.h> 或是 #include "io.h" 究 竟做了什麼事?

首先我們知道 C/C++ compiler 在編譯之前會先進行前處理 (preprocessing) 的動作, 做完了以後才開始正式編譯

#include, #define, #if, #else, #endif, #pragma, #line 就是所謂的 preprocessor directives

#include 基本上是把所指定的檔案合併到目前要編譯的程式中一起編譯

在 Visual Studio 中你可以用下列的設定看到前處理器真的把所 include 的檔案合在一起

首先依照下圖設定

選取 C/C++ 設定編譯器的屬性, 點選 Project Options 欄位, 如圖手動加入 /E

設定完以後, 鍵入下圖 main.cpp 程式

編譯執行, 就可以看到下圖的輸出, 可以看到 main.cpp 第一列 引入 stdio.h,

stdio.h 共有 706 列, 然後再開始編譯 程式的第二列 void main() ...

使用 /E 只是讓你了解像是 #include 或是 #define 的運作方法, 實際上使用時會產生一個 LNK1104 的錯誤, 因為編譯器沒有產生 .obj 檔案, 所以正常撰寫程式時不能加上 /E 的編譯選項。

步驟二 一般來說 #include 都是引入 .h 的檔案, 在 .h 的檔案中我們只放變數的宣告, 函式的宣告, 自定資料型態的宣告 (declaration), 例如:

extern int x;

void printRoutine(int x, double y);

typedef struct
{
  int x;
  char name[100];
} MyRecordType;

不放任何變數或是函式的定義 (definition), 例如:

int x;

void printRoutine(int x, double y)
{
...
}

MyRecordType x;

.h 的檔案中我們只是告訴 compiler 說下面的程式中會使用到某一個名稱, 這個名稱是個具有什麼型態的變數或是這個名稱是一個需要傳入某些參數的函式, 以便 compiler 看到這個名稱時知道該做什麼事

在我們寫的程式中, 每一個模組通常都包含 .h 和 .cpp 的檔案, .cpp 檔案中包含變數的定義以及 函式的定義, 是模組的實作, .h 檔案的目的是提供給所有需要使用這個模組的程式來引入此模組內各種工具的定義用的。

簡單的說, 你現在一定知道在使用一個變數之前一定要先定義過, 例如:

    int value;
    value = 1;
同樣的, 當你要使用任何函式之前, 也一定要先引入它的宣告檔案, 例如:
	#include <stdio.h>
	...
	printf("Hello World!\n");
或是
	#include "io.h"
	...
	printArray(data, ndata);
其中 stdio.h 檔案內就包含了 printf() 函式的宣告, io.h 檔案內也應該要包含 printArray() 函式的宣告
步驟三 請看下列程式 , 製作一個 project, 包含下列兩個 .cpp 的檔案, 測試一下會有什麼錯誤?

檔案 printArray.cpp

#include <stdio.h>

void printArray(int data[], int numData)
{
    int i;

    for (i=0; i<numData; i++)
        printf("%d ", data[i]);
}
檔案 main.cpp
#include "printArray.cpp"

void main()
{
    int dataArray[] = {5, 4, 3, 2, 1};

    printArray(dataArray, 5);
}

1. 分別編譯這兩個檔案會有錯誤嗎?

2. 合在一起編譯會有什麼錯誤嗎?

3. 請問這個錯誤是 compiler 的錯誤 (語法錯誤)? 還是 linker 的錯誤?

步驟四

請注意上述程式並沒有語法的錯誤, 發生的錯誤是 linker 連結時的錯誤, linker 告訴你有函式重複定義了,

請回憶上一次實習時 .h 檔案的用法, 製作一個使用多個檔案, 但是可以一起編譯的 project

步驟五 想一想為什麼會發生那樣的錯誤, 為什麼你的方法可以解決那樣的錯誤, Demo 時告訴助教

如果把 printArray.cpp 改成 printArray.h 就可以了嗎? (.h 檔案裡放函式的定義的話也會有同樣的錯誤嗎?)

是檔案名稱的問題嗎? 還是檔案內容的問題? .h 檔案該放什麼東西?

請依照上一次實習時 分開檔案的作法, 將適當的東西放入 .h 檔案, main.cpp 只引入使用到的 .h 檔案

步驟六 請助教檢查後, 將所完成的 project (去掉 debug/ 資料匣下的所有內容) 壓縮起來, 選擇 Lab2-0 上傳

C++ 物件導向程式設計課程 首頁

製作日期: 03/01/2012 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程系 Lagoon

>