C Primer Plus--結構和其他資料型別(2)
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);
}