C Primer Plus--結構和其他數據類型(2)

C Primer Plus–結構和其他數據類型(2)

枚舉類型 enumerated type

枚舉是用來代表整數常量的符號,枚舉類型的聲明與struct聲明類似。枚舉常量都是int型的。枚舉聲明的花括號內枚舉了該類型變量可能有的值。枚舉是爲了增強程序的可讀性。

enum vehicle {bicycle,car,plane,train,ship};

上面說了枚舉類型就是int類型的常量,那麼凡是可以使用int的地方都可以使用枚舉常量。

枚舉默認值

枚舉列表中的默認值被指定爲整數值0、1、2等等。如上面枚舉聲明中:
bicyclecarplanetrainship的值依次爲0 1 2 3 4

爲枚舉指定值

    enum levels {low = 20, medium = 50, high = 80, perfect = 100};
    enum phones {ios, windowsPhone = 60, blackberry = 80, android};
    //ios = 0; android = 81

在C中,允許對枚舉類型的變量使用自增(++)或自減(–)符號,但是在C++中不允許,爲了使得程序兼容,應該一開就將變量聲明爲int型。

enum vehicle {bicycle,car,plane,train,ship};
    enum vehicle trans;
    //在C++中要聲明爲
    //int trans;
    //trans此時的值不確定,需要賦值
    for (trans = bicycle;  trans <= ship  ; trans++) {
        printf("%d\n",trans);
    }

命名空間 namespace

在C中,變量名和標記名(結構標記、聯合標記、枚舉標記)不在同一個命名空間中,因此二者可以同名,但在C++中不可以。

struct car {
        char brand[30];
        int litre;
    };
    int car = 0;
    //C中不衝突

typedef關鍵字

typedef工具是一種高級數據特性,他使您能夠爲某一類型創建您自己的名字。在這個方面,它和#define相似,但是它們具有三個不同之處:

  1. #define不同,typedef給出的符號名稱僅限於對類型,而不是對值
  2. typedef的解釋由編譯器而不是預處理器執行
  3. 雖然它的的範圍有限,但在其受限範圍內,typedef#define更靈活

這裏就告訴我們typedef並不創建新的數據類型,只是創建了易於使用的標籤別名。
例:頂一個一個數據類型別名BYTE,它只佔一個字節,可以先定義一個char變量BYTE,然後在前面加上typedef即可。

typedef unsigned cahr BYTE;

BYTE x;//定義一個x
BYTE Y[10];//定義一個數組容納十個BYTE
BYTE * z;//定義一個指向BYTE的指針

總之,#define只是由預處理器對文件裏的字符進行替換,而typedef則新建了一種數據類型的代替。

typedef char * STRING;//STRING成了char指針的別名
STRING a,b;//聲明兩個char指針a,b

//若是用define來試一試
#define STRING char *;

STRING a , b;//這裏被預處理器替換,成了char * a , b;兩個就不都是指針了,只有a是,b成了字符。

typedef struct {
	float real;
    float imag;
} COMPLEX; //將這個struct起個別名COMPLEX

COMPLEX foo = { 1.0 ,1};//一個複數

複雜的typedef

typedef char (* FRPTC())[5];

這裏FPRTC返回的是一個指向含有5個元素的char數組的指針。

* () []修飾符

這三者優先級有低到高:* < () = [],而且他們與變量名的結合是從左到右的。

int foo[12][24];//一個12x24的int二維數組
int * p;//一個指向int的指針
int ** ptr;//一個指向int的指針的指針
char * strings[5];//一個數組,共5個元素,每個元素是一個指向char的指針
int (* pointer) [5];//一個指向int[5]數組的指針
int * bar[12][24];//一個12x24的二維數組,每個元素是一個指向int的指針
int (* pp) [12][24];//一個指向12x24二維數組的指針
int (* ppp[3]) [4];//一個數組,共三個元素,每個元素是一個指向int[4]數組的指針

char * func();//一個返回值爲指向char的指針的函數
char (* funcp) func1();//一個指針,該指針指向一個返回類型爲char的函數
char (* funcps[3]) func2();//一個數組,共3個元素,每個元素是一個指針,指針指向一個返回值爲char的函數

typedef與這三個運算符結合

typedef int array5[5];
typedef array5 * p_to_array5;
typedef p_to_array5 arrayp[10];

array5 foo;//foo是一個int[5]數組
p_to_array5 p;//p是一個指向int[5]數組的指針
arrayp array;//array是一個數組,共10個元素,每個元素是一個p_to_array5指針

函數與指針

指針可以指向函數。指向函數的指針保存着函數代碼起始處的地址。當聲明一個函數指針時,必須聲明它指向的函數類型,即指定函數的返回類型以及函數的參量類型。
void eat(char * food);聲明瞭一個形式參量爲字符指針的的函數,要聲明一個指向這樣類型函數的指針,需要這樣做:
void (* pointer) (char *);

聲明一個指向特定函數類型的指針,首先聲明一個該類型的函數,然後用(* pf)形式的表達式替換函數名稱,pf就成爲了可指向那種類型函數的指針了。

聲明瞭指針之後,還需對指針進行賦值,賦值給指針的函數必須擁有與指針聲明中一致的形參和返回值。

函數指針作爲參數

有了函數的指針,可以利用指針來訪問函數:

  • 通過 (*pf) (參數)的方式訪問函數
  • 通過 pf (參數)的方式訪問函數
#include <stdio.h>

void toUpper(char *);
void toLower(char *);
void foo( void (*pf)(char *),char * string);
int main() {
    void (*pf) (char *);
    
    char test[] = "I love you";
    
    pf = toUpper;
    
    (* pf)(test);//1
    
    pf = toLower;
    
    pf(test);//2
    
    foo(pf,test);//foo函數調用
}
/*
 * foo接受一個函數指針與char指針
 */
void foo( void (*pf)(char *),char * string){
    pf(string);
    puts(string);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章