2024-2025-1 20241413 《計算機基礎與程式設計》第十一週學習總結

yokinn發表於2024-12-08
班級 https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP
作業要求 https://www.cnblogs.c
作業目標 計算機網路 網路拓撲 雲端計算 網路安全 Web HTML,CSS,Javascript XML
---- ----

教材學習內容總結
《電腦科學概論》第15、16章
第15章:作業系統
作業系統概念:介紹了作業系統(OS)的基本功能,包括程序管理、檔案管理、記憶體管理、輸入/輸出(I/O)管理和使用者介面。

程序管理:討論了程序的概念、程序排程、程序同步、死鎖和程序通訊。

記憶體管理:涵蓋了記憶體分配策略、虛擬記憶體、分頁和分段技術。

檔案管理:介紹了檔案系統的設計、檔案訪問方法、檔案儲存和檔案保護。

輸入/輸出(I/O)管理:探討了I/O裝置管理、緩衝、裝置驅動程式和I/O處理。

現代作業系統:討論了現代作業系統的特點,如多工、多使用者、分散式和網路作業系統。

作業系統設計和實現:概述了作業系統的設計原則和實現技術。

第16章:資料管理(資料庫系統)
資料庫系統概念:介紹了資料庫系統的定義、資料庫模型(如關係模型、物件模型)和資料庫管理系統(DBMS)的功能。

關聯式資料庫:深入探討了關聯式資料庫的基本概念,包括關係模型、關係代數、SQL語言和關係完整性。

資料庫設計:討論了資料庫設計的過程,包括需求分析、概念性設計、邏輯設計和物理設計。

資料庫應用開發:介紹瞭如何使用資料庫系統來開發應用程式,包括資料庫連線、事務處理和資料庫程式設計介面。

資料庫的高階主題:可能包括資料庫的安全性、完整性、併發控制和恢復機制。

大資料和資料倉儲:討論了大資料的概念、資料倉儲的架構和資料探勘技術。

資料庫的未來趨勢:概述了資料庫技術的未來發展方向,如雲資料庫、NoSQL資料庫和新型資料庫系統。

《C語言程式設計》第10章
第10章:字串
字串基礎:

字串定義:在C語言中,字串被定義為字元陣列,以空字元('\0')作為結束標誌。
字元陣列:字串可以儲存在字元陣列中,陣列的每個元素對應一個字元。
字串字面量:

字串字面量是雙引號括起來的字元序列,自動在末尾新增空字元。
例如:"Hello, World!" 是一個字串字面量。
字串處理函式:

C標準庫提供了多種處理字串的函式,如strcpy(), strncpy(), strcat(), strncat(), strcmp(), strncmp(), strlen(), strchr(), strrchr()等。
這些函式用於複製、連線、比較、查詢字串中的特定字元或子串、獲取字串長度等。
字串陣列和指標:

字串可以透過指標來處理,指標指向字串的第一個字元。
字串陣列是儲存多個字串的陣列,每個字串都是字元陣列。
字串和記憶體:

動態記憶體分配:使用malloc()或calloc()分配記憶體來建立可變長度的字串。
記憶體釋放:使用free()釋放動態分配的記憶體。
字串輸入和輸出:

使用scanf()和printf()函式進行字串的輸入和輸出。
注意scanf()在讀取字串時可能會遇到問題,因為它會在遇到空格時停止讀取。
字串操作的注意事項:

緩衝區溢位:確保在複製或連線字串時不會超出分配的記憶體空間。
空字元:始終在字串的末尾保留空字元,以標識字串的結束。
字串的高階操作:

字串分割:使用strtok()函式分割字串。
字串反轉:編寫函式來反轉字串。
字串和字元處理技巧:

利用ASCII值進行字元比較和轉換。
使用迴圈和條件語句處理字串中的每個字元。
案例研究:

透過實際程式設計示例來展示字串處理的應用,如字串反轉、模式匹配等。

教材學習中的問題與解決過程
1.什麼時候會用到動態記憶體分配?
AI:動態記憶體分配在C語言中是一種重要的技術,它允許程式在執行時根據需要分配和釋放記憶體。以下是一些常見的使用動態記憶體分配的場景:

未知大小的資料結構:

當你需要建立的資料結構的大小在編譯時未知,或者取決於使用者輸入時,動態記憶體分配非常有用。例如,你可能需要根據使用者輸入建立一個大小可變的陣列。
大型資料集:

對於處理大型資料集,如大型矩陣、影像處理或科學計算,可能需要的記憶體量很大,而且這些資料通常不會全部同時使用,動態記憶體分配可以更有效地管理這些資源。
物件池:

在需要頻繁建立和銷燬物件的場景下,使用動態記憶體分配可以避免頻繁的記憶體分配和釋放帶來的效能損耗,透過物件池來重用已分配的記憶體。
快取實現:

快取經常需要根據實際使用情況動態調整大小,動態記憶體分配允許快取在需要時增長,在不需要時縮小。
資料庫和檔案系統:

資料庫和檔案系統需要動態地儲存和檢索資料,這些資料的大小和數量往往是動態變化的。
網路程式設計:

在網路程式設計中,接收的資料包大小是未知的,因此需要動態分配記憶體來儲存這些資料。
圖形和遊戲開發:

在圖形和遊戲開發中,物件的數量和複雜性可能會根據遊戲的程序而變化,動態記憶體分配允許靈活地管理這些資源。
多執行緒和併發程式設計:

在多執行緒環境中,每個執行緒可能需要自己的資料副本,動態記憶體分配可以為每個執行緒分配獨立的記憶體空間。
避免棧溢位:

棧空間有限,對於大型資料結構,使用堆上的動態記憶體分配可以避免棧溢位的問題。
資源管理:

在嵌入式系統或資源受限的環境中,動態記憶體分配可以幫助更精細地控制記憶體使用,最佳化資源利用。
靈活性和可擴充套件性:

動態記憶體分配提供了編寫靈活和可擴充套件程式碼的能力,因為你可以根據程式執行時的需要來分配記憶體。
動態記憶體分配提供了極大的靈活性,但同時也帶來了記憶體洩漏、野指標和記憶體碎片等潛在問題,因此在使用時需要謹慎管理記憶體。

2.gets和puts輸入輸出字串時AI總會提醒會出現問題,他們是否是標準的用法?
在C語言中,gets 和 puts 確實是標準庫函式,它們分別用於字串的輸入和輸出。以下是它們的標準用法和一些相關的注意事項:

gets 函式:

gets 函式用於從標準輸入(通常是鍵盤)讀取一行字串,並將其儲存在指定的字元陣列中。它的原型是 char *gets(char *str),其中 str 是儲存讀入資料的緩衝區指標。
需要注意的是,gets 函式存在安全風險,因為它不檢查目標緩衝區的大小,可能會導致緩衝區溢位。因此,在實際程式設計中,推薦使用 fgets 函式替代 gets,因為 fgets 允許指定最大讀取字元數,從而避免緩衝區溢位問題。
puts 函式:

puts 函式用於向標準輸出裝置(通常是螢幕)輸出一個字串,並在字串末尾自動新增一個換行符。它的原型是 int puts(const char *str),其中 str 是要輸出的字串。
puts 函式在輸出字串時會自動新增換行符,因此不需要像 printf 那樣手動新增 \n。
儘管 gets 和 puts 是C語言中的標準函式,但由於 gets 函式的安全問題,它已經在C11標準中被移除。因此,即使 gets 和 puts 是標準用法,出於安全考慮,gets 函式不推薦使用,而 puts 函式雖然仍然可用,但在輸出時需要注意其自動新增換行符的特性。

3.為什麼字串複製不能直接兩個字串相等,還需要用strcpy函式?
在C語言中,字串是字元陣列的序列,以空字元('\0')作為結束標誌。當你直接使用等號賦值運算子(=)來“複製”兩個字串時,實際上是進行的是指標賦值,而不是內容複製。這意味著兩個指標指向的是同一塊記憶體區域,它們共享相同的字元陣列。這會導致幾個問題:

記憶體洩漏:如果原始字串是透過動態記憶體分配(如 malloc 或 calloc)建立的,那麼直接賦值會導致無法釋放原始記憶體,因為兩個指標指向的是同一塊記憶體。

修改問題:如果透過一個字串指標修改了字串內容(例如,使用 strcat 或直接透過索引賦值),那麼另一個字串也會顯示相同的修改,因為它們指向的是同一塊記憶體。

釋放問題:如果使用其中一個指標釋放了記憶體,那麼另一個指標就會變成“野指標”,指向一個已經被釋放的記憶體區域,這是非常危險的。

