目录

一、stdin、stdout 和 stderr 详解

二、文件打开方式

三、C语言文件操作函数详解

1、文件操作概述

2、文件操作函数分类表

1. 文件打开与关闭

2. 字符读写函数

3. 字符串读写函数

4. 格式化读写函数

5. 二进制读写函数

6. 文件定位函数

7. 文件状态与错误检测

8. 其他文件操作函数

3、注意事项

4、对文件进行写入操作示例

5、对文件进行读取操作示例

6、另一个读文件的例子

代码功能

代码结构分析

1. 代码功能

2. 代码解析

(1) 参数检查

(2) 打开文件

(3) 读取文件内容

(4) 关闭文件

3. 关键点分析

(1) fread 的返回值

(2) buf[s] = '\0' 的作用

(3) 循环终止条件

四、输出信息到显示器的常用方法

1、代码功能

2、代码解析

(1) fwrite 方式

(2) printf 方式

(3) fprintf 方式

3、输出结果

4、关键区别

5、使用场景建议

6. 扩展:puts 和 fputs

7. 总结

五、 什么是当前路径?

命令解析:ps -axj | head -1 && ps -axj | grep demol | grep -v grep

组合效果:


一、stdin、stdout 和 stderr 详解

        在Linux系统中,"一切皆文件"的理念意味着所有设备都可以被视为文件进行操作。显示器作为输出设备被抽象为文件,通过写入数据实现内容显示;键盘作为输入设备同样被抽象为文件,系统通过读取该文件获取用户输入的字符。

        这些特殊设备文件之所以不需要手动打开,是因为每个进程在创建时都会自动打开三个标准I/O流:

  1. 标准输入(stdin) - 对应键盘设备
  2. 标准输出(stdout) - 对应显示器设备
  3. 标准错误(stderr) - 同样对应显示器设备

        根据man手册的说明,这三个标准流在C语言中都是以FILE*指针形式存在的,与 fopen 返回的文件指针类型相同。这种设计使得进程可以直接使用这些预打开的文件描述符进行基本输入输出操作,无需额外的打开步骤。

        当运行C程序时,操作系统会自动使用C语言接口打开这三个标准输入输出流,这样我们才能调用scanf和printf等函数进行键盘输入和屏幕输出。

        实际上,stdin、stdout和stderr与通过fopen获取的文件指针本质相同。例如使用fputs函数时,若将第二个参数设为stdout,函数就会直接将数据输出到显示器上。

#include <stdio.h>
int main()
{fputs("hello stdin\n", stdout);fputs("hello stdout\n", stdout);fputs("hello stderr\n", stdout);return 0;
}

此时我们相当于使用fputs函数向“显示器文件”写入数据,也就是显示到显示器上: 

        需要注意的是,标准输入流、标准输出流和标准错误流并非C语言独有的概念。在C++中对应的是cin、cout和cerr,几乎所有编程语言都具备类似的设计。实际上,这些特性并非源于特定编程语言,而是由操作系统底层提供的基础支持。


二、文件打开方式

文件操作模式说明:

  • r:以只读方式打开文本文件。文件指针位于文件开头。
  • r+:以读写方式打开文件。文件指针位于文件开头。
  • w:以写入方式打开文件。若文件存在则清空内容,不存在则创建新文件。文件指针位于文件开头。
  • w+:以读写方式打开文件。若文件不存在则创建,存在则清空内容。文件指针位于文件开头。
  • a:以追加方式打开文件(写入内容到文件末尾)。若文件不存在则创建。文件指针位于文件末尾。
  • a+:以读写和追加方式打开文件。若文件不存在则创建。读取时文件指针位于开头,写入时始终追加到末尾。

我将会在另一篇博客中详细验证上面的每一种文件打开模式,挺多内容的其实!!!


三、C语言文件操作函数详解

1、文件操作概述

        在C语言中,文件操作主要通过标准库中的文件I/O函数实现。这些函数定义在<stdio.h>头文件中。文件操作通常包括打开、读写、定位和关闭等基本操作。

2、文件操作函数分类表

1. 文件打开与关闭

函数原型功能描述参数说明返回值示例
FILE *fopen(const char *filename, const char *mode);打开文件filename: 文件名
mode: 打开模式
成功: 返回FILE指针
失败: 返回NULL
FILE *fp = fopen("test.txt", "r");
int fclose(FILE *stream);关闭文件stream: 文件指针成功: 返回0
失败: 返回EOF
fclose(fp);

