2024-2025-1 20241413 《计算机基础与程序设计》第八周学习总结
这个作业属于哪个课程 | 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