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

yokinn發表於2024-11-23
班級連結 https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP
作業要求 https://www.cnblogs.com/rocedu/p/9577842.html#WEEK09
作業目標 作業系統責任 記憶體與程序管理 分時系統 CPU排程 檔案、檔案系統 檔案保護 磁碟排程

教材學習內容總結
《電腦科學概論》第十章第十一章
第十章 作業系統基礎
作業系統的概念與功能:作業系統是管理計算機硬體和軟體資源的程式,是使用者與計算機硬體之間的介面。其主要功能包括資源管理(如CPU、記憶體、外設等)和任務排程。核心功能有程序管理、記憶體管理、檔案系統管理、裝置管理以及使用者介面

程序管理:程序是程式的一個執行例項,有獨立的記憶體空間和執行狀態,包括執行態、就緒態、阻塞態等。作業系統透過特定的排程演算法決定程序的執行順序,常見排程演算法有先來先服務、短作業優先、優先順序排程、時間片輪轉等

記憶體管理:作業系統負責分配記憶體給程序,常見的記憶體分配方式有連續記憶體分配、分頁系統、分段系統。虛擬記憶體技術可透過硬碟空間模擬出比實體記憶體更大的記憶體空間,讓程式能使用更多記憶體

檔案系統:檔案是資料儲存的基本單位,作業系統管理檔案的建立、刪除、讀取和寫入等操作,並透過目錄結構組織檔案,還可對檔案進行許可權控制,檔案通常儲存在硬碟等外部儲存裝置上

輸入輸出管理:輸入輸出裝置包括鍵盤、滑鼠、顯示器、硬碟等。作業系統透過提供緩衝區和I/O排程演算法,提高資料傳輸效率,減少等待時間

第十一章 資料庫系統
資料庫系統概述:資料庫是有組織的資料集合,由資料庫管理系統進行管理,提供高效的資料儲存、查詢、更新和管理功能。資料庫管理系統確保資料的完整性、一致性和安全性

資料模型:主要有層次模型、網狀模型和關係模型。層次模型以樹形結構組織資料;網狀模型以圖形結構組織,更靈活;關係模型以二維表格形式組織,是目前最常用的資料模型,關聯式資料庫管理系統採用此模型

關聯式資料庫:表是基本儲存單位,包含列(屬性)和行(記錄)。主鍵用於唯一標識每條記錄,外來鍵用於建立表之間的聯絡。資料完整性包括實體完整性、參照完整性和域完整性等

SQL語言:SQL是用於訪問和運算元據庫的標準語言,包括資料查詢(SELECT)、資料操作(INSERT、UPDATE、DELETE)、資料定義(CREATE、ALTER、DROP)以及資料控制(GRANT、REVOKE)等功能

資料庫設計:實體-關係模型是一種圖形化的資料庫設計工具,用於描述資料庫中的實體及其關係。規範化可消除冗餘資料、避免更新異常,常見的規範化正規化有第一正規化、第二正規化、第三正規化等

《C語言程式設計》第八章
一、陣列的定義和使用
定義一維陣列:可以透過指定陣列的長度和型別來定義一維陣列,例如 int a[10]; 定義了一個包含10個整數的陣列。
引用一維陣列元素:透過陣列名和下標來引用陣列元素,例如 a[6] 表示陣列 a 中序號為6的元素。
一維陣列的初始化:可以在定義陣列時對全部或部分陣列元素賦予初值,例如:
全部初始化:int a[10]={0,1,2,3,4,5,6,7,8,9};
部分初始化:int a[10]={0,1,2,3};(剩餘元素自動初始化為0)
全部元素值為0:int a[10]={0}; 或 int a[10]={0,0,0,0,0,0,0,0,0,0};
二、二維陣列的定義和使用
定義二維陣列:透過兩個常量表示式來定義二維陣列,例如 float a[3][4],b[5][11]; 分別定義了3x4和5x11的二維陣列。
引用二維陣列元素:透過兩個下標來引用二維陣列的元素,例如 a[1][2] 表示陣列 a 第二行第三列的元素。
三、陣列的指標
陣列元素的指標:可以透過指標來引用陣列元素,例如 int *p=&a[0]; 將指標 p 指向陣列 a 的第一個元素。
指標的自增自減:如果指標 p 已經指向陣列中的一個元素,則 p+1 指向下一個元素,p-1 指向上一個元素。
四、字串處理
字串的結束標誌:字串以 '\0' 結尾,這是字串處理函式定位字串結束的關鍵。
字串處理函式:學習瞭如何使用字串處理函式,如 strcpy、strlen 等,來操作字串。
五、查詢和排序
查詢演算法:介紹了順序查詢演算法,即遍歷陣列查詢某個元素。
排序演算法:介紹了氣泡排序演算法,這是一種簡單的排序方法,透過重複遍歷待排序的數列,比較每對相鄰元素,如果順序錯誤就交換過來。

教材學習中的問題與解決過程
問題一:怎麼讓呼叫函式的值正常返回到主函式中?
AI:在C語言中,函式的值可以透過以下幾種方式返回到主函式中:

返回值(Return Value):
使用return語句將值返回給呼叫函式。這是最常見的方法,適用於返回單個值的情況。

c
int add(int a, int b) {
return a + b; // 將計算結果返回
}

int main() {
int result = add(5, 3); // 接收返回值
printf("%d", result); // 輸出結果
return 0;
}
指標引數(Pointer Arguments):
如果需要返回多個值,可以透過傳遞指標引數到被呼叫函式,然後在被呼叫函式中修改這些指標指向的值。

c
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}

int main() {
int x = 5, y = 10;
swap(&x, &y); // 透過指標傳遞值
// x 和 y 的值已經被交換
return 0;
}
陣列引數(Array Arguments):
對於返回一系列值的情況,可以使用陣列作為引數。

c
void getNumbers(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] = i * i;
}
}

int main() {
int arr[5];
getNumbers(arr, 5);
// arr 中的元素現在是 0, 1, 4, 9, 16
return 0;
}
結構體引數(Structure Arguments):
如果返回的資料是複合資料型別,可以使用結構體。

c
typedef struct {
int x;
int y;
} Point;

void getPoint(Point *p) {
p->x = 10;
p->y = 20;
}

int main() {
Point p;
getPoint(&p); // 透過結構體指標傳遞
// p.x 和 p.y 現在分別是 10 和 20
return 0;
}
全域性變數(Global Variables):
雖然不推薦使用全域性變數,但它們可以用來在函式之間共享資料。

c
int globalVar;

void setGlobalVar(int value) {
globalVar = value;
}

int main() {
setGlobalVar(100);
// globalVar 現在是 100
return 0;
}
問題二:陣列中每個元素的值的地址怎麼透過偏移量計算?
AI:在C語言中,陣列元素的地址可以透過偏移量來計算。陣列元素的偏移量是相對於陣列首元素地址的差值。對於一個陣列 arr,其第 i 個元素的地址可以透過以下公式計算:

地址 of
a
r
r
[
i
]

地址 of
a
r
r
[
0
]
+
i
×
元素大小
地址 of arr[i]=地址 of arr[0]+i×元素大小

這裡,\text{地址 of } arr[0] 是陣列首元素的地址,i 是元素的索引,\text{元素大小} 是陣列元素所佔的位元組數。

例如,假設我們有一個整數陣列 int arr[10];,其中每個整數佔用4個位元組(這取決於編譯器和機器架構,但為了簡化,我們假設是4個位元組)。如果我們想要找到第5個元素的地址,我們可以這樣計算:

地址 of
a
r
r
[
5
]

地址 of
a
r
r
[
0
]
+
5
×
4
地址 of arr[5]=地址 of arr[0]+5×4

這意味著第5個元素的地址是首元素地址加上5個整數所佔的總位元組數。

在C語言中,我們可以使用指標來表示地址,並透過指標運算來計算偏移量。例如:

c
int arr[10];
int *ptr = arr; // ptr 指向陣列的首元素
ptr += 5; // 將 ptr 移動到第6個元素(索引為5)
在這個例子中,ptr 是一個指向 int 型別的指標,ptr += 5 意味著將 ptr 增加5個整數的大小,從而指向陣列的第6個元素。

需要注意的是,當使用指標進行偏移量計算時,確保不要超出陣列的邊界,否則會導致未定義行為。
問題三:C語言中判斷某數是不是整數怎麼表達?
AI:在C語言中,判斷一個數是否為整數,通常是指判斷這個數是否能被精確表示為一個整數,即沒有小數部分。這通常涉及到浮點數的判斷,因為整數型別(如int)本身就是整數,不需要判斷。

如果你有一個浮點數(如float或double型別),並且想要判斷它是否等於某個整數,你可以將這個浮點數與它的整數部分進行比較。這可以透過使用modf函式來實現,該函式可以將浮點數分解為整數部分和小數部分。下面是一個示例:

c

include <stdio.h>

include <math.h>

int isInteger(double num) {
double intPart;
// modf函式將num分解為整數和小數部分,整數部分透過intPart返回
modf(num, &intPart);
// 如果小數部分為0,則num是一個整數
return num == intPart;
}

int main() {
double num = 123.0;
if (isInteger(num)) {
printf("%f 是整數\n", num);
} else {
printf("%f 不是整數\n", num);
}
return 0;
}
在這個例子中,isInteger函式使用modf函式來獲取num的整數部分,並將其與num本身進行比較。如果相等,說明num沒有小數部分,即num是一個整數。

需要注意的是,由於浮點數的精度問題,這種方法可能不適用於所有情況,特別是在處理非常大或非常小的浮點數時。此外,由於浮點數的表示方式,可能會存在一些非常接近整數但不是完全精確的整數的浮點數,這種情況下,即使它們在數學上非常接近整數,isInteger函式也會返回0(即false)。

基於AI的學習
User: 我在學習《C語言程式設計》第八章陣列的相關內容,請你以蘇格拉底的方式,每次向我提問一個問題

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

問題1:當我們談論陣列時,你如何定義它?