文件打开模式:(同第六点)

  • "r": 只读

  • "w": 只写(创建新文件或清空已有文件)

  • "a": 追加

  • "r+": 读写(文件必须存在)

  • "w+": 读写(创建新文件或清空已有文件)

  • "a+": 读写(追加)

2. 字符读写函数

函数原型功能描述参数说明返回值示例
int fgetc(FILE *stream);从文件读取一个字符stream: 文件指针成功: 返回读取的字符
失败/EOF: 返回EOF
char c = fgetc(fp);
int fputc(int c, FILE *stream);向文件写入一个字符c: 要写入的字符
stream: 文件指针
成功: 返回写入的字符
失败: 返回EOF
fputc('A', fp);
int getc(FILE *stream);同fgetc,但可能实现为宏同fgetc同fgetcchar c = getc(fp);
int putc(int c, FILE *stream);同fputc,但可能实现为宏同fputc同fputcputc('B', fp);

3. 字符串读写函数

函数原型功能描述参数说明返回值示例
char *fgets(char *s, int size, FILE *stream);从文件读取一行s: 存储缓冲区
size: 缓冲区大小
stream: 文件指针
成功: 返回s
失败/EOF: 返回NULL
fgets(buf, 100, fp);
int fputs(const char *s, FILE *stream);向文件写入字符串s: 要写入的字符串
stream: 文件指针
成功: 返回非负值
失败: 返回EOF
fputs("Hello", fp);

4. 格式化读写函数

函数原型功能描述参数说明返回值示例
int fprintf(FILE *stream, const char *format, ...);格式化输出到文件stream: 文件指针
format: 格式字符串
...: 可变参数
成功: 返回写入字符数
失败: 返回负值
fprintf(fp, "%d %f", i, f);
int fscanf(FILE *stream, const char *format, ...);从文件格式化输入stream: 文件指针
format: 格式字符串
...: 可变参数
成功: 返回匹配项数
失败/EOF: 返回EOF
fscanf(fp, "%d %f", &i, &f);

5. 二进制读写函数

函数原型功能描述参数说明返回值示例
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);从文件读取二进制数据ptr: 数据存储位置
size: 每个元素大小
nmemb: 元素数量
stream: 文件指针
返回成功读取的元素数fread(&data, sizeof(data), 1, fp);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);向文件写入二进制数据ptr: 要写入的数据
size: 每个元素大小
nmemb: 元素数量
stream: 文件指针
返回成功写入的元素数fwrite(&data, sizeof(data), 1, fp);

6. 文件定位函数

函数原型功能描述参数说明返回值示例
int fseek(FILE *stream, long offset, int whence);移动文件位置指针stream: 文件指针
offset: 偏移量
whence: 起始位置(SEEK_SET/SEEK_CUR/SEEK_END)
成功: 返回0
失败: 返回非0
fseek(fp, 0, SEEK_END);
long ftell(FILE *stream);获取文件当前位置stream: 文件指针成功: 返回当前位置
失败: 返回-1L
long pos = ftell(fp);
void rewind(FILE *stream);重置文件位置到开头stream: 文件指针rewind(fp);
int fgetpos(FILE *stream, fpos_t *pos);获取文件位置stream: 文件指针
pos: 存储位置
成功: 返回0
失败: 返回非0
fgetpos(fp, &pos);
int fsetpos(FILE *stream, const fpos_t *pos);设置文件位置stream: 文件指针
pos: 要设置的位置
成功: 返回0
失败: 返回非0
fsetpos(fp, &pos);

7. 文件状态与错误检测

函数原型功能描述参数说明返回值示例
int feof(FILE *stream);检测文件结束标志stream: 文件指针到达文件尾: 返回非0
否则: 返回0
while(!feof(fp)) {...}
int ferror(FILE *stream);检测文件错误stream: 文件指针发生错误: 返回非0
否则: 返回0
if(ferror(fp)) {...}
void clearerr(FILE *stream);清除错误标志stream: 文件指针clearerr(fp);

8. 其他文件操作函数