因此,為了確保每個字串都有自己的獨立記憶體區域,需要使用 strcpy 或其他類似的字串複製函式來建立字串內容的副本。strcpy 函式會將源字串(包括空字元)複製到目標字串,確保兩個字串是完全獨立的。

下面是一個使用 strcpy 的示例:

c

include <stdio.h>

include <string.h>

int main() {
char src[] = "Hello, World!";
char dest[20]; // 確保有足夠的空間來儲存複製的字串

strcpy(dest, src); // 複製src到dest

printf("Source: %s\n", src);
printf("Destination: %s\n", dest);

return 0;

}
在這個示例中,dest 是一個足夠大的字元陣列,可以儲存 src 的內容。使用 strcpy 函式後,dest 包含了 src 的一個副本,對 dest 的任何修改都不會影響到 src。

需要注意的是,使用 strcpy 時要確保目標字串有足夠的空間來儲存源字串,包括終止的空字元。如果目標空間不足,可能會導致緩衝區溢位,這是一個常見的安全問題。因此,在實際程式設計中,推薦使用 strncpy 函式,它允許指定最大複製的字元數,從而避免溢位。

基於AI的學習
Hi,我是 Kimi~
很高興遇見你!你可以隨時把網址🔗或者檔案📃發給我,我來幫你看看

我學習了《C語言程式設計》第10章字串的內容,請你以蘇格拉底的方式,一次向我提問一個問題

當然可以,讓我們開始蘇格拉底式的對話。

問題1: 你能告訴我什麼是字串嗎?

一串字元

問題2: 那麼,這些字元是如何在計算機中儲存的呢?

以字元型別的陣列方式儲存

問題3: 既然字串是字元型別的陣列,那麼它們是如何表示字串的結束呢?

結尾為\0表示字串的結束

問題4: 這個特殊的字元,我們稱之為空字元(null character),它在字串中扮演著怎樣的角色?

代表一個字串的結束

問題5: 空字元(\0)在字串中的作用是否僅限於表示結束?它是否還有其他的作用或含義?

我認為只代表字串的結束

問題6: 非常好,那麼在C語言中,當我們使用函式處理字串時,這些函式是如何知道一個字串何時結束的?它們是依賴於陣列的長度嗎?還是依賴於空字元?

這個問題可以幫助我們更深入地理解C語言中字串處理的機制。

依賴於空字元

問題7: 既然C語言中的字串處理函式依賴於空字元(\0)來識別字串的結束,那麼如果一個字串陣列中包含了空字元,這些函式會如何反應?它們會認為這是字串的結束嗎?

這個問題可以幫助我們理解字串處理函式是如何區分字串中的空字元和用來標識字串結束的空字元。

會認為這是字串的結束

問題8: 如果字串處理函式會將遇到的空字元視為字串的結束,那麼在實際程式設計中,我們如何避免這種情況?或者說,我們如何確保函式正確地處理包含空字元的字串?

這個問題引導我們思考如何在程式設計實踐中處理包含特殊字元的字串,這對於編寫健壯的程式碼非常重要。

程式設計中給一個字串賦值不是不用加\0嗎?定義結束不是會自動加上\0嗎

問題9: 你提到了在程式設計中給字串賦值時不需要手動新增空字元(\0),這是在什麼情況下成立的?所有的字串賦值操作都不需要手動新增空字元嗎?

這個問題旨在澄清字串賦值和空字元新增的具體條件,以便更好地理解字串的儲存和處理。

你的回答呢

抱歉,讓我們繼續。

回答: 在C語言中,當你使用字串字面量(例如 "hello")來初始化一個字元陣列時,編譯器會自動在字串的末尾新增一個空字元(\0)來表示字串的結束。例如:

c
char str[] = "hello";
在這個例子中,str 實際上被儲存為 h e l l o \0。編譯器幫你處理了新增空字元的部分。

然而,如果你透過其他方式給字串賦值,比如使用 scanf 或者字串連線函式,你可能需要手動確保字串以空字元結束。例如:

c
char str[6];
scanf("%5s", str); // 使用者輸入 "hello",但不會包含空字元
str[5] = '\0'; // 需要手動新增空字元
在這種情況下,因為 scanf 只會讀取到空格之前的字元,所以你需要手動在陣列的最後一個位置新增空字元。

這樣的處理確保了字串的正確性和字串處理函式的正常工作,因為這些函式通常依賴於空字元來判斷字串何時結束。

相關文章