# 【課堂筆記】師大-程式設計(二)
```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");
}
}
```