2024-2025-1 20241302 《计算机基础与程序设计》第十二周学习总结
2024-2025-1 20241302 《计算机基础与程序设计》第十二周学习总结
作业信息
这个作业属于哪个课程 | 2024-2025-1-计算机基础与程序设计 |
---|---|
这个作业要求在哪里 | 2024-2025-1计算机基础与程序设计第十二周作业 |
这个作业的目标 | ![]() |
作业正文 | 2024-2025-1 20241302 《计算机基础与程序设计》第十二周学习总结 |
教材学习内容总结
1. 指针和一维数组间的关系(第268页)
- 基本概念:指针可以指向数组中的任何一个元素,通过指针可以访问或修改数组元素。
- 指针与数组名的区别:数组名是一个指向数组首元素的常量指针,而指针变量可以改变其指向。
- 指针算术运算:指针支持加减运算,可以用来遍历数组。
- 数组元素的访问:可以通过指针加上偏移量的方式访问数组中的任意元素,例如
*(array + i)
等价于array[i]
。
2. 指针和二维数组间的关系(第275页)
- 二维数组的存储方式:在内存中,二维数组是以行优先的方式连续存储的。
- 指针与二维数组:二维数组的指针实际上是指向一维数组的指针,即
int (*p)[N];
其中N
是列数。 - 访问二维数组:可以通过指针来访问二维数组中的元素,例如
*(*(arr + i) + j)
或者arr[i][j]
。
3. 指针数组及其应用(第281页)
- 指针数组的定义:指针数组是一种特殊的数组,其中每个元素都是一个指针。
- 字符串数组:指针数组可以用来存储多个字符串,每个字符串由一个字符指针指向。
- 命令行参数:
main
函数中的argv
参数就是一个指针数组,用于接收命令行输入的参数。
4. 动态数组(第289页)
- C程序的内存映像:介绍了程序运行时的内存布局,包括代码段、数据段、堆和栈等。
- 动态内存分配函数:
malloc(size_t size)
:分配指定大小的内存块,返回指向该内存的指针。calloc(size_t num, size_t size)
:分配并初始化为零的内存块。realloc(void *ptr, size_t newsize)
:重新调整已分配内存块的大小。free(void *ptr)
:释放之前分配的内存块。
- 长度可变的一维动态数组:使用
malloc
或calloc
分配内存,然后用free
释放。 - 长度可变的二维动态数组:可以使用双重指针或指针数组来实现,先分配指针数组,再为每个指针分配一维数组。
5. 本章扩充内容(第295页)
- 常见的内存错误及其对策:
- 野指针:未初始化或已释放的指针。
- 内存泄漏:分配的内存未被释放。
- 越界访问:访问超出数组边界。
- 重复释放:多次释放同一块内存。
- 解决方案:使用工具如 Valgrind 进行内存检测,合理管理内存生命周期。
- 缓冲区溢出攻击:
- 概念:当向缓冲区写入超过其容量的数据时,可能导致程序崩溃或被恶意利用。
- 预防措施:使用安全的函数如
strncpy
和snprintf
,避免使用不安全的函数如gets
和strcpy
。
6. 本章知识点小结(第305页)
- 指针和数组的关系:指针可以用来访问和操作数组。
- 指针数组的应用:存储多个字符串或命令行参数。
- 动态内存管理:使用
malloc
、calloc
、realloc
和free
进行动态内存管理。 - 内存错误处理:识别和预防常见的内存错误,确保程序的健壮性。
7. 本章常见错误小结(第305页)
- 指针未初始化:使用未初始化的指针会导致未定义行为。
- 内存泄漏:忘记释放已分配的内存。
- 越界访问:访问数组或指针指向的内存区域之外。
- 重复释放:多次释放同一块内存。
- 野指针:使用已释放的指针。
- 缓冲区溢出:写入超过缓冲区大小的数据。
教材学习中的问题和解决过程(先问 AI)
问题:动态数组的使用方法。
解决过程:在C语言中,没有内置的动态数组类型,但可以通过指针和内存管理函数(如malloc
、realloc
、free
)来实现动态数组的功能。下面是一个简单的示例,演示如何创建、使用和释放动态数组。
创建动态数组
使用malloc
函数分配内存,可以创建一个动态数组。malloc
函数接收一个参数,表示要分配的字节数,并返回指向分配内存的指针。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *array;
int n = 5; // 初始数组大小
int i;
// 分配内存
array = (int *)malloc(n * sizeof(int));
if (array == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return 1;
}
// 初始化数组
for (i = 0; i < n; i++) {
array[i] = i * i;
}
// 打印数组
printf("Initial array:\n");
for (i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 动态增加数组大小
n += 3; // 增加3个元素
array = (int *)realloc(array, n * sizeof(int));
if (array == NULL) {
fprintf(stderr, "Memory reallocation failed\n");
free(array);
return 1;
}
// 继续初始化新增部分
for (i = n - 3; i < n; i++) {
array[i] = i * i;
}
// 再次打印数组
printf("Array after resizing:\n");
for (i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 释放内存
free(array);
return 0;
}
关键点解释
malloc
: 用于分配指定大小的内存块。如果分配成功,返回一个指向该内存块的指针;如果失败,则返回NULL
。realloc
: 用于重新调整之前分配的内存块的大小。如果新的内存块被分配成功,原来的内存块将被释放,新的指针将被返回。如果调整失败,原始内存块保持不变,且返回NULL
。free
: 用于释放之前通过malloc
、calloc
或realloc
分配的内存。释放后,不应再访问该内存区域。
注意事项
- 在使用
malloc
和realloc
时,总是检查返回值是否为NULL
,以确保内存分配成功。 - 使用完动态分配的内存后,应调用
free
来释放它,避免内存泄漏。 - 在使用
realloc
时,如果返回NULL
,则原内存块仍然有效,因此在使用realloc
前最好先保存原指针,以防止内存泄漏。
基于AI的学习
其他(感悟、思考等,可选)
在C语言中,数组和指针是两个非常重要的概念,它们之间有着密切的关系,但也有着本质的区别。理解这两者及其相互作用对于深入掌握C语言至关重要。以下是我对C语言数组与指针学习的一些感悟:
1. 数组与指针的关系
- 内存布局:数组是一段连续的内存空间,用于存储相同类型的元素。而指针则是一个变量,它存储的是另一个变量的地址。当我们将一个数组的名字用作表达式中的值时,它实际上会被转换为指向该数组第一个元素的指针。
- 使用灵活性:指针提供了更大的灵活性。例如,你可以通过指针来改变所指向的地址,而数组名则是一个常量,不能被重新赋值以指向其他位置。
2. 数组与指针的区别
- 类型不同:虽然数组名可以被解释为指向其第一个元素的指针,但数组名本身并不是指针变量。数组名是一个常量,表示数组首元素的地址,而指针是一个变量,可以被赋值或修改。
- 大小不同:
sizeof
应用于数组时,返回的是整个数组占用的字节数;而应用于指针时,返回的是指针本身占用的字节数(通常为4或8字节,取决于系统架构)。 - 传递给函数:当你将数组作为参数传递给函数时,实际上传递的是数组的指针,而不是数组本身。这意味着函数内部对指针的操作会影响到原数组。
3. 指针与数组操作
- 指针算术:指针支持算术运算,如加法、减法等,这使得遍历数组变得简单。例如,
p + i
可以用来访问数组中的第i个元素(假设p是指向数组开始的指针)。 - 指针与字符串:在C语言中,字符串是以空字符
\0
结尾的字符数组。因此,处理字符串时,经常使用指向字符的指针来实现各种操作,如字符串复制、比较等。
4. 学习建议
- 实践:多写代码,尤其是涉及到指针和数组的代码。实践是检验真理的唯一标准,通过实际编程,可以更好地理解这些概念。
- 阅读文档:阅读C语言标准库函数的文档,了解它们如何使用指针和数组,以及它们的返回值和参数类型。
- 理解底层:尝试理解C语言是如何在内存层面操作数组和指针的,这有助于更深入地掌握这些概念。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 300/800 | 1/5 | 10/48 | |
第四周 | 300/1100 | 1/6 | 10/58 | |
第五周 | 300/1400 | 1/7 | 10/68 | |
第六周 | 300/1700 | 1/8 | 10/78 | |
第七周 | 300/2000 | 1/9 | 10/88 | |
第八周 | 300/2300 | 1/10 | 10/98 | |
第九周 | 300/2600 | 1/11 | 10/108 | |
第十周 | 300/2900 | 1/12 | 10/118 | |
第十一周 | 300/3200 | 1/13 | 10/128 | |
第十二周 | 300/3500 | 1/14 | 10/138 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:10小时
-
实际学习时间:10小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)
参考资料
- 《计算机科学概论(第七版)》
- ...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人