函数原型功能描述参数说明返回值示例
int remove(const char *filename);删除文件filename: 文件名成功: 返回0
失败: 返回-1
remove("temp.txt");
int rename(const char *old, const char *new);重命名文件old: 原文件名
new: 新文件名
成功: 返回0
失败: 返回-1
rename("old.txt", "new.txt");
FILE *tmpfile(void);创建临时文件成功: 返回FILE指针
失败: 返回NULL
FILE *tmp = tmpfile();
char *tmpnam(char *s);生成唯一文件名s: 存储缓冲区(可为NULL)返回指向文件名的指针char name[L_tmpnam]; tmpnam(name);

3、注意事项

  1. 使用文件操作函数时,应始终检查返回值以确保操作成功

  2. 打开文件后,必须记得关闭文件(重要!!!)

  3. 二进制模式和文本模式在Windows平台上有区别(换行符处理不同)

  4. 文件指针位置会影响读写操作的结果

  5. 缓冲区内容在文件关闭或调用fflush()之前可能不会实际写入磁盘

4、对文件进行写入操作示例

#include <stdio.h>
int main()
{FILE* fp = fopen("log.txt", "w");if (fp == NULL){perror("fopen");return 1;}int count = 5;while (count){fputs("hello world\n", fp);count--;}fclose(fp);return 0;
}

编译并运行程序后,在当前路径下就会生成对应文件,文件当中就是我们写入的内容:

5、对文件进行读取操作示例

#include <stdio.h>
int main()
{FILE* fp = fopen("log.txt", "r");if (fp == NULL){perror("fopen");return 1;}char buffer[64];for (int i = 0; i < 5; i++){fgets(buffer, sizeof(buffer), fp);printf("%s", buffer);}fclose(fp);return 0;
}

编译并运行程序后,就会将我们刚才写入文件的内容读取出来,并打印在显示器上:

6、另一个读文件的例子

#include <stdio.h>
#include <string.h>int main() {FILE *fp = fopen("myfile", "r");if(!fp) {printf("fopen error!\n");return 1;}char buf[1024];const char *msg = "hello bit!\n";while(1) {ssize_t s = fread(buf, 1, strlen(msg), fp);if(s > 0) {buf[s] = '\0';printf("%s", buf);}if(feof(fp)) {break;}}fclose(fp);return 0;
}

代码功能

  1. 打开名为"myfile"的文件用于读取

  2. 如果文件打开失败,打印错误信息并退出

  3. 每次读取与字符串"hello bit!\n"长度相同的数据块(11字节)

  4. 将读取的内容打印到标准输出

  5. 遇到文件结尾时停止读取

  6. 关闭文件并退出

代码结构分析

  1. 文件打开部分

    FILE *fp = fopen("myfile", "r");
    if(!fp) {printf("fopen error!\n");return 1;
    }
    • 尝试以只读模式打开"myfile"文件

    • 如果打开失败(fp为NULL),打印错误信息并返回1

  2. 变量定义

    char buf[1024];
    const char *msg = "hello bit!\n";
    • buf是1024字节的缓冲区

    • msg是字符串常量"hello bit!\n",用于确定每次读取的长度

  3. 读取循环

    while(1) {ssize_t s = fread(buf, 1, strlen(msg), fp);if(s > 0) {buf[s] = '\0';printf("%s", buf);}if(feof(fp)) {break;}
    }
    • 无限循环读取文件内容

    • 每次读取strlen(msg)(11)个字节到buf

    • 如果读取到数据(s>0),在末尾添加'\0'使其成为字符串并打印

    • 检查文件结束标志,如果到达文件末尾则退出循环

  4. 清理部分

    fclose(fp);
    return 0;
    • 关闭文件

    • 程序正常退出

编译并运行输出的结果:

稍作修改,实现简单cat命令:

#include <stdio.h>
#include <string.h>int main(int argc, char* argv[]) {if (argc != 2) {printf("Usage: %s <filename>\n", argv[0]);return 1;}FILE *fp = fopen(argv[1], "r");if(!fp) {printf("fopen error!\n");return 2;}char buf[1024];while(1) {int s = fread(buf, 1, sizeof(buf), fp);if(s > 0) {buf[s] = '\0';printf("%s", buf);}if(feof(fp)) {break;}}fclose(fp);return 0;
}

1. 代码功能

  • 从命令行接收一个文件名,并尝试打开该文件。

  • 逐块读取文件内容(每次最多 1024 字节),并打印到标准输出(stdout)。

  • 检测文件结束(EOF),并在读取完成后关闭文件。

