C Primer Plus–結構和其他數據類型(2)
文章目錄
枚舉類型 enumerated type
枚舉是用來代表整數常量的符號,枚舉類型的聲明與struct聲明類似。枚舉常量都是int
型的。枚舉聲明的花括號內枚舉了該類型變量可能有的值。枚舉是爲了增強程序的可讀性。
enum vehicle {bicycle,car,plane,train,ship};
上面說了枚舉類型就是int
類型的常量,那麼凡是可以使用int
的地方都可以使用枚舉常量。
枚舉默認值
枚舉列表中的默認值被指定爲整數值0、1、2等等。如上面枚舉聲明中:
bicycle
、car
、plane
、train
、ship
的值依次爲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
相似,但是它們具有三個不同之處:
- 與
#define
不同,typedef
給出的符號名稱僅限於對類型,而不是對值 typedef
的解釋由編譯器而不是預處理器執行- 雖然它的的範圍有限,但在其受限範圍內,
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);
}