瘋子C語言筆記(結構體/共用體/枚舉篇)

 

(一)結構體類型程序員

1.簡介:數組

例:函數

struct datespa

{指針

  int month;內存

  int day;原型

  int year;string

};io

struct student編譯

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 類型*/

  char addr[30];

}student1,student2;

(1):結構體可嵌套

(2):與枚舉相比結構體內元素爲變量,而枚舉爲常量

(3):元素只能單個引用:如:student.num;  student.birthday.month;

(4):內部元素變量能夠與其餘變量重名且互不影響;

(5):賦值:student.num = 10010;

2.初始化

(可直接賦值)

struct student

{

  long int num;

  char name[20];

  char sex;

  char addr[20];

}a = {10101,"Li Lin","M","BeiJing Road"};

3.結構體數組

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 類型*/

  char addr[30];

};

struct student stu[3];

注:數組中每個元素都是一個結構體類型數據;

4.指向結構體類型數據的指針

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 類型*/

  char addr[30];

};

struct student stu_1;

struct student *p;

p = &stu_1;

在實例化結構體指針時,務必先malloc分配對應的地址(在堆中開闢);

使用指針務必在堆中開闢地址空間,以避免出現野指針;

注:

(1)一個結構體變量的指針就是該變量所佔據的內存段的起始地址(開頭地址);

(2)(*p).num 等價於 stu_1.num;(*p兩端的括號不能省略)

(3)(*p).num 等價於 p->num; (-> 稱爲指向運算符)

(4)以下運算

p->n; 獲得p指向的結構體變量中的成員n的值。

p->n ++;獲得p指向的結構體變量中的成員n的值,用完該值後使它加1。

++ p->n;獲得p指向的結構體變量中的成員n的值加1,而後再使用它。

-> 運算優先級大於 ++;

5.指向結構體數組元素的指針

struct student

{

  int num;

  char name[20];

  char sex;

  int age;

  struct date birthday;  /*birthday 是 struct date 類型*/

  char addr[30];

};

struct student stu[3];

struct student *p;

for( p = stu;p < stu + 3;p ++)

  printf( "%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);

注:p是一個指向struct student 類型數據的指針變量,它用來指向一個struct student 類型的數據(及:stu數組的一個元素如stu[0],stu[1],的起始地址),不該用來指向stu數組元素中的某一成員,

p = stu[1].name;   這樣的用法是錯誤的

可是:

強制類型轉換後能夠用

p = (struct student *)stu[0].name;  這樣是正確的;

這樣的話:p的值是stu[0]元素的name成員的起始地址。printf(「%s」,p)輸出stu[0]中成員name的值。但printf(「%s」,p +1)則輸出 stu[1]中name的值。p+1 的值是在p值的基礎上加上結構體struct student的字節長度。

由於:p加減運算他的類型就是他的最小運算單元
  

 6.結構體變量作函數參數

注:用結構體變量作函數參數時,採用值傳遞的方式,將結構體變量所佔的內存單元的內容所有順序傳遞給形參。

#include<stdio.h>

#include<string.h>

#define FORMAT "%d\n%s\n%f\n%f\n%d\n"

struct student

{

  int num;

  char name[20];

  float score[3];

} ;

void main()

{

  void print(struct student);

  struct student stu;

  stu.num = 12345;

  strcpy(stu.name,"Li Li");

  stu.score[0] = 67.5;

  stu.score[1] = 89;

  stu.score[2] = 78.6;

  print(stu);

}

void print(struct student stu)

{

  printf(FORMAT,stu.num,stu.name,stu.score[0], stu.score[1],stu.score[2]);

  printf("\n");

}

運行結果:

12345

Li Li

67.500000

89.000000

78.599998

 7.用指針處理鏈表

例:

#include<stdio.h>

#define NULL 0

struct student

{

  long num;

  float score;

  struct student *next;

};

void main()

{

  struct student a,b,c,*head,*p;

  a.num = 10101;a.score = 89.5;

  b.num = 10103;b.score = 90;

  c.num = 10107;c.score = 85;

  head = &a;

  a.next = &b;

  b.next = &c;

  c.next = NULL;

  p = head;

  do

  {

    printf("%ld%5.1f\n",p -> num,p -> score);

    p = p -> next;    //使P指向下一結點

  }

  while(p != NULL);

}

運行結果:

10101  89.5

10103  90.0

10107  85.0

注:

該例子結點都是在程序中定義的,不是臨時開闢的,也不能用完後釋放,這種鏈表稱爲「靜態鏈表」。

 8.處理動態鏈表

①malloc函數

原型:void *malloc(unsigned int size)

其做用是在內存的動態存儲區分配一個長度爲size的連續空間。此函數的值(即「返回值」)是一個分配域的起始地址(類型爲void)。若是此函數未能成功地執行(例如內存不足),則返回空指針(NULL)。

②calloc函數

原型:void *calloc(unsigned n unsigned int size);

其做用是在內存的動態存儲區分配n個長度爲size的連續空間。函數返回一個指向分配域起始位置的指針;若是分配不成功,返回NULL;

③free函數

原型:void free (void *p);

其做用是釋放由p指向的動態存儲區,使這部份內存區能被其餘變量使用。p是最近一次調用calloc或malloc函數時返回的值。free函數無返回值。

 

C語言跟內存 分配方式
1) 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。
2) 在棧上建立。在執行函數時,函數內局部變量的存儲單元均可以在棧上建立,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,可是分配的內存容量有限。
3從堆上分配,亦稱動態內存分配。程序在運行的時候用mallocnew申請任意多少的內存,程序員本身負責在什麼時候用freedelete釋放內存。動態內存的生存期由咱們決定,使用很是靈活,但問題也最多

