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

manurios發表於2024-12-08

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

作業資訊

這個作業屬於哪個課程 <班級的連結>(如2024-2025-1-計算機基礎與程式設計
這個作業要求在哪裡 <作業要求的連結>(如2024-2025-1計算機基礎與程式設計第一週作業)
這個作業的目標 <寫上具體方面>
作業正文 https://www.cnblogs.com/manurios/p/18593468

教材學習內容總結

C語言程式設計第十章通常涉及的是C語言中的高階主題。不過,由於不同的教材和課程可能會有不同的章節安排,以下是一個較為通用的第十章知識點總結,可能包括但不限於以下內容:

  1. 前處理器指令

    • #include:用於包含標準庫或使用者自定義的標頭檔案。
    • #define:用於定義宏。
    • #ifdef#ifndef#endif:用於條件編譯。
  2. 位運算

    • 位與(&)、位或(|)、位非(~)、位異或(^)。
    • 位左移(<<)和位右移(>>)。
  3. 檔案操作

    • fopenfclosefreadfwritefprintffscanffgetsfputcfgetc 等函式的使用。
    • 檔案指標和檔案緩衝區的概念。
  4. 結構體

    • 結構體的定義和使用。
    • 結構體陣列。
    • 結構體與函式。
  5. 聯合(Union)

    • 聯合的定義和使用。
    • 聯合與結構體的區別。
  6. 列舉(Enum)

    • 列舉型別的定義和使用。
  7. 動態記憶體分配

    • malloccallocreallocfree 函式的使用。
  8. 指標的高階應用

    • 指標和陣列的關係。
    • 指標和函式的關係。
    • 指標的指標。
  9. 遞迴

    • 遞迴函式的定義和使用。
    • 遞迴的注意事項和常見問題。
  10. 訊號處理

    • signal 函式的使用。
    • 訊號集和訊號掩碼。
  11. 多執行緒程式設計(如果教材包含):

    • pthread 庫的使用。
    • 執行緒的建立、同步和銷燬。
  12. 網路程式設計(如果教材包含):

    • 套接字(Socket)的概念。
    • 網路通訊的基本流程。

請注意,具體內容可能會根據你所使用的教材或課程有所不同。如果你有具體的教材或課程大綱,可以提供更詳細的資訊,以便給出更準確的知識點總結。

透過 AI 工具總結一下內容,自己再補充
透過思維導圖形成知識體系
看懂就過,看不懂,學習有心得的記一下

教材學習中的問題和解決過程(先問 AI)

(一個模板:我看了這一段文字 (引用文字),有這個問題 (提出問題)。 我查了資料,有這些說法(引用說法),根據我的實踐,我得到這些經驗(描述自己的經驗)。 但是我還是不太懂,我的困惑是(說明困惑)。【或者】我反對作者的觀點(提出作者的觀點,自己的觀點,以及理由)。 )

  • 問題1:聯合與結構體的區別是什麼?
  • 問題1解決方案:在C語言中,聯合(Union)和結構體(Structure)都是使用者定義的複合資料型別,但它們之間存在一些關鍵的區別:
  1. 儲存方式

    • 結構體:結構體中的所有成員都佔用自己的記憶體空間,它們是同時儲存的。這意味著結構體的大小是其所有成員大小的總和(考慮到記憶體對齊)。
    • 聯合:聯合中的所有成員共享同一塊記憶體空間。在任意時刻,聯合只能儲存其中一個成員的值。聯合的大小等於其最大成員的大小(也要考慮記憶體對齊)。
  2. 記憶體佔用

    • 結構體:由於所有成員都同時儲存,結構體通常佔用更多的記憶體。
    • 聯合:由於成員共享記憶體,聯合通常佔用較少的記憶體。
  3. 使用目的

    • 結構體:用於儲存不同的、相關的資料項,這些資料項不一定在所有時間都同時使用。
    • 聯合:用於儲存多個資料項,但這些資料項在同一時間只能使用其中一個。聯合常用於需要節省空間或處理多種資料型別的場景。
  4. 訪問成員

    • 結構體:可以透過點運算子(.)或箭頭運算子(->)安全地訪問所有成員,不會覆蓋其他成員。
    • 聯合:雖然也可以透過點運算子(.)或箭頭運算子(->)訪問成員,但訪問一個成員可能會覆蓋另一個成員的值,因此需要小心使用。
  5. 初始化

    • 結構體:可以初始化所有成員,也可以只初始化部分成員(使用指定初始化器)。
    • 聯合:只能初始化一個成員,因為所有成員共享記憶體。
  6. 清零

    • 結構體:使用memset清零結構體會清零所有成員。
    • 聯合:使用memset清零聯合只會清零共享的記憶體區域。
  7. 賦值

    • 結構體:不能直接將一個結構體賦值給另一個結構體,除非使用memcpy或結構體賦值運算子(C11標準引入)。
    • 聯合:可以直接將一個聯合賦值給另一個聯合,因為它們共享記憶體。
  8. 傳遞和返回

    • 結構體:作為函式引數時,通常是透過值傳遞或引用傳遞。
    • 聯合:作為函式引數時,也可以透過值傳遞或引用傳遞,但由於共享記憶體的特性,有時可以直接傳遞聯合的地址。

根據具體的應用場景和需求,開發者可以選擇使用結構體或聯合來儲存和管理資料。

  • 問題2:為什麼將一個聯合賦值給另一個聯合,它們共享記憶體
  • 問題2解決方案:在C語言中,將一個聯合賦值給另一個聯合,它們共享記憶體的原因是因為聯合(union)是一種特殊的資料結構,其內部的所有成員都共享同一塊記憶體空間。這意味著無論聯合中定義了多少個成員,它們實際上都是同一個儲存位置的別名。

以下是幾個關鍵點來解釋為什麼聯合賦值會導致它們共享記憶體:

  1. 記憶體共享機制

    • 聯合的定義使得它的所有成員都從同一塊記憶體地址開始儲存。因此,當一個聯合被賦值給另一個聯合時,它們實際上都指向了同一塊記憶體區域。
  2. 地址相同

    • 當你將一個聯合變數賦值給另一個時,你只是複製了這塊記憶體的地址,而不是記憶體中的內容。這意味著兩個聯合變數現在指向了同一塊記憶體,任何對這塊記憶體的修改都會反映在兩個聯合變數上。
  3. 節省空間

    • 聯合的設計初衷之一是為了節省空間。透過共享記憶體,聯合可以只佔用最大成員所需的空間,而不是所有成員大小的總和。
  4. 資料覆蓋

    • 由於聯合的成員共享記憶體,對一個成員的賦值會覆蓋其他成員的值。因此,當你將一個聯合賦值給另一個聯合時,你實際上是在複製了這塊記憶體的當前狀態,而不是它們的獨立副本。
  5. 不可預測的行為

    • 如果同時透過兩個聯合變數訪問和修改記憶體,可能會導致不可預測的行為,因為它們實際上訪問的是同一塊記憶體區域。
  6. 賦值語義

    • 在C語言中,當一個聯合被賦值給另一個聯合時,這種賦值操作是透過記憶體複製實現的,而不是值複製。這意味著兩個聯合變數將共享同一塊記憶體空間。

因此,當你將一個聯合賦值給另一個聯合時,它們共享記憶體是因為聯合的資料結構定義了這樣的記憶體共享機制,這也是聯合與結構體的一個主要區別。結構體的成員各自擁有獨立的記憶體空間,而聯合的成員則共享相同的記憶體空間。

  • ...

基於AI的學習

問題1:細講指標
回答:指標是C語言中一個非常核心和強大的概念,它提供了對記憶體的直接訪問和操作能力。以下是指標的一些基礎知識和詳細解釋:

1. 指標的定義

指標是一個變數,其儲存的是另一個變數的記憶體地址。指標變數的宣告通常包括指標型別和指標名,例如:

int *ptr; // ptr是一個指向整型變數的指標

2. 指標的型別

指標的型別決定了它可以指向的資料型別。例如:

  • int *ptr 指向一個整型變數。
  • float *ptr 指向一個浮點型變數。
  • char *ptr 指向一個字元型變數。

3. 指標的初始化

指標變數在使用前應該被初始化,以避免指向隨機的記憶體地址。可以初始化為NULL或者具體的地址:

int a = 10;
int *ptr = &a; // ptr指向變數a的地址
int *ptr = NULL; // ptr初始化為NULL

4. 指標的解引用

透過指標訪問其指向的變數的值稱為解引用。使用*運算子來解引用指標:

int a = 10;
int *ptr = &a;
int value = *ptr; // value現在等於10

5. 指標的算術

指標可以進行加法和減法運算,但只能對同型別的指標進行。指標的加法實際上是按照指標指向的資料型別的大小進行跳轉:

char str[] = "Hello";
char *ptr = str;
ptr++; // ptr現在指向'e'

6. 指標和陣列

指標和陣列緊密相關。陣列名本身可以作為指向陣列第一個元素的指標:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr指向陣列的第一個元素

7. 指標和函式

指標可以作為函式引數傳遞,這允許函式直接修改傳入的變數:

void increment(int *num) {
    (*num)++; // 增加指標指向的值
}

8. 指標的指標

指標的指標是指指向另一個指標的指標。這在處理多級指標和動態記憶體分配時非常有用:

int a = 10;
int *ptr1 = &a;
int **ptr2 = &ptr1;

9. 動態記憶體分配

使用malloccallocreallocfree等函式可以在堆上動態分配和釋放記憶體。這些函式返回指向分配記憶體的指標:

int *ptr = (int *)malloc(sizeof(int)); // 分配一個整型大小的記憶體
if (ptr != NULL) {
    *ptr = 20; // 使用分配的記憶體
    free(ptr); // 釋放記憶體
}

10. 指標和字串

在C語言中,字串通常以字元陣列的形式儲存,而字元陣列的地址可以作為指向字串的指標:

char str[] = "Hello";
char *ptr = str; // ptr指向字串的首地址

11. 指標的比較

可以比較兩個指標是否相等,或者它們是否指向同一塊記憶體區域。也可以比較指標的值(即它們儲存的地址)。

12. 指標的注意事項

  • 避免野指標(未初始化的指標)。
  • 避免記憶體洩漏(分配了記憶體但沒有釋放)。
  • 注意指標的生命週期,確保在指標使用完畢後釋放記憶體。
  • 避免越界訪問,這可能導致程式崩潰或資料損壞。

指標是C語言中非常強大的工具,但也需要謹慎使用,以避免常見的錯誤和安全問題。

問題2:#ifdef、#ifndef、#endif:用於條件編譯。如何使用
回答:#ifdef#ifndef#endif 是 C 語言前處理器指令,用於條件編譯,即根據特定的條件決定是否編譯程式碼的某個部分。這些指令通常用於根據不同的平臺、作業系統或編譯器選項來包含或排除程式碼段。

以下是如何使用這些指令的詳細說明:

1. #ifdef(If defined)

#ifdef 指令用於檢查一個宏是否已經定義。如果宏已經定義,則編譯下面的程式碼塊;如果沒有定義,則跳過該程式碼塊。

#ifdef MACRO
// 如果宏MACRO已經定義,則編譯這段程式碼
#endif // MACRO

2. #ifndef(If not defined)

#ifndef 指令用於檢查一個宏是否沒有定義。如果宏沒有定義,則編譯下面的程式碼塊;如果已經定義,則跳過該程式碼塊。

#ifndef MACRO
// 如果宏MACRO沒有定義,則編譯這段程式碼
#endif // MACRO

3. #endif(End if)

#endif 指令用於結束由 #ifdef#ifndef 開始的條件編譯塊。

使用示例

假設我們有一個宏 DEBUG,我們想要在除錯模式下編譯某些程式碼,而在釋出模式下不編譯這些程式碼:

#ifdef DEBUG
#include <stdio.h>
printf("Debug information: Variable x = %d\n", x);
#endif // DEBUG

在上面的程式碼中,如果 DEBUG 宏被定義了,那麼包含 printf 的程式碼塊將被編譯;否則,這段程式碼將被編譯器忽略。

同樣地,使用 #ifndef

#ifndef DEBUG
// 這段程式碼只有在DEBUG宏未定義時才會被編譯
#endif // DEBUG

組合使用

#ifdef#ifndef 可以與 #else 結合使用,以提供兩種互斥的編譯選項:

#ifdef MACRO
// 如果MACRO定義了,編譯這段程式碼
#else
// 如果MACRO沒有定義,編譯這段程式碼
#endif

這種結構允許你根據宏是否存在來選擇兩個程式碼塊中的一個進行編譯。

宏定義

宏通常在編譯前透過編譯器命令列選項定義,或者在程式碼中使用 #define 指令定義:

#define MACRO

或者在編譯時透過命令列定義(以 GCC 為例):

gcc -DMACRO source.c

使用條件編譯可以使得程式碼更加靈活,能夠適應不同的編譯環境和配置需求。

三個原則:

  • 切勿原封不動地接受生成式人工智慧工具的輸出;確保對其進行評估、完善和修改(或提示),以適應您的目標。
  • 切勿將任何個人資料(自己、同學、老師等)或版權材料納入到你的提示詞中。這個可以說是保護個人隱私的最起碼的舉措。
  • 所有人工智慧生成工具都容易產生幻覺,因此會生成不準確或誤導性的資訊,要學會甄別資訊真假

選擇至少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小時

  • 改進情況:

(有空多看看現代軟體工程 課件
軟體工程師能力自我評價表
)

參考資料

  • 《電腦科學概論(第七版)》
  • ...

相關文章