C數據類型和組合類型(結構、聯合、枚舉和typedef)

注:《C primer plus》筆記

一、基本類型:

    有符號整數
    int:系統的基本整數類型。C保證int類型至少有16位長(2字節),具體長度視系統和硬件而定。(位是二進制位)
    long:這種類型的整數保證最小位數不低於int類型,可能比int多偶數個字節。long int
    short:這種類型保證最少有16位,並且不能多於int類型的位長。short int
    long long:這種類型保證位長不低於long類型並且至少有64位長。long long int
    無符號整數
    unsigned int;unsigned long;unsigned short:無符號的整數,比有符號的整數多出來一個表示正負的位來表示數值,所以它可以表示更大一位的數值,但是不能表示負數。
    字符
    char:使用一個字節保存該字符的ASCII碼(整數),所以可以進行加減等運算。
    布爾值
    _Bool:值爲1(真)和0(假),該頭文件有b變量true和false來表示真假。
    實浮點數
    float:系統的基本浮點類型。至少能精確表示6位有效數字。
    double:範圍(可能)更大的浮點類型。能表示比float類型更多的有效數字(至少10位,通常會更多)以及更大的指數。
    long double:範圍(可能)再大的浮點類型。能表示比double類型更多的有效數字以及更大的指數。
    複數和虛浮點數
    float _Complex:
    double _Complex:
    long double _Complex:
    float _Imaginary:
    double _Imaginary:
    long double _Imaginary:
    
二、衍生類型:
    數組:多個相同基本類型數據的集合,如果有N個同類數據形成的數組,那麼他們的序號就是從0~N-1,引用元素使用:數組名[元素位],更可以使用多維數組。
    字符串:特指以'\n'字符結尾的字符數組。
    指針:存儲數據的地址,對變量使用:&變量,獲得變量的指針,對指針使用:*指針,獲得該地址中存儲的數據值。指針也可以形成數組。
    結構:某個對象具有不同數據類型的屬性,這時候使用數組不能很好地表示,就可以使用結構了,結構也可以是變量。引用方式:結構名.屬性。
    聯合:是在某一個存儲空間裏,可以存儲不同類型的數據,但是同一時間,該存儲空間只能存放一種類型的數據的數據類型。


結構定義:
struct 結構類型名 {
    聲明屬性1;//例如char title[40];
    聲明屬性2;//例如char authoer[40];
    ......
};
聲明結構:
struct 結構類型名 結構變量名;
引用結構:
結構變量名.屬性1 = "test1";
puts(結構變量名.屬性2);

結構變量在內存中的存儲結構爲:
就使用上而言,可以簡單地視爲結構定義產生了一個新的類型。

可以在結構定義時創建結構變量名。
struct book {
...
...
}library;

或者在聲明結構變量時直接對其屬性賦值,注意,賦值時,屬性之間逗號分隔。
struct book library = {
    "a book",
    "Jack,
    15.5
};
或者指定初始化某個屬性。
struct book test1 { .value = 10.99 };
或者按照任意順序初始化某些屬性。
struct book test2 { .value = 25.55,.author = "hank",.title = "Road" };
或者對一個屬性多次初始化,但是隻取最後一個值生效。
或者對指定屬性初始化後,進行不指定屬性的初始化,將會對指定屬性的下一個屬性進行初始化。
struct book test3 { .author = "boy",4.44};//下一個屬性value被初始化爲4.44

結構數組
若干個結構組成的數組。
結構數組定義和聲明
struct book {
    char titile[30];
    char author[30];
    float value;
};
struct book library[100];

嵌套結構
struct name {
屬性1;
屬性2;
};
struct friend {
struct name hank;
屬性4;
屬性5;
};
引用friend的hank的屬性1,可以使用friend.hank.屬性1
注意:屬性也可以成爲成員。

指向結構的指針
struct book test;
struct book * ptr;
ptr = &test;
注意:結構變量名不像數組那樣,是首個元素的地址。
利用指針訪問屬性:
ptr->屬性1
->就相當於使用變量名的小數點。

數組不允許直接被另一個數組賦值,但是,結構可以直接被另一個結構賦值,即便結構中有屬性是數組。
jiegou1 = jiegou2;
也可以初始化的時候直接賦值爲了那個一個結構變量。
struct names h1 = {"dsajkd","dsadsa"};
struct names h2 = h1;

結構不僅可以作爲參數傳入函數,也可以作爲返回值從函數返回,這就爲多值返回,繼指針之後,提供了又一種方法。

C99具有一個稱爲伸縮性數組成員(變長數組)的新特性。利用這一新特性可以聲明最後一個成員是一個具有特殊屬性的數組的結構。
該結構規則如下:
1,伸縮性數組成員必須是最後一個數組。
2,結構中必須至少有一個其他成員。
3,伸縮性數組就像普通數組一樣被聲明,除了它的方括號是空的。
示例如下:
struct flex {
    int count;
    double average;
    double scores[];
 };