2. 代码解析

(1) 参数检查

if (argc != 2) {printf("Usage: %s <filename>\n", argv[0]);return 1;
}
  • argc 表示命令行参数的个数,argv[0] 是程序名,argv[1] 是传入的文件名。

  • 如果用户未提供文件名(argc != 2),打印用法提示并返回 1(表示错误)。

(2) 打开文件

FILE *fp = fopen(argv[1], "r");
if(!fp) {printf("fopen error!\n");return 2;
}
  • 尝试以 只读模式("r" 打开文件 argv[1]

  • 如果打开失败(fp == NULL),打印错误信息并返回 2

(3) 读取文件内容

char buf[1024];
while(1) {int s = fread(buf, 1, sizeof(buf), fp);if(s > 0) {buf[s] = '\0';  // 添加字符串结束符printf("%s", buf);}if(feof(fp)) {break;}
}
  • fread 读取数据

    • buf:存储数据的缓冲区。

    • 1:每个元素的大小(字节)。

    • sizeof(buf):每次最多读取 1024 字节。

    • fp:文件指针。

    • 返回值 s:实际读取的字节数(可能小于 1024)。

  • printf 打印数据

    • buf[s] = '\0':确保 buf 是一个合法的 C 字符串(printf 需要 \0 结尾)。

    • printf("%s", buf):打印读取的内容。

  • feof(fp) 检测文件结束

    • 如果 fread 返回 0 且 feof(fp) 为真,说明文件已经读完,退出循环。

(4) 关闭文件

fclose(fp);
return 0;
  • 关闭文件,防止资源泄漏。

  • 返回 0 表示程序正常结束。

3. 关键点分析

(1) fread 的返回值

  • s > 0:成功读取数据,存入 buf 并打印。

  • s == 0

    • 如果 feof(fp) 为 true,说明文件已读完,正常结束。

    • 如果 feof(fp) 为 false,可能是 读取错误(但代码未处理)。

(2) buf[s] = '\0' 的作用

  • fread 不会自动添加 '\0',但 printf("%s", buf) 需要 '\0' 作为字符串结束符。

  • 如果文件是 二进制数据,可能会因为 '\0' 导致 printf 提前终止输出。

(3) 循环终止条件

  • feof(fp) 为 true:文件读完,正常退出。

  • 如果 fread 返回 0 但 feof(fp) 仍为 false

    • 可能是 读取错误(如文件损坏)。

    • 当前代码 不会检测这种情况,可能导致 无限循环

编译并运行输出结果:


四、输出信息到显示器的常用方法

#include <stdio.h>
#include <string.h>int main() {const char *msg = "hello fwrite\n";fwrite(msg, strlen(msg), 1, stdout);printf("hello printf\n");fprintf(stdout, "hello fprintf\n");return 0;
}

1、代码功能

  • 使用 fwrite 直接写入二进制数据。

  • 使用 printf 格式化输出字符串。

  • 使用 fprintf 向指定流(这里是 stdout)输出格式化字符串。

2、代码解析

(1) fwrite 方式

const char *msg = "hello fwrite\n";
fwrite(msg, strlen(msg), 1, stdout);
  • fwrite 是 二进制写入函数,适用于任何数据(包括字符串、二进制数据等)。

  • 参数解析

    • msg:要写入的数据("hello fwrite\n")。

    • strlen(msg):写入的 每个元素的大小(这里是字符串长度,不包括 '\0')。

    • 1:写入的元素个数(这里是 1 个字符串)。

    • stdout:输出流(标准输出)。

  • 特点

    • 不会自动添加 '\0',因为它 不关心数据内容,只是按字节写入。

    • 适合 二进制写入(如文件 I/O),但也可以用于字符串。

(2) printf 方式

printf("hello printf\n");
  • printf 是 格式化输出函数,默认输出到 stdout

  • 特点

    • 自动处理 '\0' 结尾,适合 文本输出

    • 支持格式化字符串(如 %d%s 等)。

(3) fprintf 方式

fprintf(stdout, "hello fprintf\n");
  • fprintf 是 指定流的格式化输出,可以输出到任意文件流(如 stdout、文件等)。

  • 参数解析

    • stdout:指定输出流(这里仍然是标准输出)。

    • "hello fprintf\n":要输出的字符串。

  • 特点

    • 和 printf 类似,但可以指定输出目标(如文件、标准错误 stderr 等)。

    • 适合需要 灵活控制输出目标 的场景。

3、输出结果

编译并运行程序后,输出如下:

  • fwrite 和 printf/fprintf 都能正确输出字符串。

  • 但它们的 底层机制不同

    • fwrite 是 二进制写入,不关心字符串格式。

    • printf 和 fprintf 是 格式化输出,更适合文本。

4、关键区别

函数类型是否处理 '\0'适用场景示例
fwrite二进制写入❌ 不处理文件 I/O、二进制数据fwrite(data, 1, size, fp);
printf格式化输出✅ 自动处理标准输出、格式化文本printf("num=%d", 123);
fprintf流格式化输出✅ 自动处理任意流(文件、stdoutstderrfprintf(stderr, "Error: %s", errmsg);

5、使用场景建议

  1. 如果要写入字符串到 stdout,优先用 printf 或 fprintf

    • 它们会自动处理 '\0',更安全。

    • 支持格式化(如 %d%f)。

  2. 如果要写入二进制数据(如图片、结构体),用 fwrite:它不会修改数据,适合原始字节流。

  3. 如果要输出到文件或 stderr,用 fprintf:可以灵活指定输出目标。

6. 扩展:puts 和 fputs

如果只是简单输出字符串,还可以用:

puts("hello puts");       // 自动加换行
fputs("hello fputs", stdout);  // 不加换行
  • puts 会自动在末尾加 '\n',而 fputs 不会。

7. 总结

  • fwrite:底层二进制写入,适合非文本数据。

  • printf:标准格式化输出,默认到 stdout

  • fprintf:可指定输出流的格式化写入(如文件、stderr)。

  • puts/fputs:更简单的字符串输出方式。

这段代码展示了三种不同的输出方式,实际使用时可以根据需求选择最合适的函数。 


五、 什么是当前路径?

        当使用fopen以写入模式打开文件时,若文件不存在,系统会在当前工作目录自动创建该文件。这里的"当前路径"具体指程序运行时的工作目录。

        例如上面的例子中,在当前工作目录(~目录)下运行可执行程序demo1时,程序创建的log.txt文件默认会生成在~目录中:

        我们可以理解为:"当前路径"指的是可执行程序运行时所在的路径。为了验证这一点,我们可以进行以下测试:

  1. 首先删除之前生成的log.txt文件
  2. 在当前工作目录中,创建一个新目录,将可执行程序demo1拷贝到这个新目录中
  3. cd到这个新目录中重新运行该程序,观察log.txt生成在哪里

        运行该可执行程序后,我们发现log.txt文件并未在~目录下生成,而是出现在当前工作目录newdir中!!!这与结论相符!!!

        当程序运行成为进程后,我们可以通过获取其PID来查看相关信息。该进程的详细信息存储在根目录下的proc目录中,可通过对应PID进行访问。

        为了可以查看相关信息,我们把demo1.c改为每写入一句字符串就休眠5秒,不至于查看信息的时候看不到现象:

#include <stdio.h>
#include <unistd.h>int main()
{FILE* fp = fopen("log.txt", "w");if (fp == NULL){perror("fopen");return 1;}int count = 5;while (count){fputs("hello world\n", fp);sleep(5);count--;}fclose(fp);return 0;
}

命令解析:ps -axj | head -1 && ps -axj | grep demol | grep -v grep

  1. ps -axj | head -1

    • ps -axj:显示所有用户的进程(a),包括无控制终端的进程(x),并以作业格式(j)显示

    • head -1:只保留第一行输出(即列标题)

    • 这部分的作用是显示进程列表的标题行

  2. ps -axj | grep demo1 | grep -v grep

    • ps -axj:同上,获取所有进程的完整列表

    • grep demo1:过滤出包含"demo1"的行

    • grep -v grep:排除掉grep自身的进程(因为grep命令本身也会出现在进程列表中)

组合效果:

  • 先显示进程列表的标题行

  • 然后显示所有包含"demo1"的进程信息(不包括grep自身的进程)

其中:

  • cwd:指向当前进程运行目录的符号链接
  • exe:指向启动当前进程的可执行文件(含完整路径)的符号链接

        当打开文件时,实际上是进程在执行文件的操作。由于进程知道自身所在位置,即便文件不带路径信息,进程也能准确定位。因此,操作系统能够明确新创建文件的存储位置。

        需要强调的是,这里所说的"当前路径"并非指可执行程序的存储位置,而是指程序运行成为进程时所在的工作目录路径。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89429.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89429.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/89429.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【自用】JavaSE--集合框架(一)--Collection集合体系

概述之前学的ArrayList就是集合的一种&#xff0c;是一种容器&#xff0c;可以往里面存东西&#xff0c;大小可变Collection集合体系Collection的常用方法以后Collection体系的集合都可以用下图的方法注意toArray方法的数组类型是Object&#xff0c;这样就可以接收任意类型的数…

电脑视频常用几种接口

传输信号类型 DP&#xff08;DisplayPort&#xff09;主要用于传输数字视频和音频信号&#xff0c;支持高分辨率和高刷新率。HDMI&#xff08;High-Definition Multimedia Interface&#xff09;同样传输数字音视频信号&#xff0c;但更偏向消费电子领域&#xff0c;如电视、游…

CherryStudio+playwright-mcp-server实现AI自动化

目录 1、CherryStudio安装与配置 1.1什么是CherryStudio 1.2安装 1.3配置 2、playwright-mcp-server的安装与配置 3、执行测试与结果 1、CherryStudio安装与配置 1.1什么是CherryStudio Cherry Studio 是一款集多模型对话、知识库管理、AI 绘画、翻译等功能于一体的全能 …

深入了解 find_element 方法:Web 自动化定位元素的核心​

在 Web 自动化测试领域&#xff0c;元素定位是实现各类操作的基础&#xff0c;而find_element方法正是 Selenium 等自动化工具中用于定位单个元素的核心方法。掌握它的使用技巧&#xff0c;能让我们更精准、高效地操控网页元素&#xff0c;为自动化测试脚本的编写打下坚实基础。…

从零开始的云计算生活——第三十三天,关山阻隔,ELK日志分析

目录 一.故事背景 二、Elasticsearch 全面概述 1、核心定位 2、核心特性 a. 分布式架构 b. 高性能原理 c. 数据模型创新 3、核心技术组件 4、核心应用场景 a. 企业级搜索 b. 可观测性 c. 安全分析&#xff08;SIEM&#xff09; 5、版本演进关键特性 6、核心优势…

深入理解 Spring Boot Starter 的生成机制

在使用 Spring Boot 进行开发时&#xff0c;我们常常会引入诸如 spring-boot-starter-web、spring-boot-starter-data-jpa 等依赖&#xff0c;从而快速开启相关功能模块。但你是否思考过这些 Starter 是如何构建的&#xff1f;如果我们要开发自己的 Starter&#xff0c;又该如何…

阿里云-通义灵码:隐私保护机制—为数据安全筑起铜墙铁壁

免责声明&#xff1a;此篇文章所有内容皆是本人实验&#xff0c;并非广告推广&#xff0c;并非抄袭&#xff0c;该系列继续~每日一句不要感叹自己的平凡&#xff0c;即便是最暗的星星&#xff0c;相与无边的黑暗已是耀眼。一.引言在这个数据如同空气般渗透到生活每个角落的时代…

最小生成树算法详解

最小生成树算法详解一、最小生成树基础概念1.1 生成树与最小生成树1.2 核心性质1.3 应用场景二、Prim 算法&#xff1a;从顶点出发的“生长式”构建2.1 算法原理2.2 Java 代码实现&#xff08;邻接矩阵版&#xff09;2.3 复杂度分析三、Kruskal 算法&#xff1a;按边权排序的“…

YOLO 目标检测的改进方法

YOLO目标检测的改进方法可以从模型架构、训练策略、损失函数等多个方面入手&#xff0c;以下是一些常见的改进方法方向及参考文献&#xff1a; 模型架构改进 骨干网络替换&#xff1a;使用更轻量或更强大的网络替换原始骨干网络。轻量级网络如MobileNetV3、ShuffleNetV2等适合…

C++ 程序 AddressSanitizer:DEADLYSIGNAL

GCC && G 操作系统&#xff1a;Ubuntu 22.04 现象&#xff1a;C程序编译时开启ASAN&#xff0c;运行时有几率会出现大量AddressSanitizer:DEADLYSIGNAL 参考文章&#xff1a; https://stackoverflow.com/questions/77894856/possible-bug-in-gcc-sanitizers https://st…

【强化学习】实际部署

环境 Gymnasium 作为环境接口&#xff0c; PyBullet作为物理仿真平台&#xff0c; Stable Baselines3 用于训练算法。 测试框架搭建 以pybullet自带的Cart-pole-v1为例 安装依赖&#xff1a;确保安装了 Gymnasium 和 SB3 ( pip install gymnasium stable-baselines3 ).初始化环…

集训Demo4

创建数据库创建项目基本和视频中的一样我给User添加了vip这个属性&#xff0c;想实现两个令牌通过访问的案例&#xff0c;但遇到了问题一个令牌是密码加用户名的map数组这是它的获取、验证逻辑获取验证另一个令牌是Int vip这是自己写的另一套密钥和方法获取但在验证这里有问题头…

深度优化:Java 慢查询排查与性能调优实战

文章目录&#x1f680; 深度优化&#xff1a;Java 慢查询排查与性能调优实战&#x1f6a8;1. 事故全景&#xff1a;从告警到定位&#x1f575;️‍♂️1.1 事故时间线&#x1f4ca; 1.2 关键指标异常&#x1f6e0;️ 1.3 排查工具链&#x1f50d; 2. 深度剖析&#xff1a;MySQL…

TF-IDF(Term Frequency - Inverse Document Frequency)

TF-IDF&#xff08;Term Frequency - Inverse Document Frequency&#xff09;是一种在信息检索与文本挖掘中非常常用的关键词提取方法&#xff0c;用于衡量一个词在文档集合中的重要性。它的核心思想是&#xff1a;如果一个词在某个文档中出现得频繁&#xff0c;同时在其他文档…

Chrome紧急更新,谷歌修复正遭活跃利用的关键零日漏洞

谷歌已针对桌面版Chrome发布重要稳定渠道更新&#xff08;版本138.0.7204.157/.158&#xff09;&#xff0c;修复了六个安全漏洞&#xff0c;其中包括一个已被实际利用的漏洞。该更新正在向Windows、Mac和Linux平台推送&#xff0c;预计未来数日或数周内将通过自动更新完成部署…

Typecho插件开发:实现文章字数统计与阅读时长计算功能

文章目录 Typecho文章字数统计与阅读时长计算功能实现指南 1. 功能背景与需求分析 2. 插件设计与实现 2.1 插件基础结构 2.2 插件主逻辑实现 2.3 代码解析与优化 3. 前端展示优化 3.1 CSS样式增强 3.2 多语言支持 4. 高级功能扩展 4.1 数据库表优化 4.2 定时批量处理历史文章 5…

开源短链接工具 Sink 无需服务器 轻松部署到 Workers / Pages

本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 Sink 是一款开源免费的短链接生成工具,支持自定义短链接 Slug 以及设置到期时间,并且还可以借助 Cloudflare 的 Analytics Engine 功能分析短链接的统计数据。 最重要的是实现以上这些功能并不需要有自己的服务器,…

嵌入式数据结构之顺序表总结

以下是为嵌入式面试准备的顺序表全面优化指南&#xff0c;结合高频考点、代码规范与嵌入式专项优化技巧&#xff0c;助你系统掌握该知识点。 一、顺序表基础与嵌入式特点 ​本质​ 用连续内存空间存储线性表元素&#xff0c;通过下标实现O(1)随机访问 。 ​嵌入式优势​&#x…

Pytorch下载Mnist手写数据识别训练数据集的代码详解

datasets.MNIST(root./data, trainFalse, downloadTrue, transformtransforms.ToTensor())1. datasets.MNIST这是torchvision.datasets模块中的一个类&#xff0c;专门用于加载MNIST数据集。MNIST是一个著名的手写数字识别数据集&#xff0c;包含60,000个训练样本和10,000个测试…

汽车免拆诊断案例 | 07款丰田Hilux启动故障

故障现象一辆 2007 年的丰田Hilux 2.5L柴油手动挡&#xff0c;行驶里程为23万公里。车主说车辆有很多故障&#xff0c;包括故障灯闪烁、发动机启动后又熄火、短时间运行时发动机还会剧烈抖动异响&#xff0c;从排气管冒出大量烟雾。故障诊断接车之后进行检查&#xff0c;发现发…