首页 > 编程语言 >2024-2025-1 20241314 《计算机基础与程序设计》第十四周学习总结

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

时间:2024-12-29 14:58:01浏览次数:1  
标签:fp 文件 return 函数 int 2024 2025 20241314 指针

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

作业信息

这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计
这个作业要求在哪里 <作业要求的链接>2024-2025-1计算机基础与程序设计第十四周作业
作业正文 正文

教材学习内容总结

第十三章:文件操作

一、文件概述

  • 文件的概念
    • 文本文件:例如一个简单的文本文件example.txt,内容是“Hello, World!”。在文本文件中,每个字符都按照字符编码(如ASCII码)存储。在ASCII码中,字符‘H’对应的十进制值是72,‘e’是101等等。当我们用文本编辑器打开这个文件时,编辑器会根据字符编码将这些数字转换为对应的字符显示出来。
    • 二进制文件:以存储整数数组为例。如果有一个整数数组int arr[] = {1, 2, 3, 4, 5},在二进制文件中,这些整数会按照它们在内存中的存储形式(在大多数系统中,int类型占4个字节)直接存储到文件中。这种存储方式对于计算机处理数据效率较高,但对于人类来说,打开文件看到的是一堆乱码。
  • 文件指针
    • 例如,定义一个文件指针FILE *fp;。这个指针变量将用于指向我们要操作的文件相关的结构体信息。就好像这个指针是一个“把手”,通过它可以找到文件的各种属性以及对文件进行读写等操作。

二、文件的打开与关闭

  • fopen函数
    • 示例:
#include <stdio.h>
int main()
{
    FILE *fp;
    // 尝试以只读方式打开文件
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 文件操作...
    fclose(fp);
    return 0;
}

在这个例子中,程序试图打开一个名为example.txt的文件用于只读。如果fp的值为NULL,说明文件打开失败,通过perror函数打印出错误信息。如果打开成功,就可以对文件进行后续操作,最后使用fclose函数关闭文件。

  • fclose函数
    • 继续上面的例子,fclose(fp);语句用于关闭已经打开的文件。如果文件在写入操作后没有正确关闭,可能会导致数据丢失。例如,如果正在向文件写入数据,数据可能还在缓冲区中,没有真正写入磁盘,关闭文件会强制将缓冲区的数据写入磁盘。

三、文件的读写

  • 字符读写函数
    • fgetc函数
#include <stdio.h>
int main()
{
    FILE *fp;
    int ch;
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 从文件中读取一个字符
    ch = fgetc(fp);
    if (ch!= EOF)
    {
        putchar(ch);
    }
    fclose(fp);
    return 0;
}

在这个程序中,首先打开文件example.txt。然后使用fgetc函数从文件中读取一个字符,将其存储在变量ch中。如果ch不等于EOF(文件结束标志),就使用putchar函数将这个字符输出到控制台。
- fputc函数

#include <stdio.h>
int main()
{
    FILE *fp;
    char ch = 'A';
    fp = fopen("new_file.txt", "w");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 将字符写入文件
    fputc(ch, fp);
    fclose(fp);
    return 0;
}

这里创建了一个新文件new_file.txt(如果文件已存在,内容会被清空),然后使用fputc函数将字符‘A’写入这个文件。

  • 字符串读写函数
    • fgets函数
#include <stdio.h>
int main()
{
    FILE *fp;
    char str[100];
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 从文件中读取一行字符串
    fgets(str, 100, fp);
    printf("%s", str);
    fclose(fp);
    return 0;
}
 假设`example.txt`中有多行内容,这个程序会从文件中读取最多99个字符(因为要留一个位置给字符串结束符`\0`)到字符数组`str`中。读取会在遇到换行符`\n`、读取了99个字符或者遇到文件末尾`EOF`时停止,然后将读取到的字符串输出到控制台。
    - **fputs函数**:
```c
#include <stdio.h>
int main()
{
    FILE *fp;
    char str[] = "This is a test string.";
    fp = fopen("new_file.txt", "a");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 将字符串写入文件
    fputs(str, fp);
    fclose(fp);
    return 0;
}

程序打开文件new_file.txt用于追加内容。然后使用fputs函数将字符串str的内容写入文件。如果文件原来有内容,新内容会添加在文件末尾。

  • 格式化读写函数
    • fscanf函数
      假设data.txt文件内容为“1 2.5”,下面的程序读取文件中的整数和浮点数。
#include <stdio.h>
int main()
{
    FILE *fp;
    int num;
    float fnum;
    fp = fopen("data.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 从文件中按照格式读取数据
    fscanf(fp, "%d %f", &num, &fnum);
    printf("读取的整数为:%d,浮点数为:%f\n", num, fnum);
    fclose(fp);
    return 0;
}
- **fprintf函数**:
#include <stdio.h>
int main()
{
    FILE *fp;
    int num = 10;
    float fnum = 3.14;
    fp = fopen("output.txt", "w");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 将数据按照格式写入文件
    fprintf(fp, "整数为:%d,浮点数为:%f", num, fnum);
    fclose(fp);
    return 0;
}

这个程序创建一个新文件output.txt,并将整数num和浮点数fnum按照指定的格式写入文件。

四、文件的定位

  • rewind函数
#include <stdio.h>
int main()
{
    FILE *fp;
    char ch;
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 读取一个字符
    ch = fgetc(fp);
    if (ch!= EOF)
    {
        putchar(ch);
    }
    // 将文件指针重新定位到文件开头
    rewind(fp);
    // 再次读取一个字符
    ch = fgetc(fp);
    if (ch!= EOF)
    {
        putchar(ch);
    }
    fclose(fp);
    return 0;
}

在这个例子中,首先从文件中读取一个字符并输出。然后使用rewind函数将文件指针重新定位到文件开头,再次读取一个字符并输出,这样可以看到文件内容被重新读取的过程。

  • fseek函数
#include <stdio.h>
int main()
{
    FILE *fp;
    char ch;
    fp = fopen("example.txt", "r");
    if (fp == NULL)
    {
        perror("文件打开失败");
        return 1;
    }
    // 将文件指针从文件开头向后移动3个字节
    fseek(fp, 3L, SEEK_SET);
    // 读取一个字符
    ch = fgetc(fp);
    if (ch!= EOF)
    {
        putchar(ch);
    }
    fclose(fp);
    return 0;
}

假设example.txt中有足够的内容,这个程序将文件指针从文件开头向后移动3个字节,然后读取并输出一个字符。这可以用于跳过文件开头的一些内容或者定位到文件中的特定位置进行读取。

第十四章:其他高级主题

一、动态内存分配

  • malloc函数、calloc函数和realloc函数
    • malloc函数
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *p;
    // 分配可以存储5个整数的内存空间
    p = (int *)malloc(5 * sizeof(int));
    if (p == NULL)
    {
        perror("内存分配失败");
        return 1;
    }
    for (int i = 0; i < 5; i++)
    {
        p[i] = i;
    }
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", p[i]);
    }
    // 释放内存
    free(p);
    return 0;
}

这个程序首先使用malloc函数分配了可以存储5个整数的内存空间。如果分配成功,p将指向这块内存空间的起始地址。然后通过数组的方式给每个元素赋值,并输出这些元素的值。最后使用free函数释放分配的内存,避免内存泄漏。
- calloc函数

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *p;
    // 分配可以存储5个整数的内存空间,并初始化为0
    p = (int *)calloc(5, sizeof(int));
    if (p == NULL)
    {
        perror("内存分配失败");
        return 1;
    }
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", p[i]);
    }
    // 释放内存
    free(p);
    return 0;
}

malloc函数不同,calloc函数在分配内存后会将内存空间初始化为0。在这个程序中,分配了可以存储5个整数的内存空间,然后直接输出这些元素的值,可以看到它们都是0。
- realloc函数

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int *p;
    // 先分配可以存储5个整数的内存空间
    p = (int *)malloc(5 * sizeof(int));
    if (p == NULL)
    {
        perror("内存分配失败");
        return 1;
    }
    for (int i = 0; i < 5; i++)
    {
        p[i] = i;
    }
    // 重新分配内存空间,使其可以存储10个整数
    p = (int *)realloc(p, 10 * sizeof(int));
    if (p == NULL)
    {
        perror("内存重新分配失败");
        return 1;
    }
    for (int i = 5; i < 10; i++)
    {
        p[i] = i;
    }
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", p[i]);
    }
    // 释放内存
    free(p);
    return 0;
}

程序首先使用malloc函数分配了可以存储5个整数的内存空间,然后使用realloc函数将其重新分配为可以存储10个整数的内存空间。接着给新增加的元素赋值,并输出所有元素的值。最后释放内存。

二、命令行参数

  • main函数的参数
#include <stdio.h>
int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("请在命令行输入参数\n");
        return 1;
    }
    printf("程序名:%s\n", argv[0]);
    for (int i = 1; i < argc; i++)
    {
        printf("参数 %d:%s\n", i, argv[i]);
    }
    return 0;
}

假设这个程序名为test。如果在命令行输入test arg1 arg2argc的值为3。argv[0]指向字符串"test"(程序名),argv[1]指向"arg1"argv[2]指向"arg2"。程序会先检查是否有足够的参数,如果有,就输出程序名和各个参数。这可以用于实现根据不同的命令行参数执行不同的功能,比如一个文件处理程序可以根据命令行输入的文件名来处理不同的文件。

三、预处理指令的深入应用

  • 宏定义的高级用法
    • 带参数的宏定义
#include <stdio.h>
#define MAX(a, b) ((a) > (b)? (a) : (b))
int main()
{
    int x = 5;
    int y = 3;
    int max_value = MAX(x, y);
    printf("较大的值是:%d\n", max_value);
    return 0;
}

这个程序定义了一个带参数的宏MAX,用于比较两个数并返回较大的值。在main函数中,通过MAX(x, y)调用这个宏,预处理器会将其替换为((x) > (y)? (x) : (y)),从而实现比较两个数大小的功能。
- 条件编译指令

#include <stdio.h>
#define DEBUG
int main()
{
#ifdef DEBUG
    printf("程序处于调试模式\n");
#endif
    return 0;
}
  • 在这个程序中,定义了DEBUG宏。因为#ifdef DEBUG条件成立,所以printf语句会被编译并执行。如果没有定义DEBUG宏,这部分代码将不会被编译,这对于在调试阶段输出一些调试信息,而在正式发布时不输出这些信息很有用。

教材学习中的问题和解决过程

指针数组,数组指针,函数指针,指针函数的定义与区别

  1. 指针数组
    • 定义:指针数组是一个数组,其元素为指针类型。也就是说,数组中的每个元素都存放着一个地址。其定义形式一般为数据类型 *数组名[数组大小];。例如int *p[5];,这里定义了一个名为p的指针数组,它可以存放5个指向int类型数据的指针。
    • 示例
#include <stdio.h>
int main()
{
    int a = 1, b = 2, c = 3, d = 4, e = 5;
    int *p[5];
    p[0] = &a;
    p[1] = &b;
    p[2] = &c;
    p[3] = &d;
    p[4] = &e;
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", *(p[i]));
    }
    return 0;
}
- 在这个例子中,首先定义了5个整数`a`、`b`、`c`、`d`、`e`,然后定义了一个指针数组`p`。通过`p[i] = &变量名`的方式,将每个变量的地址存放在指针数组`p`的元素中。最后,通过`*(p[i])`的方式访问每个变量的值并打印出来。
  1. 数组指针
    • 定义:数组指针是一个指针,它指向一个数组。定义形式为数据类型 (*指针变量名)[数组大小];。例如int (*q)[5];,这里q是一个指针,它指向一个包含5个int类型元素的数组。
    • 示例
#include <stdio.h>
int main()
{
    int arr[5] = {1, 2, 3, 4, 5};
    int (*q)[5];
    q = &arr;
    for (int i = 0; i < 5; i++)
    {
        printf("%d ", (*q)[i]);
    }
    return 0;
}
- 在这个例子中,首先定义了一个数组`arr`和一个数组指针`q`。然后将数组`arr`的地址赋给`q`(注意是`&arr`而不是`arr`)。最后通过`(*q)[i]`的方式访问数组中的元素并打印出来。这种方式是先解引用指针`q`得到指向的数组,再通过索引`i`访问数组中的元素。
  1. 函数指针
    • 定义:函数指针是指向函数的指针。函数在内存中也有自己的地址,函数指针可以保存这个地址,从而可以通过函数指针来调用函数。其定义形式为返回值类型 (*指针变量名)(参数列表);。例如int (*func_ptr)(int, int);定义了一个函数指针func_ptr,它可以指向一个返回值为int,参数为两个int类型的函数。
    • 示例
#include <stdio.h>
int add(int a, int b)
{
    return a + b;
}
int main()
{
    int (*func_ptr)(int, int);
    func_ptr = add;
    int result = func_ptr(3, 5);
    printf("结果是:%d\n", result);
    return 0;
}
- 在这个例子中,首先定义了一个函数`add`,用于计算两个整数的和。然后在`main`函数中定义了一个函数指针`func_ptr`,并将`add`函数的地址赋给它(通过`func_ptr = add;`)。最后通过`func_ptr(3, 5)`来调用`add`函数,就好像`func_ptr`就是`add`函数一样,得到计算结果并打印出来。
  1. 指针函数
    • 定义:指针函数是一个函数,其返回值是一个指针。定义形式为数据类型 *函数名(参数列表);。例如int *func(int a);定义了一个函数func,它接受一个int类型的参数a,并且返回一个指向int类型数据的指针。
    • 示例
#include <stdio.h>
#include <stdlib.h>
int *create_array(int size)
{
    int *arr = (int *)malloc(size * sizeof(int));
    if (arr == NULL)
    {
        return NULL;
    }
    for (int i = 0; i < size; i++)
    {
        arr[i] = i;
    }
    return arr;
}
int main()
{
    int *p;
    p = create_array(5);
    if (p!= NULL)
    {
        for (int i = 0; i < 5; i++)
        {
            printf("%d ", p[i]);
        }
        free(p);
    }
    return 0;
}
- 在这个例子中,`create_array`函数是一个指针函数,它接受一个整数`size`作为参数,用于分配一个包含`size`个`int`类型元素的数组空间。在函数内部,通过`malloc`函数分配内存,给数组元素赋值后,返回这个数组的首地址(即指向`int`类型的指针)。在`main`函数中,通过`p = create_array(5);`调用这个指针函数,得到返回的指针,然后可以通过这个指针访问数组元素。最后使用`free`函数释放内存。
  1. 区别总结
    • 指针数组:重点在于它是一个数组,数组元素是指针。可以用于存储多个同类型的指针,比如存储多个字符串的首地址等情况。
    • 数组指针:重点是一个指针,它指向一个数组。在处理二维数组或者需要将数组作为参数传递给函数并且在函数内部需要以数组的形式操作数据时比较有用。
    • 函数指针:主要用于指向函数,通过函数指针可以实现函数回调等功能,比如在库函数或者事件驱动编程中很常见。
    • 指针函数:本质是一个函数,其特点是返回值为指针。通常用于需要在函数内部动态分配内存并且返回这个内存空间地址的情况。

基于AI的学习


标签:fp,文件,return,函数,int,2024,2025,20241314,指针
From: https://www.cnblogs.com/serene99/p/18638770

相关文章

  • 2024-12-12《UML类图》
    UML九图  1.类图类图(ClassDiagram)是面向对象系统建模中最常用和最重要的图,是定义其它图的基础。类图主要是用来显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。类图不仅用于可视化描述和记录系统的不同方面,也为构建可执行代码的软件应用程序。类图描述......
  • 2024-12-13《构建之法阅读笔记》
    构建之法阅读笔记(1) 第一章概论在这一章中,作者为我们介绍了一些关于软件工程的基本知识。①软件=程序+软件工程:正是因为对软件开发活动(构建管理、源代码管理、软件设计、软件测试、项目管理)相关的内容的完成,才能完成把整个程序转化成为一个可用的软件的过程。扩展的推论......
  • 2024-11-25《Vscode热部署》
    VsCode配置Javaweb热部署(Deploy)   最近又开始使用VsCode来进行web开发,但是每次都需要package一下项目再放到Tomcat下面太繁琐了,就想着能不能像IDEA一样可以进行热部署,经过不懈百度后终于发现了解决方法。首先需要以下三个插件:  首先我们要去创建一个webapp项目,具体的......
  • 2024-11-28《关于mybatis创建的mapper映射路径不对导致的系列报错》
    关于mybatis创建的mapper映射路径不对导致的系列报错 今天在写mybatis项目的时候,使用注解发现无法使用别名,添加ResultMap的时候直接报错显示无法解析。经过百度了好久也是成功的发现了问题的所在,就是这个:这个路径创建的时候我以为创建的是分级目录,实际上创建成为了com.inn......
  • 2024-11-27《架构漫谈读后感》
    架构漫谈读后感 首先,最近在课上老师推荐我们阅读王概凯老师的架构漫谈连载博客,通过详细的阅读,我确实收获颇丰。首先就是对于架构是什么,架构解决的是什么有了一个深入的了解。第一,什么架构呢?王概凯老师认为他没有一个确切的定义,在软件行业,每个人都有自己的理解,所以一百个人心......
  • 2024-11-29《axios获取不到response返回的响应的解决方法》
    axios获取不到response返回的响应的解决方法 今天在用mybatis+vue+axios写登录界面的时候,发现用户名还有密码的数据都能够传输到servlet里,但是当servlet对html界面进行相应的时候,axios却收不到消息,经过长时间的排查后也没有发现问题,终于在今晚的百度下发现了结果,上原文:解决方......
  • 2024-12-3《利用ffmpeg推流到rtsp,再利用jmpeg在html界面上显示的解决办法》
    利用ffmpeg推流到rtsp,再利用jmpeg在html界面上显示的解决办法  目录需求在python代码里推流到rtsphtml里播放rtsp视频流 需求最近在百度飞桨上训练了一个摔倒识别的模型,用的PaddleDetection这个模型,训练好以后我部署到了Windows,但是我看大多数人都是部署到了......
  • 2024-12-4《大数据指令汇总》
    大数据指令汇总  目录使用Finalshell作为连接机器界面命令汇总针对全部会话的命令Zookeeper集群启动:Zookeeper集群状态:Zookeeper集群关闭:针对当前会话的命令Hadoop启动:Hadoop关闭:hive1启动:hive2启动:beeline启动:beeline登录(账户是root,密码为空):hbase......
  • 2024-12-05《关于pip总是下载到基础环境不下载到虚拟环境》
    关于pip总是下载到基础环境不下载到虚拟环境 今天使用pip安装包报错了,使用piplist查询了一下发现竟然默认安装在了基础环境里,我激活了conda的虚拟环境再运行pip依然是安装在了基础环境里,百度后发现解决方法为去除掉系统环境变量里的PYTHONHOME然后使用虚拟环境变量里的虚拟......
  • 2024-12-06《WebApplication配置》
    WebApplication是用于配置HTTP管道和路由的web应用程序,接来下我将一一拆解它的组成。//////ThewebapplicationusedtoconfiguretheHTTPpipeline,androutes.///[DebuggerDisplay("{DebuggerToString(),nq}")][DebuggerTypeProxy(typeof(WebApplication.WebApplicatio......