學期2024-2025-1 學號20241317 《計算機基礎與程序設計》第十三周學習總結
學期2024-2025-1 學號20241317 《計算機基礎與程序設計》第十三周學習總結
作業信息
| 這個作業屬于哪個課程 | <班級的鏈接>(如2024-2025-1-計算機基礎與程序設計) |
|---|---|
| 這個作業要求在哪里 | <作業要求的鏈接>(如2024-2025-1計算機基礎與程序設計第一周作業) |
| 這個作業的目標 | <寫上具體方面> |
| 作業正文 | http://www.rzrgm.cn/manurios/p/18622472 |
教材學習內容總結
在《C語言程序設計》教材中,第十二章通常會介紹結構體以及基于結構體構建的簡單數據結構。以下是這一章節可能包含的內容總結:
結構體(Structures)
- 結構體定義:介紹如何使用
struct關鍵字定義結構體類型,包括如何聲明結構體變量。 - 結構體初始化:講解如何初始化結構體變量,包括直接初始化和使用
memset()函數進行初始化。 - 結構體訪問:使用
.運算符訪問結構體成員,以及如何通過指針訪問結構體成員(使用->運算符)。 - 結構體數組:創建和操作結構體數組,包括如何遍歷和處理結構體數組。
- 結構體與函數:如何將結構體作為參數傳遞給函數,以及如何從函數返回結構體。
- 結構體嵌套:介紹結構體中可以嵌套其他結構體,以及如何訪問嵌套結構體的成員。
枚舉類型(Enumerations)
- 枚舉定義:使用
enum關鍵字定義枚舉類型,以及如何聲明枚舉變量。 - 枚舉使用:講解如何使用枚舉類型來表示一組相關的常量,提高代碼的可讀性和可維護性。
聯合體(Unions)
- 聯合體定義:介紹如何使用
union關鍵字定義聯合體類型,以及如何聲明聯合體變量。 - 聯合體使用:講解聯合體的特性,即所有成員共享同一塊內存空間,以及如何根據需要訪問不同的成員。
數據結構基礎
- 鏈表(Linked List):
- 單鏈表:介紹單鏈表的基本概念,包括節點的定義和鏈表的創建。
- 鏈表操作:講解如何實現鏈表的插入、刪除、查找等基本操作。
- 棧(Stack):
- 棧的定義:介紹棧的后進先出(LIFO)特性。
- 棧的實現:使用數組或鏈表實現棧,并實現棧的基本操作,如
push、pop、peek等。
- 隊列(Queue):
- 隊列的定義:介紹隊列的先進先出(FIFO)特性。
- 隊列的實現:使用數組或鏈表實現隊列,并實現隊列的基本操作,如
enqueue、dequeue、front等。
- 樹(Tree):
- 樹的定義:介紹樹的基本概念,包括節點、邊、根節點、葉子節點等。
- 二叉樹:講解二叉樹的定義,以及如何使用結構體表示二叉樹的節點。
- 二叉樹遍歷:介紹二叉樹的三種基本遍歷方法:前序遍歷、中序遍歷和后序遍歷。
應用實例
- 結構體在實際問題中的應用:通過一些實際問題,展示如何使用結構體來組織和管理數據。
- 數據結構的應用:通過實例講解如何使用鏈表、棧、隊列等數據結構解決實際問題,如棧在表達式求值中的應用、隊列在任務調度中的應用等。
這一章節的內容旨在幫助讀者掌握結構體的使用方法,并通過結構體構建簡單的數據結構,為后續更復雜的數據結構和算法學習打下基礎。
教材學習中的問題和解決過程(先問 AI)
(一個模板:我看了這一段文字 (引用文字),有這個問題 (提出問題)。 我查了資料,有這些說法(引用說法),根據我的實踐,我得到這些經驗(描述自己的經驗)。 但是我還是不太懂,我的困惑是(說明困惑)。【或者】我反對作者的觀點(提出作者的觀點,自己的觀點,以及理由)。 )
- 問題1:結構體定義注意事項有什么?
- 問題1解決方案:在C語言中定義結構體時,需要注意以下幾點:
1. 結構體名稱
- 命名規范:結構體類型名稱應遵循良好的命名規范,通常使用大寫字母開頭或全大寫字母,并使用下劃線分隔單詞,例如
Student或STUDENT_INFO。 - 避免與關鍵字沖突:確保結構體名稱不與C語言的關鍵字或已定義的標識符沖突。
- 描述性名稱:選擇能夠清晰描述結構體內容和用途的名稱,使代碼更易讀和理解。
2. 成員變量
- 類型選擇:根據實際需求為成員變量選擇合適的數據類型,例如使用
int表示整數、float或double表示浮點數、char數組表示字符串等。 - 成員命名:為成員變量選擇有意義的名稱,通常使用小寫字母開頭,并使用下劃線分隔單詞,例如
name、age、score等。 - 避免重復成員:確保結構體中沒有重復的成員變量,每個成員變量應具有獨特的功能和用途。
- 對齊和填充:了解結構體成員的對齊和填充規則,不同編譯器和平臺可能有不同的對齊要求,這可能會影響結構體的內存占用和性能。
3. 結構體初始化
- 初始化方式:在定義結構體變量時,可以使用初始化列表對成員變量進行初始化,例如:
struct Student stu = {"John", 20, 85.5}; - 默認初始化:如果未顯式初始化,結構體的成員變量可能會被初始化為零或隨機值,具體取決于編譯器和平臺。
4. 結構體嵌套
- 嵌套結構體:結構體中可以嵌套其他結構體,但要注意嵌套的層次不宜過深,以保持代碼的清晰和可維護性。
- 嵌套訪問:訪問嵌套結構體的成員時,需要使用多個
.運算符,例如:struct Address address = {"China", "Beijing"}; struct Student stu = {"John", 20, address}; printf("%s\n", stu.address.city);
5. 結構體與指針
- 結構體指針:可以使用指針訪問結構體變量,使用
->運算符訪問成員變量,例如:struct Student *p = &stu; printf("%s\n", p->name); - 動態分配結構體:可以使用
malloc()等函數動態分配結構體內存,但要注意內存的釋放和指針的管理。
6. 結構體與函數
- 函數參數:將結構體作為函數參數傳遞時,可以傳遞結構體變量或結構體指針,根據需要選擇傳值或傳址。
- 返回結構體:函數可以返回結構體變量,但要注意大結構體的返回可能會導致性能開銷。
7. 結構體與內存管理
- 內存占用:了解結構體的內存占用情況,包括成員變量的大小和對齊填充的影響。
- 內存釋放:如果結構體中包含指向動態分配內存的指針,需要在適當的時候釋放這些內存,避免內存泄漏。
通過注意這些事項,可以更好地定義和使用結構體,提高程序的可讀性、可維護性和性能。
- 問題2:如何實現鏈表的位置轉換?
- 問題2解決方案:在鏈表中實現位置交換,通常是指交換兩個節點在鏈表中的位置。以下是實現鏈表位置交換的一般步驟和注意事項:
單鏈表節點交換
假設我們有一個單鏈表,每個節點包含數據和指向下一個節點的指針。我們需要交換兩個節點node1和node2的位置。以下是實現步驟:
1. 定義鏈表節點結構體
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
2. 查找節點及其前驅節點
- 首先,需要找到
node1和node2以及它們的前驅節點prev1和prev2。 - 如果
node1或node2是頭節點,那么它們的前驅節點可以是NULL。
3. 交換節點
- 根據
node1和node2的位置關系,以及它們是否相鄰,分別處理不同的情況:- 如果
node1和node2相鄰,交換它們的next指針。 - 如果
node1和node2不相鄰,需要調整它們的前驅節點的next指針,以及node1和node2的next指針。
- 如果
4. 處理特殊情況
- 如果
node1或node2是尾節點,需要特別注意尾節點的處理。 - 如果鏈表只有一個節點或兩個節點相同,不需要進行交換。
示例代碼
以下是一個簡單的示例代碼,展示如何交換兩個節點的位置:
void swapNodes(ListNode **head, ListNode *node1, ListNode *node2) {
if (node1 == node2) {
return; // 相同節點,無需交換
}
ListNode *prev1 = NULL, *prev2 = NULL;
ListNode *current = *head;
// 查找node1的前驅節點
while (current && current->next != node1) {
prev1 = current;
current = current->next;
}
// 查找node2的前驅節點
current = *head;
while (current && current->next != node2) {
prev2 = current;
current = current->next;
}
// 如果沒有找到node1或node2,無法交換
if (!node1 || !node2) {
return;
}
// 處理node1和node2的前驅節點
if (prev1) {
prev1->next = node2;
} else {
*head = node2; // node1是頭節點
}
if (prev2) {
prev2->next = node1;
} else {
*head = node1; // node2是頭節點
}
// 交換node1和node2的next指針
ListNode *temp = node1->next;
node1->next = node2->next;
node2->next = temp;
}
注意事項
- 邊界條件:確保處理好頭節點和尾節點的特殊情況。
- 相鄰節點:如果兩個節點相鄰,交換時要注意不要丟失鏈表的連接。
- 內存管理:在交換過程中,不要丟失對節點的引用,確保鏈表的完整性和連續性。
- 效率考慮:在實際應用中,頻繁的節點交換可能會導致鏈表操作的效率降低,需要根據具體需求進行優化。
通過上述步驟和示例代碼,可以在單鏈表中實現節點的位置交換。對于雙向鏈表,交換過程類似,但需要同時調整前驅和后繼指針。
- ...
基于AI的學習
問題1:舉例機構體和聯合體的區別:
結構體(struct)和聯合體(union)都是C語言中用于組合多個不同類型的數據項的復合類型,但它們在內存分配和使用方式上有顯著的區別。以下是結構體和聯合體的區別舉例:
結構體(struct)
- 內存分配:結構體為每個成員變量分配獨立的內存空間。結構體的總大小等于其所有成員變量大小的總和(考慮內存對齊)。
- 成員訪問:可以同時訪問結構體的所有成員變量,每個成員變量都有自己的內存地址。
- 使用場景:適用于需要存儲多個相關數據項的場景,例如表示一個學生的信息(姓名、年齡、成績等)。
結構體示例
#include <stdio.h>
// 定義一個學生結構體
typedef struct {
char name[50];
int age;
float score;
} Student;
int main() {
// 創建并初始化一個學生結構體變量
Student stu = {"John Doe", 20, 85.5};
// 訪問和打印結構體成員
printf("Name: %s\n", stu.name);
printf("Age: %d\n", stu.age);
printf("Score: %.2f\n", stu.score);
return 0;
}
聯合體(union)
- 內存分配:聯合體為所有成員變量分配同一塊內存空間。聯合體的大小等于其最大成員變量的大小。
- 成員訪問:同一時間只能使用聯合體的一個成員變量,因為所有成員共享同一塊內存。
- 使用場景:適用于需要根據不同的情況存儲不同類型的數據的場景,例如表示一個可以存儲整數或浮點數的變量。
聯合體示例
#include <stdio.h>
// 定義一個可以存儲整數或浮點數的聯合體
typedef union {
int intValue;
float floatValue;
} Number;
int main() {
// 創建一個聯合體變量
Number num;
// 存儲整數
num.intValue = 100;
printf("Integer Value: %d\n", num.intValue);
// 存儲浮點數
num.floatValue = 3.14;
printf("Float Value: %.2f\n", num.floatValue);
return 0;
}
總結
- 內存使用:結構體使用更多的內存,因為每個成員都有獨立的內存空間;聯合體使用較少的內存,因為所有成員共享同一塊內存。
- 數據訪問:結構體可以同時訪問所有成員;聯合體同一時間只能訪問一個成員。
- 適用場景:結構體適用于存儲多個相關數據項;聯合體適用于根據需要存儲不同類型的數據。
通過這些區別和示例,可以更好地理解結構體和聯合體在C語言中的不同用途和使用方式。
問題2:如何查找鏈表?
在鏈表中查找特定的節點通常涉及遍歷鏈表,直到找到符合條件的節點。查找操作是鏈表操作中的基本操作之一,以下是一些常見的查找方法和示例:
單鏈表查找
假設我們有一個單鏈表,每個節點包含數據和指向下一個節點的指針。我們需要查找包含特定值的節點。
定義鏈表節點結構體
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
查找特定值的節點
ListNode* findNode(ListNode *head, int value) {
ListNode *current = head; // 從頭節點開始遍歷
while (current != NULL) {
if (current->data == value) {
return current; // 找到節點,返回節點指針
}
current = current->next; // 移動到下一個節點
}
return NULL; // 遍歷結束,未找到節點
}
雙向鏈表查找
雙向鏈表的查找與單鏈表類似,但由于每個節點都有前驅和后繼指針,可以雙向遍歷。但通常情況下,查找操作仍然從頭節點開始向后遍歷。
定義雙向鏈表節點結構體
typedef struct DoublyListNode {
int data;
struct DoublyListNode *prev;
struct DoublyListNode *next;
} DoublyListNode;
查找特定值的節點
DoublyListNode* findNode(DoublyListNode *head, int value) {
DoublyListNode *current = head;
while (current != NULL) {
if (current->data == value) {
return current;
}
current = current->next;
}
return NULL;
}
循環鏈表查找
循環鏈表的查找也需要遍歷鏈表,但由于鏈表是循環的,需要注意避免無限循環。
定義循環鏈表節點結構體
typedef struct CircularListNode {
int data;
struct CircularListNode *next;
} CircularListNode;
查找特定值的節點
CircularListNode* findNode(CircularListNode *head, int value) {
if (head == NULL) {
return NULL;
}
CircularListNode *current = head;
do {
if (current->data == value) {
return current;
}
current = current->next;
} while (current != head); // 循環直到回到頭節點
return NULL;
}
查找節點的前驅節點
在某些情況下,可能需要找到某個節點的前驅節點,例如在刪除節點時。
查找特定值節點的前驅節點
ListNode* findPreviousNode(ListNode *head, int value) {
if (head == NULL || head->next == NULL) {
return NULL;
}
ListNode *current = head;
while (current->next != NULL) {
if (current->next->data == value) {
return current; // 返回前驅節點
}
current = current->next;
}
return NULL; // 未找到
}
注意事項
- 邊界條件:在查找過程中,要特別注意鏈表為空或只有一個節點的情況。
- 效率:查找操作的時間復雜度為O(n),其中n是鏈表的長度。對于大型數據集,查找效率可能較低,可以考慮使用其他數據結構(如哈希表)來提高查找效率。
- 循環鏈表:在循環鏈表中查找時,要確保不會無限循環,通常通過檢查當前節點是否回到頭節點來結束循環。
通過這些方法和示例,可以在不同類型的鏈表中實現查找操作。
三個原則:
- 切勿原封不動地接受生成式人工智能工具的輸出;確保對其進行評估、完善和修改(或提示),以適應您的目標。
- 切勿將任何個人數據(自己、同學、老師等)或版權材料納入到你的提示詞中。這個可以說是保護個人隱私的最起碼的舉措。
- 所有人工智能生成工具都容易產生幻覺,因此會生成不準確或誤導性的信息,要學會甄別信息真假
選擇至少2個知識點利用chatgpt等工具進行蘇格拉底挑戰,并提交過程截圖,提示過程參考下面內容
“我在學***X知識點,請你以蘇格拉底的方式對我進行提問,一次一個問題”
核心是要求GPT:“請你以蘇格拉底的方式對我進行提問”
然后GPT就會給你提問,如果不知道問題的答案,可以反問AI:“你的理解(回答)是什么?”
如果你覺得差不多了,可以先問問GPT:“針對我XXX知識點,我理解了嗎?”
GPT會給出它的判斷,如果你也覺得自己想清楚了,可以最后問GPT:“我的回答結束了,請對我的回答進行評價總結”,讓它幫你總結一下。
代碼調試中的問題和解決過程
- 問題1:XXXXXX
- 問題1解決方案:XXXXXX
- 問題2:XXXXXX
- 問題2解決方案:XXXXXX
- ...
代碼托管
(statistics.sh腳本的運行結果截圖)
上周考試錯題總結
- 錯題1及原因,理解情況
- 錯題2及原因,理解情況
- ...
其他(感悟、思考等,可選)
xxx
xxx
學習進度條
| 代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
|---|---|---|---|---|
| 目標 | 5000行 | 30篇 | 400小時 | |
| 第一周 | 200/200 | 2/2 | 20/20 | |
| 第二周 | 300/500 | 2/4 | 18/38 | |
| 第三周 | 500/1000 | 3/7 | 22/60 | |
| 第四周 | 300/1300 | 2/9 | 30/90 |
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進自己的計劃能力。這個工作學習中很重要,也很有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。
-
計劃學習時間:XX小時
-
實際學習時間:XX小時
-
改進情況:
(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表)
參考資料
- 《計算機科學概論(第七版)》
- ...

浙公網安備 33010602011771號