9.創建動態鏈表

 

 ------------------------------------------------------------------------------------

(二)共用體

1.概述:使幾個不一樣的變量共佔同一段內存的結構,稱爲「共用體」類型的結構;

2.定義

union 共用體名

{

  成員表列;

}變量表列;

如:

union data

{

  int i;

  char ch;

  float f;

}a,b,c;

或者

union data

{

  int i;

  char ch;

  float f;

};

union data a,b,c;

注:共用體與結構體定義形式類似,但佔內存不一樣,結構體佔的是各個成員內存和,共用體的內存是成員中字節最長的那個;

3.共用體變量的引用方式

必須先定義後引用,引用時只能引用共用體變量中的成員。

如:

a.i

a.ch

a.f

4.共用體類型數據的特色

(1)同一個內存段能夠用來存放幾種不一樣類型的成員,但在每一瞬時只能存放其中一種,而不是同時存放幾種。因此對於共用體變量中起做用的成員是最後一次存放的成員。

如:

a.i = 1;

a.c = 'a';

a.f = 1.5;

只有a.f 是有效的,a.i ,a.c已經無心義了,此時用"printf("%d",a);"是不行的,"printf("%d",a.i);"是不行的,"printf("%d",a.f);"能夠

(2)共用體變量的地址、它的各成員的地址都是同一地址。

:&a, &a.i, &a.c, &a.f都是同一地址

(3)不能對共用體變量名賦值不能賦值給共用體名不能定義共用體時對它初始化

union data

{

  int i;

  char ch;

  float f;

}a={1,'a',1.5};    錯誤

a = 1;        錯誤

m =a;        錯誤

(4)不能把共用體變量做爲函數參數,也不能使函數帶回共用體變量,但能夠使用指向共用體變量的指針(和結構體變量這種用法相仿)。

(5)共用體類型能夠出如今結構體類型定義中,也能夠定義共用體數組。反之,結構體也能夠出如今共用體類型定義中,數組也能夠做爲共用體的成員。

  ------------------------------------------------------------------------------------

(三)枚舉類型

1.enum weekday{sum,mon,tue,wed,thu,fri,sat};(枚舉定義的量都爲常量)

聲明一個枚舉類型 enum weekday,能夠用此類型來定義變量。如:

enum weekday workday,week_end;

workday和week_end被定義爲枚舉變量,它們的值只能是sum到sat之一。如:

workday = mon;

week_end = sum;

等價於

enum {sum,mon,tue,wed,thu,fri,sat} workday,week_end;

它們都是其中之一。

2.固然能夠用

typedef  enum {sum,mon,tue,wed,thu,fri,sat}  weekday;

即等價於 enum weekday{sum,mon,tue,wed,thu,fri,sat};

3.枚舉類型特色

(1)枚舉元素做爲常量,它們是有值的,C語言編譯按定義時的順序使它們的值爲 0,1,2.....

在上面定義中sun的值爲0,mon的值爲1......sat的值爲6。

例如:

printf("%d",workday);

將輸出整數 1。

能夠在定義式對元素賦初值

如:

enum weekday {sum =7,mon =1,tue,wed,thu,fri,sat}  workday,week_end;

定義sun爲7,mon爲1,其餘值仍是按順序給值,即sat任爲6

③枚舉類值可比較大小作判斷。

(2)一個整數不能直接賦給一個枚舉變量

如:

workday = 2;    錯誤

但可

workday = (eunm weekday)2;    正確

相關文章
相關標籤/搜索