Introduction to the C Programming Language Preprocessor (前端處理器)
Preprocessor (前端處理器) Preprocessor (前端處理器)主要之三項功能: 巨集 #define 指令 常數代換 字串代換 定義簡易函數 包含檔案 (include) : 將某個檔案包含於目前的檔案下工作, 通常包含進來的檔案都以 h 為副檔名, 如: stdio.h, stdlib.h等 #include <檔案名稱> #include “檔案名稱” 條件式編譯 (在此不介紹) 在此僅討論前兩項 以「#」開頭的前置處理指令,之所以會稱為”前置處理”,這是因為在為這些指令在編譯之前就會先進行處理,再把處理後的結果與程式碼一起送給編譯器編譯。 條件式編譯在藍色書的ch13.3
#define前置處理器 #define可方便將常用的常數、字串替換成一個自訂的識別名稱。亦可取代簡單的函數。 這兒不可以加分號 替換常數,簡單函數範例1 取代簡單函數範例2 在#define後面所使用的「識別名稱」,是用來替換後面的「代換標記」。
#include前置處理器 #include除了可以含括C語言提供的標頭檔之外,也含括入我們自己所寫的標頭檔。 #include <標頭檔.h> /*C語言提供的標頭檔*/ #include ”檔案名稱” /*自己的檔案*/
範例一 : #define 利用 #define 方式撰寫輸入圓周半徑計算圓面積 define 使用方式 #define PI 3.1415929 #define Area(r) PI * (r) * (r) /*定義巨集Area(r)*/ void main() { int r; printf("Enter radius : "); scanf(" %d", &r); printf("The area = %10.4f \n", Area(r)); } define 使用方式 pre1.c 巨集:假設程式裡會使用到巨集十次,在compiler就會產生十段相同的程式碼 vs 函數:無論程式裡呼叫函數幾次,只會有一段程式碼出現 因此在選擇使用函數或是巨集的同時,也需要程式設計師在時間與空間中做出取捨:選擇巨集佔用的記憶體較多,但是程式的控制權不用移轉,因而程式執行的速度較快; 選擇函數程式碼較短,佔用的記憶體較少,但是程式的控制權要交給函數使用,所以執行速度會較慢
範例二: #define 利用 #define 方式撰寫判斷輸入數值為奇數或偶數 #define odd(x) ((x) % 2 ==1) ? 1 : 0 void main() { int x; printf("Enter one integer value : "); scanf(" %d", &x); if( odd(x)) printf("%d is odd number. \n", x); else printf("%d is even number. \n", x); } pre2.c
範例三: #define 依照輸入數值列出其平方值, 若數值小於50時, 則程式結束 #define TRUE 1 #define FALSE 0 #define SQ(x) (x * x) /*定義巨集SQ(x)*/ void main() { int num; int again = 1; printf("\1: Program will stop if input value less then 50. \n"); while(again) printf("\1: Please input number ==> "); scanf("%d", &num); printf("\2: The square for this number is %d \n", SQ(num)); if(num >= 50) again = TRUE; else again = FALSE; } 注意: 先乘除後加減 Ex: SQ(num+1)?? pre3.c 注意:先乘除後加減 Ex: SQ(num-1)
範例五: #include 使用自訂的標頭檔 area.h #define PI 3.14 #define CIRCLE(r) ((PI)*(r)*(r)) #define RECTANGLE(length,height) ((length)*(height)) #define TRIANGLE(base,height) ((base)*(height)/2.) pre5.c #include <stdio.h> #include<stdlib.h> #include “d:\area.h” int main() { float base,height; printf(“Please input triangle base:”); scanf(“%f”,&base); printf(“Please input triangle height”); scanf(“%f”,&height); printf(“Triangle area: %.2f\n”,TRIANGLE(base,height)); system(“pause”); return 0; } 注意事項: 1.範例5中的area.h檔必須存在d槽上/*因為pre5.c檔中,要呼叫自訂的標頭檔設的路徑*/ 2.若在pre5.c檔中,改寫成#include “area.h” 方法一:則請將area.h檔存在TC環境設定裡的函式庫(c:\tc\include\) 方法二:看使用者將自定的標頭檔存放在哪個資料夾下,則去TC環境設定函式庫路徑裡增加路徑 Ex: 將area.h放在c:\temp\,所以要將TC環境設定函式庫路徑增加上 ,c:\temp\ 這樣才找得到此自定的標頭檔
C語言標頭檔 alloc.h assert.h bios.h conio.h ctype.h dir.h dos.h errno.h fcntl.h float.h graphics.h io.h limits.h math.h mem.h process.h setjmp.h share.h signal.h stdarg.h stddef.h stdio.h stdlib.h string.h time.h values.h alloc.h 配置記憶體的檔頭 time.h 系統時間的檔頭 … conio.h 一些輸入輸出的檔頭 math.h 數學函數的檔頭 … dos.h DOS模式下用到的檔頭 string.h 字串函數的檔頭 …
範例六: 常用函數介紹 簡易數學函數使用 #include <math.h> void main() { double x = 8.0; printf("\2: exp(x) is --> %f \n", exp(x)); printf("\2: log(x) is --> %f \n", log(x)); printf("\2: log10(x) is --> %f \n", log10(x)); printf("\2: sqrt(x) is --> %f \n", sqrt(x)); } 數學函數:(要include<math.h>檔頭) exp(x) 指數函數,計算x的指數值 sqrt(x) 平方根函數,計算非負數x的平方根值 log(x) 自然對數函數,計算x的自然對數值
範例七: 常用函數介紹 應用亂數函數設計猜數字遊戲 #include <time.h> #include <stdlib.h> #include <time.h> void main() { int num, guess, count=0; randomize(); num = random(80) + 1; do printf("Enter your guess (1-80) : "); scanf("%d", &guess); count ++; if( guess > num ) printf(" Too high ...\n"); else if( guess < num) printf(" Too low ... \n"); else printf(" Bingo ! \n"); } while (( guess != num) && ( count < 5)); if (guess != num) printf(" Too bad. The number is %d \n", num); printf(" You are lucky !! \n"); 應用亂數函數設計猜數字遊戲 pre6.c