User: 先判斷裡面的資料的型別再定義陣列的名字和行列

Kimi: 問題2:那麼,你如何理解陣列中資料型別的一致性?為什麼陣列中的所有元素需要具有相同的資料型別?

User: 一個陣列中的資料型別都是一致的,因為他們佔用相同的預留空間

Kimi: 問題3:你提到陣列中的元素佔用相同的預留空間,那麼這個“預留空間”是如何確定的?是誰來決定每個元素應該佔用多少空間?

User: 定義陣列時分配的空間大小

Kimi: 問題4:當我們在定義陣列時分配空間大小,你能否詳細解釋一下這個過程是如何進行的?比如,如果我們定義了一個整型陣列,編譯器是如何知道需要為每個整型元素分配多少空間的?

User: 整形資料佔用4個位元組,再乘以資料的個數

Kimi: 問題5:你提到整型資料通常佔用4個位元組,這個“通常”意味著什麼?為什麼是“通常”而不是“總是”?不同情況下整型資料佔用的空間大小會有所不同嗎?

User: 是因為整形資料還有長整型long之類的嗎

Kimi: 問題6:對的,你提到了整型資料有intlong等不同的型別。那麼,這些不同型別的整型資料在佔用空間上有何不同?為什麼它們會有不同的空間佔用?這種差異是如何影響陣列定義和使用的?

User: 因為他們的大小範圍不同,所以佔據的空間大小也不同

Kimi: 問題7:確實,不同型別的整型資料有不同的大小範圍,這影響了它們佔用的空間大小。那麼,你能進一步解釋一下為什麼需要有不同的整型資料型別嗎?在實際程式設計中,我們如何選擇使用intlong或其他整型資料型別?

User: 根據資料的大小進行選擇

Kimi: 問題8:你提到根據資料的大小進行選擇,這是一個非常實用的指導原則。那麼,你能描述一下在具體程式設計時,我們如何判斷資料的大小,以及如何根據這個判斷來選擇適當的整型資料型別嗎?例如,當我們需要儲存一個班級學生的學號時,使用int是否足夠,還是需要long

User: 學號一般比較長,所以一般用long型

Kimi: 問題9:你提到學號比較長,所以一般用long型。這個“長”是指什麼?是指學號的位數多,還是指學號的數值範圍大?在實際應用中,學號的位數和數值範圍對資料型別的選擇有何影響?

這個問題可以幫助你深入思考資料型別選擇的依據,不僅僅是基於資料的“長度”,還包括資料的實際範圍和應用場景。

User: 位數多,即數值大

Kimi: 問題10:明白了,你指的是學號的位數多和數值範圍大。那麼,讓我們進一步探討一下:

  1. 位數多:如果學號的位數多,意味著可能需要更多的儲存空間來確保每個學號都能被唯一標識。這是否意味著在位數多的情況下,我們應該選擇更大的資料型別,如longlong long

  2. 數值大:如果學號的數值範圍大,那麼使用int可能不足以覆蓋所有的學號。在這種情況下,選擇longlong long可以提供更大的數值範圍,確保所有學號都能被正確儲存。

那麼,基於這些考慮,你能描述一下在實際程式設計中,我們如何根據學號的位數和數值範圍來選擇合適的資料型別嗎?例如,如果一個學校的學號是8位數字,我們應該如何選擇合適的資料型別?

User: 你的回答呢

Kimi: 如果一個學校的學號是8位數字,我們來分析一下如何選擇資料型別:

  1. int型別:在C語言中,int型別通常佔用4個位元組,即32位。這意味著int可以表示的數值範圍大約是-21億到21億。對於8位數字的學號,即使是最大的8位數(99999999),也遠遠小於int能表示的最大值。因此,從數值範圍的角度來看,int型別是足夠的。

  2. 位數:雖然int可以容納8位數字的學號,但我們還需要考慮位數的問題。如果學號的前幾位是0,例如00012345,那麼直接使用int型別儲存可能會導致前導0的丟失,因為int型別是整數型別,不會儲存前導0。在這種情況下,如果需要保留前導0,我們可能需要使用字串型別(如char陣列)來儲存學號。

  3. long型別long型別通常佔用8個位元組,即64位。對於8位數字的學號,long型別顯然是綽綽有餘的。但是,使用long型別可能會造成儲存空間的浪費,因為long能表示的數值範圍遠遠超過了8位數字學號的需求。

綜上所述,對於8位數字的學號,如果不需要保留前導0,使用int型別是足夠的。如果需要保留前導0,那麼使用字串型別(如char陣列)可能更合適。選擇long型別雖然可以解決問題,但可能會造成儲存空間的浪費。

這個例子展示了在選擇資料型別時,我們需要綜合考慮數值範圍和位數等因素,以選擇最合適的資料型別。

學習進度條
程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積)
目標 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
第五週 900/1300 2/9 30/90
第六週 1000/1300 2/9 30/90
第七週 1000/1300 2/9 30/90
第八週 1100/1300 2/9 40/90
第九周 1300/1500 4/9 50/90

相關文章