這個作業屬於哪個課程 | https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP |
---|---|
這個作業要求在哪裡 | https://www.cnblogs.com/rocedu/p/9577842.html#WEEK08 |
作業目標 | 功能設計與物件導向設計 物件導向設計過程 面嚮物件語言三要素 彙編、編譯、解釋、執行 |
---- | ---- |
教材學習內容總結
《電腦科學概論》第9章
一、章節概覽
本章節深入探討了計算機程式設計的核心概念,包括演算法、資料結構、程式設計正規化以及軟體開發的生命週期。透過對這些基礎概念的學習和理解,學生能夠掌握計算機程式設計的基本技能,併為進一步的專業學習打下堅實的基礎。
二、關鍵概念
演算法:演算法是解決特定問題的明確步驟集合。本章節介紹了演算法的基本概念、特性(如確定性、有窮性、輸入、輸出)以及演算法的複雜度分析。
資料結構:資料結構是組織和儲存資料的方式,以便可以高效地訪問和修改。本章節討論了陣列、連結串列、棧、佇列、樹、圖等基本資料結構的特點和應用場景。
程式設計正規化:程式設計正規化是指編寫程式時所採用的方法論。本章節涵蓋了程序式程式設計、物件導向程式設計、函數語言程式設計等不同的程式設計正規化,並討論了它們的優勢和適用性。
軟體開發生命週期:軟體開發生命週期(SDLC)是指軟體開發過程中的一系列階段。本章節介紹了需求分析、設計、編碼、測試、部署和維護等關鍵階段。
三、演算法與資料結構
演算法和資料結構是電腦科學中緊密相關的兩個概念。演算法的效率往往依賴於所使用的資料結構,而資料結構的設計又是為了支援特定的演算法操作。本章節透過例項分析,展示了不同資料結構對演算法效能的影響。
四、程式設計正規化的比較
不同的程式設計正規化提供了不同的視角和工具來解決程式設計問題。程序式程式設計強調程式的執行流程,物件導向程式設計強調資料和操作的封裝,函數語言程式設計強調不可變資料和函式的純度。本章節透過對不同正規化的比較,幫助學生理解它們在實際程式設計中的應用。
五、軟體開發生命週期的應用
軟體開發生命週期的應用是理解和管理軟體開發專案的關鍵。本章節透過案例分析,讓學生了解如何在實際專案中應用SDLC,以及如何透過各個階段的活動來提高軟體質量和開發效率。
六、總結與展望
透過對本章節的學習,我們不僅掌握了計算機程式設計的基礎知識,還學會了如何將這些知識應用到實際的軟體開發中。隨著技術的不斷進步,新的演算法、資料結構和程式設計正規化也在不斷湧現,持續學習是每個電腦科學從業者的必備素質。
《C語言程式設計》第7章
一、章節概覽
本章節深入探討了C語言中的函式(Function)概念,包括函式的定義、宣告、呼叫以及引數傳遞機制。透過學習,學生將能夠理解如何使用函式來模組化程式碼,提高程式碼的可讀性和可重用性。
二、關鍵概念
函式定義:函式是一段完成特定任務的程式碼塊,它可以透過定義返回值型別、函式名、引數列表和函式體來建立。
函式宣告:函式宣告用於告訴編譯器函式的介面,包括返回型別、函式名和引數型別,但不包括函式體。
函式呼叫:函式呼叫是程式中請求執行另一個函式的操作,它涉及到將控制權傳遞給被呼叫函式,以及在函式執行完畢後返回到呼叫點。
引數傳遞:引數傳遞是將實際引數(實參)的值傳遞給函式的形式引數(形參)的過程。本章節討論了值傳遞和地址傳遞兩種方式。
返回值:函式可以透過return語句返回一個值給呼叫者,返回值的型別必須與函式宣告的返回值型別一致。
三、函式的實現與呼叫
本章節詳細介紹瞭如何在C語言中實現和呼叫函式。包括如何編寫函式體,如何宣告和定義函式原型,以及如何在主函式或其他函式中呼叫這些函式。
四、引數傳遞機制
引數傳遞是函式使用中的關鍵部分。本章節解釋了值傳遞和地址傳遞的區別,並討論了它們在不同情況下的適用性。值傳遞涉及到複製實參的值到形參,而地址傳遞則涉及到傳遞實參的記憶體地址。
五、函式的返回值
函式可以透過return語句返回一個值給呼叫者。本章節討論瞭如何設計返回值,以及如何處理不同型別的返回值,包括基本資料型別和複合資料型別。
六、函式的巢狀呼叫與遞迴
本章節還探討了函式的巢狀呼叫和遞迴呼叫的概念。巢狀呼叫是指一個函式在其執行過程中呼叫另一個函式,而遞迴呼叫是指函式直接或間接地呼叫自身。
七、總結與實踐
透過本章節的學習,我們不僅掌握了函式的基本使用,還了解了如何透過函式來組織程式碼,以及如何透過引數和返回值來控制函式的行為。實踐是鞏固理論知識的重要途徑,建議透過編寫和測試不同的函式來加深對本章節內容的理解。
教材學習中的問題與解決過程
問題一:c語言中只有整型數字可以求餘嗎?
AI:在C語言中,求餘操作是透過 % 運算子來實現的。這個運算子不僅可以用於整型數字,還可以用於浮點型數字。不過,需要注意的是,當涉及到浮點數時,求餘的結果可能與整數求餘的結果有所不同,因為浮點數的表示和運算涉及到精度問題。
具體來說:
整型求餘:對於整型數(如 int、long 等),% 運算子會返回兩數相除後的餘數。這是最常見的用法,也是最直觀的。
浮點型求餘:對於浮點型數(如 float、double 等),% 運算子的行為取決於具體的實現,但通常它也會返回兩數相除後的餘數。不過,由於浮點數的精度限制,結果可能不如整型數那樣精確。
混合型別求餘:當運算元中一個是整型,另一個是浮點型時,整型數可能會被提升為浮點型,然後進行求餘運算。
下面是一個簡單的示例程式碼,展示了整型和浮點型數求餘的情況:
c
include <stdio.h>
int main() {
int a = 10;
int b = 3;
float c = 10.0;
float d = 3.0;
printf("整數求餘:%d %% %d = %d\n", a, b, a % b);
printf("浮點數求餘:%f %% %f = %f\n", c, d, c % d);
return 0;
}
這段程式碼將輸出整型和浮點型數的求餘結果。可以看到,浮點型數的求餘結果可能會有小數部分,這取決於具體的實現和浮點數的精度。
總之,C語言中的 % 運算子不僅可以用於整型數,也可以用於浮點型數,但結果的精確性和表現可能會有所不同。
問題二:怎樣避免主函式中的變數沒在巢狀函式中被使用?
在C語言中,避免主函式中的變數在巢狀函式中被使用,主要依賴於良好的程式設計實踐和對函式作用域的理解。以下是一些建議和策略:
明確函式職責:
設計函式時,明確每個函式的職責和功能。函式應該只處理它們需要的資料,而不是依賴外部的變數。
使用引數傳遞:
將所需的資料作為引數傳遞給函式。這樣,函式就不需要依賴外部變數,而是使用傳遞給它的引數。
返回值:
如果函式需要返回多個值,考慮使用結構體、指標或引用(在C++中)來返回這些值。
全域性變數的使用:
儘量避免使用全域性變數,因為它們可以在程式的任何地方被訪問和修改,這會增加程式出錯的風險。如果必須使用全域性變數,確保它們只在確實需要的地方被訪問。
靜態變數:
在函式內部使用靜態變數,這樣變數的值在函式呼叫之間可以保持不變,但它們仍然是區域性的,不會影響其他函式。
封裝:
使用結構體或類(在C++中)來封裝資料和函式,這樣可以隱藏內部狀態,只透過公共介面與外部互動。
程式碼審查:
進行程式碼審查,檢查是否有不必要的外部變數使用,以及是否有更好的方法來組織程式碼。
單元測試:
編寫單元測試來驗證每個函式的行為,確保它們不依賴於外部狀態。
遵循最小知識原則(Principle of Least Knowledge):
也稱為“最少驚喜原則”,意味著函式應該只瞭解完成其任務所必需的資訊。
遵循單一職責原則(Single Responsibility Principle):
每個函式應該只有一個引起它變化的原因。
避免副作用:
函式應該儘量避免副作用,比如修改外部變數的值。
使用const關鍵字:
對於不應該被修改的引數,使用const關鍵字來修飾,這樣可以提醒呼叫者這些引數不應該被改變。
透過遵循這些最佳實踐,你可以減少或消除對主函式中變數的依賴,使程式碼更加模組化、可維護
問題三:C語言中怎麼表達判斷這個變數是否為整數?
AI;在C語言中,判斷一個變數是否為整數,通常需要考慮變數的型別和值。由於C語言是一種靜態型別語言,變數的型別在編譯時就已經確定,所以如果你的變數被宣告為整數型別(如 int、long、short 等),那麼它自然就是一個整數。但是,如果你想要判斷一個浮點數是否等於一個整數(即沒有小數部分),你可以使用以下方法:
方法1:使用 modf 函式
modf 函式可以將一個浮點數分解為整數部分和小數部分。如果小數部分為零,那麼這個浮點數就是一個整數。
c
include <stdio.h>
include <math.h>
int isInteger(double value) {
double intPart;
return modf(value, &intPart) == 0.0 && intPart == value;
}
int main() {
double num = 10.0;
if (isInteger(num)) {
printf("%f 是整數\n", num);
} else {
printf("%f 不是整數\n", num);
}
return 0;
}
方法2:使用 floor 和 ceil 函式
另一種方法是使用 floor 和 ceil 函式,這兩個函式分別返回小於或等於和大於或等於給定浮點數的最大整數。如果 floor 和 ceil 的結果與原數相等,那麼這個數就是整數。
c
include <stdio.h>
include <math.h>
int isInteger(double value) {
return floor(value) == value && ceil(value) == value;
}
int main() {
double num = 10.0;
if (isInteger(num)) {
printf("%f 是整數\n", num);
} else {
printf("%f 不是整數\n", num);
}
return 0;
}
方法3:使用 fabs 函式
你還可以使用 fabs 函式來計算浮點數與其整數部分的差的絕對值,如果這個差為零,那麼這個數就是整數。
c
include <stdio.h>
include <math.h>
int isInteger(double value) {
return fabs(value - (double)(int)value) == 0.0;
}
int main() {
double num = 10.0;
if (isInteger(num)) {
printf("%f 是整數\n", num);
} else {
printf("%f 不是整數\n", num);
}
return 0;
}
以上方法都可以用於判斷一個浮點數是否為整數。選擇哪種方法取決於你的具體需求和偏好。
基於AI的學習
User: 我正在學習《C語言程式設計》第7章的內容,請你以蘇格拉底的方式,一次向我提問一個我問題
Kimi: 當然可以,讓我們開始蘇格拉底式的對話。首先,我想了解你對C語言程式設計第7章的理解。
- 你能告訴我第7章主要討論了什麼內容嗎?
User: C語言中函式的呼叫
Kimi: 很好,你已經指出了第7章的核心主題是關於C語言中函式的呼叫。那麼,讓我們深入一些。
- 你能描述一下,在你看來,函式在C語言中扮演著什麼樣的角色嗎?
User: 主要組成部分,也是簡化語句的方式
Kimi: 確實,函式是程式的主要組成部分,它們幫助我們模組化程式碼,使程式更加清晰和易於管理。函式也允許我們重複使用程式碼,簡化複雜的語句。
- 既然你提到函式可以簡化語句,那麼你能給我一個例子,說明在不使用函式的情況下,程式碼可能會變得多麼複雜嗎?
User: 你的回答呢
Kimi: 當然,讓我給你一個簡單的例子來說明如果沒有函式,程式碼可能會變得多麼複雜。
假設我們有一個程式,需要計算一個數學表示式的結果,比如計算 ( (a + b) \times (c + d) )。如果沒有函式,我們可能需要在程式的多個地方重複相同的計算邏輯。下面是不使用函式時可能的程式碼結構:
int a = 5;
int b = 10;
int c = 3;
int c = 7;
// 第一次計算
int temp1 = a + b;
int temp2 = c + d;
int result1 = temp1 * temp2;
// 假設我們需要在程式的另一個地方再次計算相同的表示式
int another_a = 2;
int another_b = 4;
int another_c = 6;
int another_d = 8;
// 第二次計算
int temp3 = another_a + another_b;
int temp4 = another_c + another_d;
int result2 = temp3 * temp4;
在這段程式碼中,我們可以看到相同的計算邏輯被重複了兩次,這不僅增加了程式碼量,也增加了出錯的可能性。如果我們需要在程式的更多地方進行這種計算,程式碼的重複性會進一步增加。
- 現在,讓我們討論一下函式如何幫助我們解決這個問題。你能描述一下,如果我們使用函式來封裝這個計算過程,程式碼會有哪些變化嗎?
User: 將定值換為變數
Kimi: 非常好,將定值替換為變數是函式抽象的一個重要方面,它使得程式碼更加通用和可重用。
- 既然我們討論到了將定值替換為變數,那麼你能告訴我,為什麼在函式中使用變數而不是定值是有益的嗎?
(等待你的回答後,我們可以繼續討論如何將這個過程封裝到一個函式中。)
User: 這樣變數可以任意輸入,而只有一個語句就能完成
Kimi: 對的,使用變數而不是定值可以使得函式更加靈活和通用。這樣,函式就可以接受任意的輸入,而不是僅限於特定的值。這不僅減少了程式碼的重複,還提高了程式碼的可維護性和擴充套件性。
- 既然你提到了使用變數可以使函式更加通用,那麼讓我們進一步探討。你能描述一下,如何定義一個函式,使其能夠接受任意的四個整數作為引數,並返回它們的計算結果嗎?
(這個問題將引導我們深入到函式定義和引數傳遞的概念。)
User: 先確定變數型別為int,在輸入變數的值
Kimi: 非常好,你已經理解了函式引數的基本要求。在C語言中,定義一個函式時確實需要先確定引數的型別。對於你提到的計算 ((a + b) \times (c + d)) 的函式,我們可以定義一個接受四個整數引數的函式,並返回它們的計算結果。下面是如何定義這樣一個函式的示例:
#include <stdio.h>
// 函式宣告
int calculateExpression(int a, int b, int c, int d);
int main() {
int a, b, c, d;
printf("Enter four integers: ");
scanf("%d %d %d %d", &a, &b, &c, &d);
// 呼叫函式並列印結果
int result = calculateExpression(a, b, c, d);
printf("The result is: %d\n", result);
return 0;
}
// 函式定義
int calculateExpression(int a, int b, int c, int d) {
return (a + b) * (c + d);
}
在這個例子中,calculateExpression
函式接受四個 int
型別的引數,並返回它們的計算結果。main
函式中,我們提示使用者輸入四個整數,然後呼叫 calculateExpression
函式,並列印出結果。
- 現在,讓我們討論一下函式呼叫的過程。你能描述一下,當你在
main
函式中呼叫calculateExpression
函式時,發生了什麼嗎?
User: 將函式分為了兩個部分
Kimi: 確實,當你在 main
函式中呼叫 calculateExpression
函式時,實際上發生了兩個主要的過程:
-
引數傳遞:
main
函式中的變數a
、b
、c
和d
的值被傳遞給calculateExpression
函式的引數。這是透過值傳遞完成的,意味著函式內部對這些引數的任何修改都不會影響到main
函式中的原始變數。 -
函式執行:
calculateExpression
函式接收到這些值後,執行其內部的程式碼,即計算表示式(a + b) * (c + d)
並將結果儲存在函式內部的一個臨時變數中。 -
你能進一步解釋一下,函式返回值是如何從
calculateExpression
函式傳遞迴main
函式的嗎?
(這個問題將幫助我們理解函式呼叫的返回機制。)
User: 透過return語句
Kimi: 對的,return
語句是C語言中用來從函式返回值的關鍵機制。當 calculateExpression
函式執行完畢後,它會使用 return
語句將計算結果返回給呼叫者,也就是 main
函式。
- 那麼,你能描述一下
return
語句在函式中的作用嗎?它如何影響程式的執行流程?
(這個問題將幫助我們深入理解 return
語句的重要性和它在程式控制流中的作用。)
User: 將被呼叫函式中所需值返回至主函式中
Kimi: 完全正確。return
語句的作用是在函式執行完畢後,將特定的值從被呼叫函式(在這個例子中是 calculateExpression
)傳遞迴主調函式(main
函式)。這個過程可以這樣描述:
-
執行函式體:當
calculateExpression
函式被呼叫時,它首先執行函式體內的程式碼,即計算(a + b) * (c + d)
。 -
返回值:計算完成後,
return
語句將結果賦值給return
表示式,並將這個值返回給呼叫者。 -
控制流轉移:一旦
return
語句執行,函式的執行結束,控制流返回到呼叫點,即main
函式中呼叫calculateExpression
的位置。 -
接收返回值:在
main
函式中,calculateExpression
函式的返回值被儲存在變數result
中,這樣main
函式就可以使用這個值,例如列印輸出。 -
現在,讓我們考慮一個實際的應用場景。假設我們需要在程式中多次使用
calculateExpression
函式,每次使用不同的引數值。你能描述一下,這樣做的好處是什麼嗎?
(這個問題將幫助我們探討函式重用的重要性和它在實際程式設計中的應用。)
學習進度表
程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積)
目標 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