2024-2025-1 20241308《计算机基础与程序设计》第十四周学习总结
作业信息
这个作业属于哪个课程 2024-2025-1计算机基础与程序设计
这个作业要求在哪里 2024-2025-1计算机基础与程序设计第十四周作业
这个作业的目标 学习二进制文件和文本文件,文件的打开和关闭,顺序读写与随机读写,标准输入和输出及其重定向
作业正文
教材学习内容总结
1.学习二进制文件和文本文件
在 C 语言中,二进制文件和文本文件的主要区别在于存储数据的方式和读写操作的方法。
一、文本文件
文本文件以字符的形式存储数据,通常可以使用文本编辑器直接查看和编辑。以下是一个使用 C 语言读写文本文件的例子:
#include <stdio.h>
int main() {
// 写入文本文件
FILE *fpWrite = fopen("text.txt", "w");
if (fpWrite == NULL) {
printf("无法打开文件进行写入。\n");
return 1;
}
fprintf(fpWrite, "这是一个文本文件的示例内容。\n");
fclose(fpWrite);
// 读取文本文件
FILE *fpRead = fopen("text.txt", "r");
if (fpRead == NULL) {
printf("无法打开文件进行读取。\n");
return 1;
}
char buffer[100];
fgets(buffer, sizeof(buffer), fpRead);
printf("读取的内容:%s", buffer);
fclose(fpRead);
return 0;
}
在这个例子中,首先使用fopen
函数以写入模式打开一个名为text.txt
的文本文件,如果打开失败则输出错误信息并返回。然后使用fprintf
函数向文件中写入一段文本内容。接着以读取模式打开文件,使用fgets
函数读取文件中的一行内容,并输出到控制台。最后关闭文件。
二、二进制文件
二进制文件以二进制格式存储数据,不能直接用文本编辑器查看。以下是一个使用 C 语言读写二进制文件的例子:
#include <stdio.h>
struct Data {
int num;
char name[20];
};
int main() {
// 写入二进制文件
FILE *fpWriteBinary = fopen("binary.dat", "wb");
if (fpWriteBinary == NULL) {
printf("无法打开文件进行写入。\n");
return 1;
}
struct Data data = {100, "示例数据"};
fwrite(&data, sizeof(struct Data), 1, fpWriteBinary);
fclose(fpWriteBinary);
// 读取二进制文件
FILE *fpReadBinary = fopen("binary.dat", "rb");
if (fpReadBinary == NULL) {
printf("无法打开文件进行读取。\n");
return 1;
}
struct Data readData;
fread(&readData, sizeof(struct Data), 1, fpReadBinary);
printf("读取的整数:%d,字符串:%s\n", readData.num, readData.name);
fclose(fpReadBinary);
return 0;
}
在这个例子中,首先定义了一个结构体Data
,包含一个整数和一个字符数组。然后以写入二进制模式打开文件,创建一个Data
结构体的实例并使用fwrite
函数将其写入二进制文件。接着以读取二进制模式打开文件,使用fread
函数读取文件中的内容到另一个Data
结构体变量中,并输出到控制台。最后关闭文件。
2.文件的打开和关闭
一、文本文件的打开和关闭
#include <stdio.h>
int main() {
// 打开文本文件用于写入
FILE *fpWrite = fopen("text_file.txt", "w");
if (fpWrite == NULL) {
printf("无法打开文件进行写入。\n");
return 1;
}
fprintf(fpWrite, "这是写入文本文件的内容。\n");
fclose(fpWrite);
// 打开文本文件用于读取
FILE *fpRead = fopen("text_file.txt", "r");
if (fpRead == NULL) {
printf("无法打开文件进行读取。\n");
return 1;
}
char buffer[100];
fgets(buffer, sizeof(buffer), fpRead);
printf("读取的内容:%s", buffer);
fclose(fpRead);
return 0;
}
在这个例子中,首先以写入模式打开一个名为text_file.txt
的文本文件,如果打开失败则输出错误信息并返回。向文件中写入一段内容后关闭文件。接着以读取模式打开同一文件,如果打开失败同样输出错误信息并返回。读取文件中的一行内容并输出到控制台,最后关闭文件。
二、二进制文件的打开和关闭
#include <stdio.h>
struct Data {
int num;
char name[20];
};
int main() {
// 打开二进制文件用于写入
FILE *fpWriteBinary = fopen("binary_file.dat", "wb");
if (fpWriteBinary == NULL) {
printf("无法打开文件进行写入。\n");
return 1;
}
struct Data data = {100, "二进制数据示例"};
fwrite(&data, sizeof(struct Data), 1, fpWriteBinary);
fclose(fpWriteBinary);
// 打开二进制文件用于读取
FILE *fpReadBinary = fopen("binary_file.dat", "rb");
if (fpReadBinary == NULL) {
printf("无法打开文件进行读取。\n");
return 1;
}
struct Data readData;
fread(&readData, sizeof(struct Data), 1, fpReadBinary);
printf("读取的整数:%d,字符串:%s\n", readData.num, readData.name);
fclose(fpReadBinary);
return 0;
}
这里定义了一个结构体Data
,以写入二进制模式打开文件,将一个结构体实例写入文件后关闭。然后以读取二进制模式打开文件,读取文件中的内容到另一个结构体变量中,并输出到控制台,最后关闭文件。
3.顺序读写与随机读写
- 顺序读写
- 示例代码(文本文件顺序读写):
- 以下代码实现了向一个文本文件
example.txt
中顺序写入一些字符串,然后再顺序读取并打印这些内容。
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char str[] = "This is a line.\n"; char buffer[100]; // 打开文件用于写入 fp = fopen("example.txt", "w"); if (fp == NULL) { printf("无法打开文件进行写入。\n"); return 1; } // 顺序写入内容 fputs(str, fp); fputs("Another line.\n", fp); fclose(fp); // 打开文件用于读取 fp = fopen("example.txt", "r"); if (fp == NULL) { printf("无法打开文件进行读取。\n"); return 1; } // 顺序读取内容并打印 while (fgets(buffer, sizeof(buffer), fp)!= NULL) { printf("%s", buffer); } fclose(fp); return 0; }
- 以下代码实现了向一个文本文件
- 示例代码(二进制文件顺序读写):
- 假设我们有一个结构体来存储学生的信息,下面的代码将顺序地把学生信息写入二进制文件
students.bin
,然后再顺序读取并打印这些信息。
#include <stdio.h> #include <stdlib.h> struct Student { int id; char name[20]; }; int main() { FILE *fp; struct Student s1 = {1, "Alice"}; struct Student s2 = {2, "Bob"}; struct Student readStudent; // 打开文件用于写入 fp = fopen("students.bin", "wb"); if (fp == NULL) { printf("无法打开文件进行写入。\n"); return 1; } // 顺序写入学生信息 fwrite(&s1, sizeof(struct Student), 1, fp); fwrite(&s2, sizeof(struct Student), 1, fp); fclose(fp); // 打开文件用于读取 fp = fopen("students.bin", "rb"); if (fp == NULL) { printf("无法打开文件进行读取。\n"); return 1; } // 顺序读取学生信息并打印 while (fread(&readStudent, sizeof(struct Student), 1, fp) == 1) { printf("ID: %d, Name: %s\n", readStudent.id, readStudent.name); } fclose(fp); return 0; }
- 假设我们有一个结构体来存储学生的信息,下面的代码将顺序地把学生信息写入二进制文件
- 示例代码(文本文件顺序读写):
- 随机读写
- 示例代码(文本文件随机读写):
- 下面的代码实现了在文本文件
random_text.txt
中的随机读写。这里通过fseek
函数来设置文件指针的位置进行随机读写。
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp; char buffer[100]; // 打开文件用于读写 fp = fopen("random_text.txt", "w +"); if (fp == NULL) { printf("无法打开文件进行读写。\n"); return 1; } fputs("First line.\nSecond line.\nThird line.\n", fp); // 将文件指针移动到第二行开头 fseek(fp, 10, SEEK_SET); fgets(buffer, sizeof(buffer), fp); printf("读取的内容:%s", buffer); fclose(fp); return 0; }
- 下面的代码实现了在文本文件
- 示例代码(二进制文件随机读写):
- 对于二进制文件,我们也可以通过
fseek
函数来实现随机读写。下面的代码演示了在二进制文件random_bin.bin
中对结构体数据的随机读写。
#include <stdio.h> #include <stdlib.h> struct Item { int number; char description[20]; }; int main() { FILE *fp; struct Item i1 = {1, "Item 1"}; struct Item i2 = {2, "Item 2"}; struct Item readItem; // 打开文件用于读写 fp = fopen("random_bin.bin", "wb +"); if (fp == NULL) { printf("无法打开文件进行读写。\n"); return 1; } fwrite(&i1, sizeof(struct Item), 1, fp); fwrite(&i2, sizeof(struct Item), 1, fp); // 将文件指针移动到第二个结构体的位置 fseek(fp, sizeof(struct Item), SEEK_SET); fread(&readItem, sizeof(struct Item), 1, fp); printf("读取的结构体:Number: %d, Description: %s\n", readItem.number, readItem.description); fclose(fp); return 0; }
- 对于二进制文件,我们也可以通过
- 示例代码(文本文件随机读写):
在这些示例中,顺序读写是按照文件中数据存储的顺序依次进行读写操作。而随机读写则是通过fseek
函数来改变文件指针的位置,从而能够在文件的任意位置进行读写操作,提高了文件操作的灵活性。
4.标准输入和输出及其重定向
- 标准输入和输出
- 在C语言中,标准输入(
stdin
)通常是指键盘输入,标准输出(stdout
)通常是指屏幕输出。 - 示例代码(基本的标准输入输出):
- 下面的代码通过
scanf
函数从标准输入读取一个整数,然后通过printf
函数将这个整数乘以2后的结果输出到标准输出。
#include <stdio.h> int main() { int num; printf("请输入一个整数:"); scanf("%d", &num); printf("这个整数乘以2的结果是:%d\n", num * 2); return 0; }
- 下面的代码通过
- 在C语言中,标准输入(
- 输入输出重定向
- 输入输出重定向可以让程序从文件中读取输入,或者将输出写入到文件中,而不是默认的键盘和屏幕。
- 示例代码(输入重定向):
- 假设我们有一个文本文件
input.txt
,里面包含一个整数,例如5
。我们可以通过命令行将这个文件的内容作为程序的输入,而不是从键盘输入。 - 在命令行中(假设程序名为
a.out
),可以使用a.out < input.txt
这样的命令来运行程序。 - 下面是程序代码:
#include <stdio.h> int main() { int num; scanf("%d", &num); printf("从文件中读取的整数是:%d\n", num); return 0; }
- 假设我们有一个文本文件
- 示例代码(输出重定向):
- 我们可以将程序的输出写入到一个文件中。例如,将上面的程序输出重定向到
output.txt
文件中,可以在命令行中使用a.out > output.txt
来运行程序。 - 代码如下:
#include <stdio.h> int main() { int num = 10; printf("这个整数是:%d\n", num); return 0; }
- 我们可以将程序的输出写入到一个文件中。例如,将上面的程序输出重定向到
- 示例代码(同时进行输入输出重定向):
- 假设有一个程序,从一个文件
input_data.txt
读取两个整数,相加后将结果输出到output_result.txt
文件中。 - 程序代码如下:
#include <stdio.h> int main() { int num1, num2; FILE *input_file = fopen("input_data.txt", "r"); if (input_file == NULL) { printf("无法打开输入文件。\n"); return 1; } fscanf(input_file, "%d %d", &num1, &num2); fclose(input_file); int result = num1 + num2; FILE *output_file = fopen("output_result.txt", "w"); if (output_file == NULL) { printf("无法打开输出文件。\n"); return 1; } fprintf(output_file, "两个数相加的结果是:%d\n", result); fclose(output_file); return 0; }
- 在命令行中可以使用
a.out < input_data.txt > output_result.txt
来运行程序。
- 假设有一个程序,从一个文件
在这些示例中,标准输入输出是C程序最基本的输入输出方式,而输入输出重定向则提供了更灵活的方式,让程序能够更好地与文件等外部资源进行交互。
5.动画的基本原理
动画的基本原理主要基于视觉暂留和帧的连续播放。
(1)视觉暂留(Persistence of Vision)
- 定义:视觉暂留是指物体在快速运动时,当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1 - 0.4秒左右的图像。这是一种生理现象,它使得一系列快速呈现的静态图像能够在人眼中融合成一个连续的动态影像。
- 举例:例如,我们可以想象在一个黑暗的环境中,用一个手电筒快速地画圈挥动。由于视觉暂留现象,我们看到的不是手电筒在各个位置的离散光点,而是一个连续的光圈。
(2) 帧(Frame) - 定义:动画是由一系列静态的图像(帧)组成的。这些帧按照一定的顺序和速度连续播放,利用视觉暂留原理,在观众眼中形成动画效果。每一帧都是一个独立的图像,它记录了动画在某个特定时刻的状态。
- 帧速率(Frame Rate):帧速率是指每秒播放的帧数(fps - frames per second)。常见的帧速率包括24fps(电影)、25fps(PAL电视制式)、30fps(NTSC电视制式)等。较高的帧速率可以使动画看起来更加流畅,但同时也需要更多的存储空间和计算资源。例如,一部时长为1分钟的动画,如果帧速率是24fps,那么它总共就有1×60×24 = 1440帧。
- 关键帧(Key Frame)和过渡帧(Tween Frame):
- 关键帧:是动画中具有关键动作或关键状态的帧。它们定义了动画的主要变化点,比如一个角色从站立到跳跃的起始和结束姿势,这些姿势所在的帧就是关键帧。动画师通常会先绘制关键帧,来确定动画的主要节奏和动作走向。
- 过渡帧:是在关键帧之间用于填充动作过渡的帧。它们的作用是使动画的动作更加自然流畅。例如,在角色从站立姿势到跳跃姿势的两个关键帧之间,过渡帧会描绘出角色身体弯曲、腿部发力等中间状态,使整个跳跃动作连贯起来。
动画制作的过程就是利用这些基本原理,通过精心设计每一帧的内容,按照合适的帧速率进行播放,从而创造出各种生动的动画作品,如传统的手绘动画、计算机生成动画(3D动画、二维矢量动画等)。
6.迷宫游戏
一、迷宫游戏解释
迷宫游戏是一种常见的益智游戏,通常在一个二维平面上设置由墙壁和通道组成的迷宫。玩家需要从起点出发,通过寻找正确的路径,避开墙壁,最终到达终点。
二、用 C 语言实现简单迷宫游戏示例
以下是一个用 C 语言实现的简单控制台迷宫游戏示例:
#include <stdio.h>
#include <stdbool.h>
#define MAZE_WIDTH 10
#define MAZE_HEIGHT 10
char maze[MAZE_HEIGHT][MAZE_WIDTH] = {
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
{'#', ' ', ' ', '#', ' ', ' ', ' ', '#', ' ', '#'},
{'#', ' ', '#', ' ', '#', '#', ' ', '#', ' ', '#'},
{'#', ' ', '#', ' ', ' ', '#', ' ', ' ', ' ', '#'},
{'#', ' ', '#', '#', '#', '#', '#', '#', '#', '#'},
{'#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#'},
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
{'#', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '#'},
{'#', ' ', '#', '#', '#', '#', '#', '#', '#', '#'},
{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}
};
bool isValidMove(int x, int y) {
return x >= 0 && x < MAZE_HEIGHT && y >= 0 && y < MAZE_WIDTH && maze[x][y]!= '#';
}
void printMaze() {
for (int i = 0; i < MAZE_HEIGHT; i++) {
for (int j = 0; j < MAZE_WIDTH; j++) {
printf("%c", maze[i][j]);
}
printf("\n");
}
}
int main() {
int playerX = 1;
int playerY = 1;
bool foundExit = false;
while (!foundExit) {
printMaze();
char move;
printf("请输入移动方向(w-上,s-下,a-左,d-右):");
scanf(" %c", &move);
int newX = playerX;
int newY = playerY;
switch (move) {
case 'w':
newX--;
break;
case 's':
newX++;
break;
case 'a':
newY--;
break;
case 'd':
newY++;
break;
default:
printf("无效输入!\n");
continue;
}
if (isValidMove(newX, newY)) {
playerX = newX;
playerY = newY;
if (maze[playerX][playerY] == 'E') {
foundExit = true;
}
} else {
printf("此路不通!\n");
}
}
printf("恭喜你找到出口!\n");
return 0;
}
在这个例子中:
- 定义了一个二维字符数组来表示迷宫,
'#'
表示墙壁,' '
表示通道,'E'
表示迷宫的出口。 isValidMove
函数用于检查给定的坐标是否是合法的移动位置(即不是墙壁)。printMaze
函数用于在控制台打印迷宫。- 在
main
函数中,通过循环不断接收用户输入的移动方向,然后根据输入更新玩家的位置,直到玩家找到出口。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理