聲明一個struct flex類型的變量之後,您不能立刻使用scores做任何事情,因爲還沒有爲它分配任何內存空間。C99的意圖是希望利用這種特性聲明一個指向struct flex類型的指針,然後使用malloc()來分配足夠的空間,以存放struct flex結構的常規內容和伸縮性數組成員需要的任何額外空間。例如,假設想要用scores表示含有5個double類型數值的數組,可以如下操作:
struct flex * pf;//聲明一個struct flex類型的指針。
pf = malloc(sizeof(struct flex) + 5 * sizeof(double));//分配內存
pf->count = 5;//指針方式對結構的屬性賦值
pf->scores[2] = 18.5;//指針方式對結構的伸縮性數組成員賦值;
free(pf);//注意釋放malloc()分配的內存。

因爲結構保存不同類型的數據,所以使用結構來進行數據庫編程是不錯的選擇。
結構的存在,爲各種算法提供了土壤,例如二叉樹。

聯合
    是在某一個存儲空間裏,可以存儲不同類型的數據,但是同一時間,該存儲空間只能存放一種類型的數據的數據類型。
聯合和結構一樣,需要事先定義模板
union hoid {
    int digit;
    double bigfl;
    char letter;
};
含義是,聯合名爲hold,可以存儲int類型的值,賦予變量digit。可以從年初double類型的值,賦予變量bigfl,可以存儲char類型的值,賦予變量letter;結構的大小以其最大的某個聲明變量一致,本例爲double類型,即8字節(不同硬件和系統,可能有差異)。
下面聲明聯合變量
union hold fit;//hold類型的聯合變量
union hold save[10];//10個聯合變量的數組
union hold * pu;//指向hold類型變量的指針
聯合的引用和賦值與結構類似,以小數點爲鏈接,可以將聯合的屬性(成員)賦值給聯合的屬性(成員),也可以將聯合賦值給聯合。
union hold valA;
valA.letter = 'R';//
union hold valB = valA;//聯合賦值給聯合
union hold valC = {88};//將值賦值給與聯合中的成員(屬性)類型一致的變量。
union hold valD = {.bigfl = 118.2};//直接指定賦值給某個屬性。
聯合同時只能有一個屬性(成員)有值存在:
fit.digit = 23;//存儲區中存儲int類型數據23
fit.bigfl = 2.0;//清除該存儲區已有的數據,存儲double類型數據2.0
fit.letter = 'h';//再次清理存儲區,存儲char類型數據h
聯合指針的引用和結構類型,也是使用符號->
pu = &fit;
int x = pu->digit;

聯合這種數據類型,可以表示某個對象的某個特徵正處於什麼狀態,當然,特徵有許多中,當狀態卻只有一種,這就是聯合的用法。聯合結合結構使用在某些實例中有不錯的效果。

枚舉
    創建一個int或char類型的數據類型,該數據類型的值爲其定義或初始化的時候的範圍,並不可跳出。使用枚舉的目的是提高程序的可讀性。
enum spectrum {red,orange,yellow,green,blue,violet};//初始化枚舉spectrum的初始值,其中red等是常量,並不需要其他定義聲明,就可以放在程序開頭。
enum spectrum color;//聲明枚舉spectrum類型的變量color。
red如果定義爲char類型,則不可移植到c++,因此,最好是定義爲int類型。
下面是使用示例:
color = blue;
for(color = red;color <= violet;color++)
...
如果將red等格式化爲%d打印,則可以看到,從第一個到最後一個常量,值都是從0開始依次增加1,這是枚舉類型的默認值。
當然,也可以在初始化枚舉時指定常量的值。
enum levels {low = 100,medium = 500,high = 2000};
如果只指定了部分常量的值,那麼在前面的會按照最初的從0開始的方式初始化,後面的會按照已經給出的值依次加1來初始化
enum feline {cat,lynb = 10,psm,ti};
其中cat被初始化爲0,psm,ti分別爲11,12.

typedef
    typedef是一種高級數據特性,它使您能夠爲某一類型創建您自己的名字(類型別名定義)。
typedef與#define的區別:
1,與#define不同,typedef給出的符號名稱僅限於對類型,而不是對值。
2,typedef的解釋由編譯器,而不是預處理器執行。
3,雖然typedef的範圍有限,但是在這個範圍內,typedef比#define靈活。
示例,單個字節的數值,其類型名稱進行別名化
typedef unsigned char BYTE;//類型別名定義
BYTE x,y[10],*z;//使用別名進行數據變量的定義。

typedef定義的類型別名有效範圍,和變量定義一樣,都分爲靜態或自動(或者說全局或局部)。可以套用變量的作用域等來看待類型別名。
typedef可以增加程序的移植性,因爲只需在程序頭部進行定義的修改,即可實現全篇類型別名的類型的修改。
另外,#define也可以實現類型別名,但是功能上和typedef有一定區別:
#define STRING char *
typedef STR char *;
STRING name,sign;//實現char * name,sign只能將第一個變量聲明爲指針,而無法作用於第二個變量。
STR na,si;//實現char * na,* si,可以作用於本行的所有變量。

typedef也可以作用於結構、聯合等。



 


發佈了45 篇原創文章 · 獲贊 7 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章