一.結構體html
由不一樣類型的數據組合成一個總體,以便引用,這些組合在一個總體中的數據是互相聯繫的。編程
1.1如何聲明結構體呢?數組
struct 結構體名 //結構體名字用做結構體類型的標誌函數
{成員列表}; spa
好比:指針
1 struct student 2 { 3 int num; //2 4 char name[20]; //20 5 char sex; //1 6 int age; //2 7 float score; //4 8 char addr[30]; //30 9 };
注意:聲明只是指定了一個結構體類型,它至關於一個模型,但其中並沒有具體數據,系統對之也不分配實際內存單元。爲了能在程序中使用結構類型的數據,應當定義結構體類型的變量....code
1.2如何定義結構體變量呢?htm
方法一:能夠在聲明的同時定義。在第9行分號前面添加 「student1,student2」 便可代表,student1和student2就是student結構體的兩個變量。在定義告終構體變量後,系統會爲之自動分配內存,上述就分配了59個字節。blog
通常形式爲:內存
struct 結構體名
{
成員表列
}變量名錶列;
方法二:直接定義結構類型變量。此形式不出現結構體名!
通常形式爲:
struct
{
成員表列
}變量名錶列;
此處特別強調:類型和變量的區別,變量能進行賦值、存取、和運算,可是類型不行。在編譯時,類型是不分配空間的,只能對變量分配空間。因此,對結構體裏面的各個的成員可都以單元使用,由於它是有內存的。那麼怎麼去用結構體裏面的成員呢?接下來就告訴你!
方法3:在已經聲明/定義告終構體類型時,利用了類型名稱定義結構體變量!
struct student student1; //student1是變量名;struct student 是變量類型名稱
1.3如何使用結構體成員變量
1 #include <stdio.h> 2 struct student 3 { 4 long int num; 5 char name[20]; 6 char sex; 7 char addr[30]; 8 }a = {89031, "Li Lin", 'M', "123 Beijing Road"}; //定義告終構體變量,並給予賦值 9 void main() 10 { 11 printf("NO. : %d\nname: %s\nsex: %c\naddress: %s\n", a.num, a.name, a.sex, a.addr) //輸出結構體成員的值 12 }
可是須要注意如下幾點:
(1)不能將一個結構體變量做爲一個總體進行輸入和輸出,只能對結構體變量在的各個成員分別進行輸入輸出!
引用結構體變量中成員方式: 結構體變量.成員名稱
若p是指向 結構體類型(student) 的指針,也能夠這樣表示成員 (*)p.age 也能夠p->age
故,以上三種表達成員的方式均是等價的!
附:->是指向運算符
p -> n 獲得 p 指向的結構體變量中的成員 n 的值
p -> n ++ 獲得 p 指向的結構體變量中的成員 n 的值,用完值後使它加1
++p -> n 獲得 p 指向的結構體變量中的成員 n 的值使之加 1 (先加)
(2)若是成員自己又屬於一個結構體類型,則要用若干個成員運算符,一級一級地找到最低一級的成員,只能對最低級的成員進行運算、賦值!
結構體變量.結構體中的結構體名稱.成員名稱
附: .是優先級最高的運算符
1.4結構體數組
定義方法:(1)struct student stu[3];
(2)在結構體最後,分號以前加入數組,如stu[4]
(3)
-----相似定義結構體變量,只不過是變量是一個數組形式存在而已
賦值方式:(舉個例子)
1 struct student 2 { 3 int mum; 4 char name[20]; 5 char sex; 6 int ag; 7 float score; 8 char addr[30]; 9 }stu[3] = {{10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"}, 10 {10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"}, 11 {10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"}};
定義數組 stu 時,元素個數能夠不指定,即寫成如下形式:
stu[] = {{...},{...},{...}};
綜上,舉一個例子:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stlib.h> 4 5 struct person 6 { 7 char name[20]; 8 int count; 9 }leader[3] = {{"Li", 0}, 10 {"Zhang", 0}, 11 {"Fun", 0}}; 12 13 void main() 14 { 15 int i, j; 16 char leader_name[20]; 17 for(i = 1; i<= 10;i++) 18 { 19 scanf("%s", leader_name); 20 for(j=0;j<3;j++) 21 if(strcmp(leader_name, leader[j].name) == 0) 22 leader[j].count ++; 23 } 24 printf("\n"); 25 for(i=0;i<3;i++) 26 printf("%5s: %d\n", leader[i].name, leader[i].count); 27 system("pause"); 28 }
2、typedef struct的用法
(此部分轉載自http://www.cnblogs.com/st-moon/p/5588321.html)
typedef爲C語言的關鍵字,做用是爲一種數據類型定義一個新名字。這裏的數據類型包括內部數據類型(int,char等)和自定義的數據類型(struct等)。
在編程中使用typedef目的通常有兩個,一個是給變量一個易記且意義明確的新名字,另外一個是簡化一些比較複雜的類型聲明。
第一種 上面第二種用法前面直接加typedef
typedef struct student{
char name[20];
int age;
char class;
}student_1;
這語句實際上完成兩個操做:
1) 定義一個新的結構類型
struct student{
char name[20];
int age;
char class;
};
2) typedef爲這個新的結構起了一個名字,叫student_1。
typedef struct student student_1; (對比typedef int student_1來進行理解)
所以,student_1實際上至關於struct student,這樣定義一個變量的時候,既能夠用struct student aaa,也能夠用student_1 aaa。student_1成了一個數據類型。
若是有逗號,好比
typedef struct student{
char name[20];
int age;
char class;
}student_1,student_2;
能夠先理解成
struct student{
char name[20];
int age;
char class;
}student_1;
和
struct student{
char name[20];
int age;
char class;
}student_2;
這樣再加上typedef,同上分析,也就是說struct student有兩個別名,分別是student_1和student_2,均可以代替struct student定義變量。也就是說有三種用法,struct student aaa;student_1 aaa;student_2 aaa都是等價的。
第二種 上面第三種用法前面直接加typedef
typedef struct {
char name[20];
int age;
char class;
}student_1;
根據惟一性,即定義變量的時候只能是student_1 aaa;
3、鏈表
是一種動態的存儲分配結構。
1 struct student 2 { 3 int num; 4 float score; 5 struct student *next; 6 };
鏈表含有一個頭指針變量,它存放一個地址,該地址指向一個元素,鏈表中每個元素稱爲結點。
結點包含兩部分:用戶須要用的實際數據、下個結點的地址!存放下一個地址的叫做 頭指針 (head).....固然,最後表尾的地址是NULL(空地址)
如下實現創建和輸出一個簡單的鏈表:
#include <stdio.h> #include <stdlib.h> #define NULL 0 struct student { long num; float score; struct student *next; }; void main() { struct student a, b, c, *head, *p; a.num = 99101; a.score = 89.5; b.num = 99103; b.score = 90; c.num = 99107; c.score = 85;//對結點的 num 和 score 成員賦值 head = &a;//將結點 a 的起始地址賦給頭指針 head a.next = &b;//將結點 b 的起始地址賦給 a 結點的 next 成員 b.next = &c; c.next = NULL;// c 結點的 next 成員不存放其餘結點地址 p = head;//使 p 指針指向 a 結點 do { printf("%ld %5.1f\n", p->num, p->score);// 輸出 p 指向的結點的數據 p = p->next;//使 p 指向下一結點 }while(p != NULL);//輸出完 c 結點後 p 的值爲 NULL system("pause"); } 運行結果 99101 89.5 99103 90.0 99107 85.0
3.1動態鏈表所需的函數
(1)malloc 函數
void *malloc(unsigned int size);
做用是在內存的動態存儲區中分配一個長度爲 size 的鏈接空間。些函數的值(即返回值)是一個指向分配空間起始地址的指針(基類型爲 void)。若是些函數未能成功地執行(例如內存空間不足)則返回空指針 NULL。
(2)calloc 函數
void *calloc(unsigned n, unsigned size);
其做用是在內存的動態區存儲中分配 n 個長度爲 size 的連續空間。函數返回一個指向分配空間起始地址的指針,若是分配不成功,返回 NULL。
用 calloc 函數能夠爲一維數組開闢動態存儲空間, n 爲數組元素個數,每一個元素長度爲 size。
(3)free 函數
void free(void *p);
其做用是釋放由 p 指向的內存區,使這部份內存區能被其它變量使用, p 是最後一次調用 calloc 或 malloc 函數時返回的值。free 函數無返回值。
請注意:之前的C版本提供的 malloc 和 calloc 函數獲得的是指向字符型數據的指針。ANSI C 提供的 malloc 和 calloc 函數規定爲 void * 類型。
例:動態表的創建
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define NULL 0 5 #define LEN sizeof(struct student) 6
7 struct student //聲明結構體 8 { 9 long num; 10 float score; 11 struct student *next; 12 }; 13 14 struct student *create() //建立結構體,create是指向這個結構體的指針 15 { 16 struct student *p1, *p2, *head; 17 int num; 18 float score; 19 int n = 0; 20 21 head = NULL; 22 23 p1 = p2 = (struct student *)malloc(LEN); 24 25 printf("please input num and score.\n"); 26 scanf("%d,%f", &p1->num, &p1->score); 27 28 while(p1->num != 0) 29 { 31 n ++; 32 if(n == 1) 33 head = p1; 34 else 35 p2->next = p1; 36 p2 = p1; 37 p1 = (struct student *)malloc(sizeof(struct student)); 38 printf("please input num and score.\n"); 39 scanf("%d,%f", &p1->num, &p1->score); 40 } 41 p2->next = NULL; 42 return head; 43 } 44 45 void printlist(struct student *head) 46 { 47 struct student *p; 48 p = head; 49 50 if(head != NULL) 51 { 52 do 53 { 54 printf("num=%d score=%f\n", p->num, p->score); 55 p = p->next; 56 57 }while(p != NULL); 58 } 59 } 60 61 void main() 62 { 63 struct student *head; 64 head = create(); 65 printlist(head); 66 system("pause"); 67 } 68 69 如下是對鏈表的各類操做 70 71 //打印鏈表 73 void printlist(struct student *head) 74 { 75 struct student *p; 76 p = head; 77 78 if(head != NULL) 79 { 80 do 81 { 82 printf("num=%d score=%5.2f\n", p->num, p->score); 83 p = p->next; 84 } while (p != NULL); 85 } 86 /* while(p -> next != NULL) 87 { 88 printf("num=%d score=%f\n", p->num, p->score); 89 p = p->next; 90 }*/ 91 } 92 93 //刪除節點 95 struct student *delNode(struct student *head, int num) 96 { 97 printf("delNode.\n"); 98 struct student *p1, *p2; 99 if(head == NULL) 100 { 101 printf("The List is NULL.\n"); 102 } 103 else 104 { 105 p1 = head; 106 while(p1->next != NULL && p1->num != num) 107 { 108 p2 = p1; 109 p1 = p1->next; 110 } 111 if(p1->num == num) 112 { 113 if(p1 == head) 114 head = p1->next; 115 else 116 p2->next = p1->next; 117 } 118 else 119 printf("Can not find list num.\n"); 120 } 121 return head; 122 } 123 124 //更新節點 126 struct student *update(struct student *head, int index, int num, float score) 127 { 128 printf("update.\n"); 129 struct student *p; 130 if(head == NULL) 131 { 132 printf("The List is NULL.\n"); 133 } 134 else 135 { 136 p = head; 137 while(p->next != NULL && p->num != index) 138 { 139 p = p->next; 140 } 141 if(p->num == index) 142 { 143 p->num = num; 144 p->score = score; 145 } 146 else 147 printf("Can not find list index.\n"); 148 } 149 return head; 150 } 151 152 //增長節點 153 154 struct student *add(struct student *head, int index, int num, float score) 155 { 156 printf("add.\n"); 157 struct student *p1, *p2, *p3; 158 if(head == NULL) 159 { 160 printf("The List is NULL.\n"); 161 } 162 else 163 { 164 p1 = p2 = head; 165 while(p1->next != NULL && p1->num != index) 166 { 167 p1 = p1->next; 168 p2 = p1; 169 } 170 if(p1->num == index) 171 { 172 p3 = (struct student *)malloc(LEN); 173 p3->num = num; 174 p3->score = score; 175 176 if(p2->next == NULL) 177 { 178 p2->next = p3; 179 p3->next = NULL; 180 } 181 else 182 { 183 p3->next = p2->next; 184 p2->next = p3; 185 } 186 } 187 else 188 printf("Can not find list index.\n"); 189 } 190 return head; 191 }