1. 程式人生 > 其它 >C語言:布林值、巨集定義、型別定義

C語言:布林值、巨集定義、型別定義

技術標籤:Cc語言

巨集定義

因為許多程式需要變數能儲存真值假值,所以C語言缺少適當的布林型別可能會很麻煩。一直採用模擬布林型變數的方法來解決麻煩,這種模擬的方法是先宣告int型變數,然後將其賦值0或1。

int flag;
flag = 0;
...
flag = 1;

雖然這種方法可行,但是對於程式的可讀性沒有多大的貢獻,因為沒有明確地表示flag的賦值只能是布林值,並且也沒明確指出0和1表示假和真。
為了使程式更加便於理解,一個好的方法是類似於TRUE和FALSE這樣的名字來定義巨集。

#define TRUE 1
#define FALSE 2

現在對flag的賦值有了更加自然的形式。

flag = FALSE;
...
flag = TRUE;

為了判斷flag是否為真,可以寫成

if(flag == TRUE)
...

或者只寫成

if(flag)
...

為了判斷flag是否為假,可以寫成

if(flag == FALSE)
...

或者只寫成

if(!flag)
...

為了進一步實現這個想法,甚至可以定義用作型別的巨集

#define BOOL int;

宣告布林型變數時可以用BOOL代替int:

BOOL flag;

型別定義

上個標題中我們用#define指令建立了一個巨集,可以用來定義布林型資料:

#define BOOL int;

但是,一個更好的設定布林型的方法是所謂的型別定義(type define)的特性:

typedef int Bool;

注意

  1. 定義的型別名放在後面
  2. 將首字母大寫不是必須的,只是一些C程式設計師的習慣。

型別定義使得程式更易於理解,例如cash_in和cash_out都用來儲存美元數量,我們可以將Dollars宣告成

typedef float Dollars;

Dollars cash_in,cash_out;

問題:用typedef和用作型別的巨集定義#define Dollars float有什麼區別?

  1. 作用域不同,#define在預處理時進行,作用於全域性,typedef可作用於區域性
  2. 實現效果不一定相同
#include <stdio.h>
#include
<typeinfo>
#define POINTER int* typedef int* Pointer2; int main(){ int* a1,a2,a3,a4; POINTER p1,p2,p3,p4; Pointer2 p5,p6,p7,p8; printf("%s %s %s %s\n",typeid(a1).name(),typeid(a2).name(),typeid(a3).name(),typeid(a4).name()); printf("%s %s %s %s\n",typeid(p1).name(),typeid(p2).name(),typeid(p3).name(),typeid(p4).name()); printf("%s %s %s %s\n",typeid(p5).name(),typeid(p6).name(),typeid(p7).name(),typeid(p8).name()); return 0; }

執行上面的測試程式
輸出結果為:
在這裡插入圖片描述
可見巨集定義是簡單的字元替換,當宣告指標變數int*時,由於C語言的規範,一次只能宣告一個,後續宣告的變數將為int型,巨集定義後效果也是如此。但typedef更徹底地將int*視為一個型別。

承接上述的

typedef float Dollars;

Dollars cash_in,cash_out;

這樣的寫法比下面的寫法更有意義:

float cash_in, cash_out;

優點:

  1. 型別定義還可以使程式更容易修改。如果之後決定Dollars的實際應用型別修改為double,則只需要修改型別定義就足夠了:typedef double Dollars
    如果不使用型別定義,則需要找出表示美元的變數並把宣告中的float修改成double。
    (這個有點巨集定義也是可以實現的,不過型別定義不是全域性的,修改起來更靈活)
    型別定義是編寫可移植程式的一種重要工具。程式從一臺計算機移動到另一臺計算機可能引發的問題之一就是不同計算機相同型別的取值範圍(機器碼位數)可能不同。如果i是int型變數,那麼賦值語句i = 100000;在一臺使用32位整數的計算機上是沒問題的,但是在一臺使用16位整數的計算機上就會出錯。簡單口算一下32*1024(-215~215)<40000 無法表示100000。

  2. 可移植性技巧
    為了更大的可移植性,可以考慮用typedef定義新的整數名。
    假設編寫的程式需要用變數來儲存產品數量,取值在0~50000.為此可以使用long int型變數,但是使用者更願意使用int型變數,因為算數運算int型比long int型運算速度更快;同時,int型變數可以佔用較少的空間。
    我們可以定義自己的數量型別 ,而避免使用int型別宣告數量變數;typedef int Quantity;並且使用這種型別來宣告變數:Quantity q;
    打把程式轉到小值整數的機器上時,需要改變Quantity的定義:
    typedef long int Quantity;
    可惜的是,這種變化無法解決所有問題,因為Quantity宣告的變化可能會導致改變Quantity型別變數的使用方式。至少使用了Quantity型別的變數在scanf和printf函式的使用上需要改變,用轉換說明%ld替換%d。

C語言庫自身使用typedef為那些可能依據C語言實現的不同的型別建立型別名;這些型別名的名字經常以_t結尾,比如ptrdiff_tsize_twchar_t