Make
each
day
count
當結構中的某個欄位成員是另⼀個結構變數,稱為巢狀結構
struct ename {
char lastname[12];
char firstname[12];
};
struct person {
char id[11];
char cname[10];
struct ename name;
};
存取巢狀結構欄位資料時,同樣使用「.」運算子逐層存取結構的成員
變數
struct person p = {"Z123456789", "李四", {"Lee", "Sam"}};
printf("姓名: %sn", p.cname);
printf("英文姓名: %s %sn", p.name.firstname, p.name.lastname);
巢狀結構 1/3
6
Make
each
day
count
#include <stdio.h>
#include <stdlib.h>
struct date {
int year;
int month;
int day;
};
struct ename {
char lastname[12];
char firstname[12];
};
void nested_struct(){
struct person {
char id[11];
char cname[10];
struct date birthday;
struct ename name;
};
巢狀結構 2/3
7
Make
each
day
count
void nested_struct(){
struct person {
char id[11];
char cname[10];
struct date birthday;
struct ename name;
};
struct person p = {"Z123456789", "李四", {2001, 2, 2}, {"Lee", "Sam"}};
printf("身份證字號: %sn", p.id);
printf("姓名: %sn", p.cname);
printf("生日: %d/%d/%dn", p.birthday.year - 1911, p.birthday.month,
p.birthday.day);
printf("英文姓名: %s %sn", p.name.firstname, p.name.lastname);
}
巢狀結構 3/3
8
Make
each
day
count
#include <stdio.h>
#include <stdlib.h>
struct char_code {
char ch;
char ascii;
};
void struct_ary() {
struct char_code numeric[10];
int i;
for (i = 0; i < 10; i++){
numeric[i].ch = '0' + i;
numeric[i].ascii = '0' + i;
}
for (i = 0; i < 10; i++){
printf("字元%c ASCII碼 = %dn", numeric[i].ch, numeric[i].ascii);
}
}
結構陣列 2/2
10
Make
each
day
count
如同 C 語言其他資料型態的指標,指標也可以指向結構,我們可以建
立指標來指向結構。例如:宣告 time 結構儲存時間資料,如下所示:
struct time {
int hours;
int minutes;
};
因為指標需要指向結構變數的位址,所以需要先宣告結構變數,然後
才能建立指向此結構變數位址的指標,如下所示:
struct time now, *ptr;
上述程式碼宣告結構變數 now 和結構指標 ptr,接著將結構指標指向
結構,如下所示:
ptr = &now; //結構指標 ptr 指向結構變數 now 的位址
結構指標 1/2
11
Make
each
day
count
現在,我們可以使用指標存取結構的成員變數,如下所示:
(*ptr).minutes = 35;
上述程式碼使用取值運算子取得結構變數now後,再存取成員變數
minutes 的值,相當於執行程式碼 now.minutes = 35;
C 語言提供結構指標的「->」運算子,可以直接存取結構的成員變數
值,如下所示:
ptr->hours = 18;
上述變數ptr是結構指標,可以存取成員變數hours的值。請注意!當
在 C 程式碼中看到「->」運算子時,就表示變數是指向結構的指標變
數
結構指標 2/2
12
Make
each
day
count
char *gets(char *str)
從標準輸入中讀取⼀行(直到換行字元或文件結束字元),並將其儲存到
由str指向的字串變數
char name[16];
gets(name);
int getche(void)
從標準輸入讀取⼀個字元,它不使用緩衝區來存儲輸入字元,讀取輸
入字元立即返回,而無需等待Enter鍵
char gender;
gender = getche();
int getch(void)
功能類似getche(),但輸入的字元不會顯示螢幕上
字串及字元輸入函式
13
Make
each
day
count
刪除串列資料
插入串列資料
鏈結串列 2/8
18
head
next
data
next
data
next
data
next
data
next
data
NULL
head
next
data
next
data
next
data
next
data
next
data
NULL
next
data
NEW Node
Make
each
day
count
建立鏈結串列
宣告 3 個結構指標
struct node *head, *ptr, *newptr;
產生第⼀個節點 (node1)
newptr = (struct node*)malloc(sizeof(struct node));
設定 node1 節點的初值
strcpy(newptr->data, "node1");
newptr->next = NULL;
鏈結串列 3/8
19
newptr
next
data
newptr
next
data
NULL
node1
Make
each
day
count
將 head 與 ptr 指標都指到 node1 節點
head = ptr = newptr;
產生第二個節點 (node2),並將newptr指向該節點起始位址
newptr = (struct node*)malloc(sizeof(struct node));
鏈結串列 4/8
20
ptr
next
data
NULL
node1
newptr
head
newptr
ptr
next
data
NULL
node1
head
Make
each
day
count
設定 node1 節點的初值
strcpy(newptr->data, "node2");
newptr->next = NULL;
將 node2 串接到 node1 之後
ptr->next = newptr;
ptr = newptr;
鏈結串列 5/8
21
newptr
ptr
next
data
NULL
node1
head
NULL
node2
node1
head
newptr
NULL
node2
ptr
Make
each
day
count
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char data[12];
struct node *next;
};
void linked_list(){
struct node *head, *ptr, *newptr;
int i;
//建立node1
newptr = (struct node*)malloc(sizeof(struct node));
strcpy(newptr->data, "node1");
newptr->next = NULL;
head = ptr = newptr;
鏈結串列 6/8
22
Make
each
day
count
堆疊 (stack) 是⼀種特殊的儲存空間,只允許在有序的線性資料集合的
⼀端 (稱為堆疊頂端 top) 進行加入資料 (push) 和移除資料 (pop) 運算。
因而按照後進先出 (LIFO, Last In First Out) 的原理運作
堆疊
25
Make
each
day
count
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct node {
int content;
struct node *next;
};
struct node *top = NULL;
void push(int data){
struct node *newnode;
newnode = (struct node *)malloc(sizeof(struct node));
newnode->content = data;
newnode->next = top;
top = newnode;
}
使用鏈結串列實作堆疊 1/4
26
top NULL
next
newnode data
top NULL
newnode data
執行newnode->next = top;後 執行top = newnode;後
Make
each
day
count
int pop(void){
struct node *temp = top;
int data;
if (temp == NULL) return '0';
data = top->content;
top = top->next;
free(temp);
return data;
}
void display(void){
struct node *temp = top;
if (temp == NULL) {
printf("n空堆疊");
return;
}
printf("n堆疊資料:");
while (temp != NULL) {
printf(" %d,", temp->content);
temp = temp->next;
}
}
使用鏈結串列實作堆疊 2/4
27
top
temp
NULL
執行top = top->next;後
top
temp
NULL
執行free(temp);後
top
temp
NULL
NULL
Make
each
day
count
void test_stack(){
int data;
display();
push(1);
push(2);
push(3);
display();
data = pop();
if (data == '0') printf("n空堆疊");
else printf("n從推疊取出資料 %d", data);
display();
data = pop();
if (data == '0') printf("n空堆疊");
else printf("n從推疊取出資料 %d", data);
data = pop();
if (data == '0') printf("n空堆疊");
else printf("n從推疊取出資料 %d", data);
data = pop();
if (data == '0') printf("n空堆疊");
else printf("n從推疊取出資料 %d", data);
}
使用鏈結串列實作堆疊 3/4
28
Make
each
day
count
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct qnode {
int content;
struct qnode *next;
};
struct qnode *front, *rear;
void init_queue(void){
front = (struct qnode *)malloc(sizeof(struct qnode));
rear = front;
rear->next = NULL;
}
使用鏈結串列實作佇列 1/6
31
? NULL
front
rear
Make
each
day
count
void put_data(int data){
struct qnode *newnode;
newnode = (struct qnode *)malloc(sizeof(struct qnode));
newnode->content = data;
newnode->next = NULL;
rear->next = newnode;
rear = newnode;
}
使用鏈結串列實作佇列 2/6
32
?
front
rear
執行rear->next = newnode;後
data NULL
newnode
?
rear
執行rear = newnode;後
data NULL
newnode
front
Make
each
day
count
int get_data(void){
struct qnode *temp;
int data;
if (front == rear)
return '0';
temp = front->next;
data = temp->content;
free(front);
front = temp;
return data;
}
使用鏈結串列實作佇列 3/6
33
?
front
data
temp
data NULL
rear
執行temp = front->next;後
front
data
temp
data NULL
rear
執行free(front);後
NULL
front
temp
data NULL
rear
執行front = temp;後
Make
each
day
count
void show_queue(void){
struct qnode *temp;
int data;
if (front == rear) {
printf("n空佇列");
return;
}
printf("n佇列資料:");
temp = front->next;
while(temp != NULL) {
printf(" %d,", temp->content);
temp = temp->next;
}
}
使用鏈結串列實作佇列 4/6
34
Make
each
day
count
data = get_data();
if (data == '0’)
printf("n空佇列");
else
printf("n從佇列取出資料 %d", data);
data = get_data();
if (data == '0’)
printf("n空佇列");
else
printf("n從佇列取出資料 %d", data);
}
使用鏈結串列實作佇列 6/6
36
Make
each
day
count
void call_by_address() {
struct scores john = {"08101", 40};
printf("傳值呼叫前n");
printf("學號%s 成績 = %dn", john.no, john.score);
func_a(&john);
printf("傳值呼叫後n");
printf("學號%s 成績 = %dn", john.no, john.score);
}
結構參數傳遞 4/6
40
Make
each
day
count
結構陣列當引數時,則是使用傳址呼叫
#include <stdio.h>
#include <stdlib.h>
struct student {
char no[8];
char name[16];
int score;
};
int search(int, struct student[]);
void show(struct student[], int);
void call_by_ary() {
struct student s[] = {{"8101", "Tom", 80},
{"8102", "John", 88},
{"8103", "Kent", 95}};
int i;
i = search(sizeof(s)/sizeof(struct student), s);
show(s, i);
}
結構參數傳遞 5/6
41
Make
each
day
count
int search(int arysize, struct student sary[]){
int i, max, num;
struct student *ptr = sary;
max = num = 0;
for (i = 0; i < arysize; i++, ptr++){
if (ptr->score > max){
max = ptr->score;
num = i;
}
}
return num;
}
void show(struct student sary[], int i){
printf("%st%st%d", sary[i].no, sary[i].name, sary[i].score);
}
結構參數傳遞 6/6
42