2024-2025-1 20241302 《计算机基础与程序设计》第十二周学习总结

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):释放之前分配的内存块。
  • 长度可变的一维动态数组:使用 malloccalloc 分配内存,然后用 free 释放。
  • 长度可变的二维动态数组:可以使用双重指针或指针数组来实现,先分配指针数组,再为每个指针分配一维数组。

5. 本章扩充内容(第295页)

  • 常见的内存错误及其对策
    • 野指针:未初始化或已释放的指针。
    • 内存泄漏:分配的内存未被释放。
    • 越界访问:访问超出数组边界。
    • 重复释放:多次释放同一块内存。
    • 解决方案:使用工具如 Valgrind 进行内存检测,合理管理内存生命周期。
  • 缓冲区溢出攻击
    • 概念:当向缓冲区写入超过其容量的数据时,可能导致程序崩溃或被恶意利用。
    • 预防措施:使用安全的函数如 strncpysnprintf,避免使用不安全的函数如 getsstrcpy

6. 本章知识点小结(第305页)

  • 指针和数组的关系:指针可以用来访问和操作数组。
  • 指针数组的应用:存储多个字符串或命令行参数。
  • 动态内存管理:使用 malloccallocreallocfree 进行动态内存管理。
  • 内存错误处理:识别和预防常见的内存错误,确保程序的健壮性。

7. 本章常见错误小结(第305页)

  • 指针未初始化:使用未初始化的指针会导致未定义行为。
  • 内存泄漏:忘记释放已分配的内存。
  • 越界访问:访问数组或指针指向的内存区域之外。
  • 重复释放:多次释放同一块内存。
  • 野指针:使用已释放的指针。
  • 缓冲区溢出:写入超过缓冲区大小的数据。

教材学习中的问题和解决过程(先问 AI)

问题:动态数组的使用方法。

解决过程:在C语言中,没有内置的动态数组类型,但可以通过指针和内存管理函数(如mallocreallocfree)来实现动态数组的功能。下面是一个简单的示例,演示如何创建、使用和释放动态数组。

创建动态数组

使用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: 用于释放之前通过malloccallocrealloc分配的内存。释放后,不应再访问该内存区域。

注意事项

  • 在使用mallocrealloc时,总是检查返回值是否为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小时

  • 改进情况:

(有空多看看现代软件工程 课件
软件工程师能力自我评价表
)

参考资料

posted @   RUNNNNN  阅读(9)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示