# 【課堂筆記】師大-程式設計(二) ```c char c; while (scanf("%c", &c) != EOF) { printf("%c", c); } char s[20]; while (scanf("%s", s) != EOF) { printf("%s", s); } ``` ```c #include <stdio.h> #include <ctype.h> int main() { if(isalnum('a')) printf("是字母或數字\n"); if(isalpha('a')) printf("是字母\n"); if(isdigit('1')) printf("是數字\n"); if(islower('a')) printf("是小寫\n"); if(isupper('A')) printf("是大寫\n"); char s[] = "Hello"; for (int i = 0; s[i] != '\0'; i++) { printf("%c", tolower(s[i])); printf("%c", toupper(s[i])); } } ``` ```c #include <stdio.h> #include <string.h> int main() { char s[] = "Hello"; int length = strlen(s); printf("%d", length); } ``` ```c char s[20]; char *ptr = s; scanf("%s", ptr); printf("%s", ptr); ``` ```c char a[] = "hello"; char *b = "hello"; printf("size = %ld\n", sizeof(a)); // 6 printf("size = %ld\n", sizeof(b)); // 8, 指標的大小為 8 ``` ```c #include <stdio.h> #include <string.h> int main() { char a[] = "hello"; char b[50]; // 需要確保有足夠的空間 strcpy(b, a); // 將 a 複製到 b printf("%s\n", b); // hello strcat(b, a); // 將 a 串接到 b printf("%s\n", b); // hellohello strncpy(b, "abcde", 3); printf("%s\n", b); // abclohello strncat(b, "zzzzz", 3); printf("%s\n", b); // abclohellozzz } ``` ```c #include <stdio.h> #include <string.h> int main() { char s1[] = "aa"; char s2[] = "ab"; printf("%d\n", strcmp(s1, s2)); // "aa" < "ab",回傳 -1 printf("%d\n", strcmp(s1, s1)); // "aa" == "aa",回傳 0 printf("%d\n", strcmp(s2, s1)); // "ab" > "aa",回傳 1 printf("%d\n", strncmp(s1, s2, 1)); // 0 } ``` ```c #include <stdio.h> #include <string.h> #define length 5 int main() { char a[length][12] = {"banana", "apple", "grape", "orange", "mango"}; // Bubble Sort for (int i = length - 1; i > 0; i--) { for (int j = 0; j < i; j++) { if (strcmp(a[j], a[j + 1]) > 0) { char temp[12]; strcpy(temp, a[j]); strcpy(a[j], a[j + 1]); strcpy(a[j + 1], temp); } } } for (int i = 0; i < length; i++) { printf("%s\n", a[i]); // apple, banana, grape, mango, orange } } ``` ```c #include <stdio.h> #include <string.h> int main() { char s[] = "hello world"; char *pos = strchr(s, 'o'); // 回傳第一個 'o' 的指標,找不到回傳 NULL if (pos) { printf("index = %ld\n", pos - s); // index = 4 } pos = strrchr(s, 'o'); // 反方向 if (pos) { printf("index = %ld\n", pos - s); // index = 7 } } ``` ```c #include <stdio.h> #include <string.h> int main() { char s1[] = "hello world"; char s2[] = "world"; char *pos = strstr(s1, s2); // 回傳 "world" 的起始指標 if (pos) { printf("index = %ld\n", pos - s1); // index = 6 } } ``` ```c #include <stdio.h> #include <string.h> // strtok #include <stdlib.h> // atoi int main() { char str[] = "2025/3/11"; char delim[] = "/"; char *token = strtok(str, delim); while (token != NULL) { printf("%d ", atoi(token)); // atoi: string 轉 int token = strtok(NULL, delim); } } ``` ```c #include <stdio.h> #include <string.h> // strcpy() struct Student { char name[20]; float score; }; int main() { struct Student s1; strcpy(s1.name, "Andy"); // 不能用 s1.name = "Andy"; s1.score = 85.5; printf("%s\n", s1.name); printf("%.1f\n", s1.score); } ``` ```c #include <stdio.h> void print_bin(char* s, int n) { printf("%s = ", s); for (int i = 7; i >= 0; i--) { printf("%d", (n >> i) & 1); } printf("\n"); } int main() { int a = 170, b = 204; print_bin("a", a); // 10101010 print_bin("b", b); // 11001100 print_bin("a & b", a & b); // 10001000 print_bin("a | b", a | b); // 11101110 print_bin("a ^ b", a ^ b); // 01100110 print_bin("~a", ~a); // 01010101 print_bin("a << 1", a << 1); // 01010100 print_bin("a >> 1", a >> 1); // 01010101 } ``` ```c #include <stdio.h> #include <stdlib.h> // malloc, free #include <assert.h> // assert // malloc = 「m」emory 「alloc」ation (分配) // assert = 斷言、肯定地說 int main() { int n = 5; int *a = malloc(n * sizeof(int)); assert(a != NULL); // 申請失敗時回傳 NULL for (int i = 0; i < n; i++) a[i] = i * i; for (int i = 0; i < n; i++) printf("%d ", a[i]); free(a); // malloc 申請的記憶體必須手動釋放 } ``` ```c // Linked list (鏈結序列) #include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct node { int data; struct node *next; } Node; Node *genNode(int data, Node *next) { Node *node = malloc(sizeof(Node)); assert(node != NULL); node->data = data; node->next = next; return node; } void printList(Node *node) { for (; node; node = node->next) printf("%d ", node->data); printf("\n"); } void freeList(Node *node) { while (node) { Node *next = node->next; free(node); node = next; } } Node *buildUnsorted(int *a, int n) { Node *head = NULL; // 最新節點永遠放在前端 int i; for (i = 0; i < n; i++) head = genNode(a[i], head); // 讓新節點指到舊 head return head; } Node *insertSorted(Node *head, int data) { if (!head || data < head->data) // 空串列或要插入最前面 return genNode(data, head); Node *prev = head; // 如果下一個節點存在 且 它的資料小於 data -> 往後找 while (prev->next && prev->next->data < data) prev = prev->next; prev->next = genNode(data, prev->next); return head; } Node *deleteValue(Node *head, int target) { if (!head) return NULL; if (head->data == target) { Node *next = head->next; free(head); return next; } Node *prev = head; while (prev->next && prev->next->data != target) prev = prev->next; if (prev->next) { Node *dead = prev->next; prev->next = dead->next; free(dead); } return head; } int main() { int a[] = {4, 6, 2, 9, 7}; int n = sizeof(a)/sizeof(a[0]); Node *head = NULL; for (int i = 0; i < n; i++) head = insertSorted(head, a[i]); printList(head); head = deleteValue(head, 6); // 刪除 6 printList(head); freeList(head); } ``` ```c /* 二元搜尋樹 (Binary Search Tree) 用途:儲存可以「快速搜尋」的資料。 規則:對於任一節點,左子樹都比它小,右子樹都比它大。 時間複雜度:O(log n) */ #include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct treenode { int data; struct treenode *left; struct treenode *right; } TreeNode; TreeNode *genTreeNode(int data) { TreeNode *node = malloc(sizeof(TreeNode)); assert(node != NULL); node->data = data; node->left = node->right = NULL; return node; } TreeNode *insertBsTree(TreeNode *root, int data) { if (!root) return genTreeNode(data); // 空樹就直接建立節點 if (data < root->data) root->left = insertBsTree(root->left, data); else root->right = insertBsTree(root->right, data); return root; } void printBsTree(TreeNode *root) { if (!root) return; printBsTree(root->left); // 先印左子樹 printf("%d ", root->data); // 中間印自己 printBsTree(root->right); // 最後印右子樹 } void freeBsTree(TreeNode *root) { if (!root) return; freeBsTree(root->left); freeBsTree(root->right); free(root); } int searchBsTree(TreeNode *root, int target) { if (!root) return 0; // 找不到 if (root->data == target) return 1; // 找到 if (target < root->data) return searchBsTree(root->left, target); // 去左邊找 else return searchBsTree(root->right, target); // 去右邊找 } int main() { int a[] = {8, 3, 10, 6, 1}; int n = sizeof(a)/sizeof(a[0]), i; TreeNode *root = NULL; for (i = 0; i < n; i++) root = insertBsTree(root, a[i]); printBsTree(root); printf(searchBsTree(root, 6) ? "找到!\n" : "找不到!\n"); freeBsTree(root); } ``` ```c #include <stdio.h> #include <stdbool.h> #include <string.h> #define STACK_SIZE 100 #define MAX_LEN 256 // 模擬 Object 的 Stack 結構與相關方法 typedef struct { int top; char elements[STACK_SIZE]; // 方法函式指標 void (*init)(void *); bool (*isFull)(void *); bool (*isEmpty)(void *); void (*push)(void *, char); int (*pop)(void *); } Stack; // 以下是模擬「物件方法」的實作 void initStack(void *self) { ((Stack *)self)->top = 0; } bool stackIsFull(void *self) { return ((Stack *)self)->top >= STACK_SIZE; } bool stackIsEmpty(void *self) { return ((Stack *)self)->top == 0; } void stackPush(void *self, char c) { Stack *s = (Stack *)self; if (s->isFull(s)) { printf("Error: stack is full\n"); return; } s->elements[s->top++] = c; } int stackPop(void *self) { Stack *s = (Stack *)self; if (s->isEmpty(s)) { printf("Error: stack is empty\n"); return -1; } return s->elements[--s->top]; } // 初始化一個堆疊「物件」,附上方法 void createStack(Stack *s) { s->init = initStack; s->isFull = stackIsFull; s->isEmpty = stackIsEmpty; s->push = stackPush; s->pop = stackPop; s->init(s); // 初始化狀態 } int main() { char input[MAX_LEN]; Stack stk; bool balanced = true; printf("請輸入一行括號表達式:"); // ([]{}) scanf("%s", input); createStack(&stk); for (int i = 0; input[i] && balanced; i++) { char ch = input[i]; switch (ch) { case '(': case '[': case '{': stk.push(&stk, ch); break; case ')': balanced = (stk.pop(&stk) == '('); break; case ']': balanced = (stk.pop(&stk) == '['); break; case '}': balanced = (stk.pop(&stk) == '{'); break; default: break; // 忽略其他字元 } } if (balanced && stk.isEmpty(&stk)) { printf("✅ 括號平衡\n"); } else { printf("❌ 括號不平衡\n"); } } ```