【Linux系统】基础IO(上)

1. 深入理解"文件"概念

1.1 文件的狭义理解

狭义上的“文件”主要指存储在磁盘上的数据集合。具体包括:

  • 文件在磁盘里:文件是磁盘上以特定结构(如FAT、ext4文件系统)保存的数据集合,由字节或字符序列构成。磁盘作为永久性存储介质,即使断电后数据也不会丢失,因此文件的存储是永久性的。
  • 磁盘是外设(输入输出设备) :磁盘被归类为外部设备,既是输入设备(如读取数据)也是输出设备(如写入数据)。因此,所有对文件的操作(如打开、读取、写入)本质上都是对外设的输入和输出,简称IO(Input/Output)。
  • IO的本质:文件操作如读写磁盘数据,不是直接在应用程序中完成,而是通过底层硬件交互实现的IO过程。例如,C语言的fopenfwrite函数最终会转化为对外设的输入输出请求。

磁盘作为计算机外设的一种,既是输入设备(读取数据)也是输出设备(写入数据)。例如:

  • 当保存文档时:数据从内存输出到磁盘
  • 当打开文档时:数据从磁盘输入到内存

所有对磁盘文件的操作(创建、读取、修改、删除)本质上都是通过操作系统提供的输入输出(IO)接口完成的。

总结:狭义文件强调磁盘存储的永久性和硬件交互的IO本质,所有操作都围绕外设进行。

1.2 文件的广义理解

在Linux/Unix操作系统中,有一个重要的设计理念:"一切皆文件"。这意味着:

硬件设备抽象为文件

  • 键盘 → /dev/input/
  • 显示器 → /dev/tty
  • 磁盘 → /dev/sda
  • 网卡 → /dev/net

特殊文件类型

  • 块设备文件(如磁盘)
  • 字符设备文件(如终端)
  • 命名管道(FIFO)
  • 套接字(Socket)

例如,在Linux中:

  • 向/dev/null写入数据会直接被丢弃
  • 从/dev/random读取会获取随机数
  • 通过/proc文件系统可以查看和修改内核参数

这种抽象极大简化了系统编程接口,开发者可以使用统一的文件操作API来访问各种资源。

1.3 文件操作的分类认知

文件存储的实质

即使是0KB的空文件也会占用磁盘空间,原因包括:

文件元数据存储:每个文件都需要存储文件名、创建时间、权限等属性信息

文件系统开销:大多数文件系统有最小分配单元(如4KB的块大小)

目录条目:文件名需要在父目录中建立对应的条目

文件的组成结构

文件由两个主要部分组成:

  1. 文件属性(元数据)

    • 文件名
    • 文件大小
    • 创建/修改/访问时间
    • 所有者/权限信息
    • 存储位置等
  2. 文件内容

    • 实际存储的用户数据
    • 可以是文本、二进制、多媒体等各种形式

例如,使用ls -l命令可以查看文件的元数据,使用cat命令可以查看文件内容。

文件操作的本质

所有文件操作都可以归类为:

内容操作

  • 读取(read)
  • 写入(write)
  • 追加(append)
  • 截断(truncate)

属性操作

  • 重命名(rename)
  • 修改权限(chmod)
  • 更改所有者(chown)
  • 设置时间戳(touch)

1.4 系统层面的文件操作

进程与文件的关系

在操作系统中:

• 文件操作的主体是进程

• 每个进程维护一个文件描述符表

• 通过文件描述符来引用打开的文件

例如:

  • 标准输入(stdin) → 文件描述符0
  • 标准输出(stdout) → 文件描述符1
  • 标准错误(stderr) → 文件描述符2

对文件的操作本质是进程对文件的操作:文件操作由运行中的进程发起,进程通过系统调用请求操作系统执行文件任务(如打开、读写)。磁盘作为硬件资源,由操作系统统一管理,进程不能直接访问磁盘。

操作系统的管理角色

操作系统作为磁盘的管理者,负责:

• 文件系统的实现(如ext4, NTFS)

• 磁盘空间分配与管理

• 文件缓存与IO调度

• 权限控制与安全机制

磁盘的管理者是操作系统:操作系统(如Linux内核)负责磁盘的底层管理,包括文件系统组织、数据存储和安全控制。用户程序不能绕过操作系统直接操作磁盘。

系统调用与库函数

文件操作的实际执行路径:

  1. 用户程序调用库函数(如fopen/fread)
  2. 库函数封装系统调用(如open/read)
  3. 系统调用触发内核文件系统例程
  4. 内核与磁盘控制器交互完成IO

例如,C语言的fopen函数底层会调用open系统调用,fread会调用read系统调用。这些系统调用才是真正与操作系统内核交互的接口。

文件读写通过系统调用接口实现:C语言或C++的库函数(如fopenfprintf)只是用户层封装,提供便利性;底层实现依赖于文件相关的系统调用接口(如open打开文件、read读取数据、write写入数据)。这些系统调用涉及模式切换(用户态到内核态),确保操作安全和高效。所有语言(包括C)的文件操作最终都调用系统调用,因为硬件访问必须通过操作系统。


2. C语言文件操作接口回顾

1. 文件打开与关闭

fopen() - 打开文件

  • 功能:打开指定路径的文件,返回文件指针(FILE*)。
  • 参数
    • filename:文件路径(绝对或相对路径)。
    • mode:打开模式(如 "r" 只读、"w" 只写、"a" 追加等)。
  • 返回值:成功返回文件指针,失败返回 NULL

fclose()- 文件关闭

  • 功能:关闭已打开的文件流,释放资源。
  • 参数FILE* 文件指针。
  • 返回值:成功返回 0,失败返回 EOF(-1)。
#include <stdio.h>int main() {// 参数1: 文件名,参数2: 模式("r"读/"w"写/"a"追加)FILE *fp = fopen("example.txt", "r"); if (fp == NULL) {  // 检查是否成功打开printf("文件打开失败\n");return 1;}printf("文件打开成功\n");fclose(fp);  // 关闭文件return 0;
}

2. 字符读写

fgetc() / getc() - 读取单个字符

  • 功能:从文件读取单个字符。
  • 参数FILE* stream
  • 返回值:成功返回读取的字符(转为 int),文件结束或失败返回 EOF

示例代码

FILE *fp = fopen("file.txt", "r");
if (fp) {char c = fgetc(fp);  // 从文件读取一个字符while (c != EOF) {   // EOF 表示文件结束printf("%c", c);c = fgetc(fp);   // 继续读取下一个字符}fclose(fp);
}
  • 注释
    • fgetc 和 getc 功能相同,但 getc 可能被实现为宏。
    • 返回值是 int 类型(可容纳 EOF)。

fputc() / putc() - 写入单个字符

  • 功能:向文件写入单个字符。
  • 参数
    • char c:待写入字符。
    • FILE* stream:文件指针。
  • 返回值:成功返回写入的字符,失败返回 EOF
FILE *fp = fopen("output.txt", "w");
if (fp) {fputc('A', fp);  // 写入字符 'A'fclose(fp);
}

3. 字符串读写

fgets() - 读取一行字符串

  • 功能:从文件读取一行字符串。
  • 参数
    • char* str:存储读取数据的缓冲区。
    • int n:最大读取长度(含结尾 \0)。
    • FILE* stream
  • 返回值:成功返回 str,失败或文件结束返回 NULL
FILE *fp = fopen("data.txt", "r");
char buf[1024];
if (fp) {// 读取一行(最多 sizeof(buf)-1 个字符)while (fgets(buf, sizeof(buf), fp) != NULL) {printf("%s", buf);}fclose(fp);
}
  • 注释
    • 读取到换行符或缓冲区满时停止,末尾自动加 \0
    • 需配合 feof() 或 ferror() 检查结束/错误。

fputs() - 写入字符串

  • 功能:向文件写入字符串(不含自动换行)。
  • 参数
    • const char* str:字符串指针。
    • FILE* stream
FILE *fp = fopen("log.txt", "a");
if (fp) {fputs("Hello, World!\n", fp);  // 写入字符串(不自动加换行)fclose(fp);
}
  • 注释
    • 成功返回非负整数,失败返回 EOF

4. 格式化读写

fprintf() - 格式化写入

  • 功能:按指定格式向文件写入数据。
  • 参数:与 printf() 类似,增加文件指针参数。
FILE *fp = fopen("report.txt", "w");
if (fp) {int num = 100;fprintf(fp, "数值: %d\n", num);  // 类似 printf,但输出到文件fclose(fp);
}

fscanf() - 格式化读取

  • 功能:按指定格式从文件读取数据。
  • 参数:与 scanf() 类似,增加文件指针参数。
FILE *fp = fopen("data.txt", "r");
int a;
char str[20];
if (fp) {fscanf(fp, "%d %s", &a, str);  // 从文件读取整数和字符串fclose(fp);
}
  • 注释
    • 返回值是成功匹配的参数个数。

5. 块数据读写

fread() - 读取数据块

  • 功能:从文件读取二进制数据块。
  • 参数
    • const void* ptr:存储目标地址。
    • size_t size:每个数据块大小(字节)。
    • size_t nmemb:数据块数量。
    • FILE* stream
struct Item
{ char name[20]; int size; 
};
struct Item items[3];
FILE *fp = fopen("/tmp/data.bin", "rb");
if (fp) {// 参数:缓冲区, 每个元素大小, 元素数量, 文件指针size_t count = fread(items, sizeof(struct Item), 3, fp);if (count != 3) {  // 检查实际读取数量printf("读取不完整\n");}fclose(fp);
}
  • 注释
    • 返回实际读取的元素数量(非字节数)。
    • 适用于二进制文件(模式含 "b")。

fwrite() - 写入数据块

  • 功能:向文件写入二进制数据块。
  • 参数
    • const void* ptr:数据源地址。
    • size_t size:每个数据块大小(字节)。
    • size_t nmemb:数据块数量。
    • FILE* stream
  • 返回值:成功写入的数据块数量。
struct Item items[3] = {{"Linux", 5}, {"C", 1}};
FILE *fp = fopen("/tmp/data.bin", "wb");
if (fp) {fwrite(items, sizeof(struct Item), 2, fp);  // 写入2个结构体fclose(fp);
}
  • 注释
    • 返回实际写入的元素数量,需检查是否完整。

6. 文件定位

fseek() - 移动文件指针

  • 功能:移动文件位置指针。
  • 参数
    • FILE* stream
    • long offset:偏移量(字节)。
    • int whence:起始位置(SEEK_SET 文件头、SEEK_CUR 当前位置、SEEK_END 文件尾)。
  • 返回值:成功返回 0,失败返回非零值
FILE *fp = fopen("large.bin", "rb");
if (fp) {fseek(fp, 100L, SEEK_SET);  // 从文件头偏移100字节long pos = ftell(fp);        // 获取当前位置printf("当前位置: %ld\n", pos); fclose(fp);
}

rewind() - 重置到文件头

rewind(fp);  // 等价于 fseek(fp, 0L, SEEK_SET)

7. 错误处理

feof() / ferror() - 检查状态

  • ferror():检查文件操作是否出错(非零值表示错误)。
  • feof():检查是否到达文件末尾(非零值表示结束)。
FILE *fp = fopen("file.txt", "r");
if (fp) {char buf[100];fgets(buf, sizeof(buf), fp);if (feof(fp)) {printf("已到文件末尾\n");}if (ferror(fp)) {printf("读取错误\n");}fclose(fp);
}
  • 注释
    • feof() 在读到末尾后返回真,ferror() 检查错误标志。

3. 输出信息到显示器,你有哪些方法

C语言通过标准I/O库提供多种输出方式,均基于stdout(标准输出流)实现:

  • printf():最常用的格式化输出函数,自动追加换行符。

    printf("Hello World\n");  // 输出字符串并换行
    
  • fprintf():指定输出流(如stdout)的格式化输出。

    fprintf(stdout, "Value: %d\n", 42);  // 等同于printf
    
  • puts():输出字符串并自动换行。

    puts("Hello Linux");  // 输出后自动换行
    
  • fputs():输出字符串但不自动换行。

    fputs("No newline", stdout);  // 需手动添加\n
    
  • putchar()/fputc():单字符输出。

    putchar('A');          // 输出字符'A'
    fputc('B', stdout);    // 等同putchar
    
  • fwrite():二进制数据块输出(也可用于文本)。

    const char *msg = "Binary write\n";
    fwrite(msg, strlen(msg), 1, stdout);  // 直接写入字节流
    

    关键点:所有方法均通过stdout(文件指针)指向显示器。


4. stdin & stdout & stderr

在C语言中,stdinstdoutstderr是三个预定义的标准I/O流,它们在程序启动时由系统自动打开。这些流是C标准库的核心组成部分,提供了一种标准化的输入/输出处理方式。


1. 基本概念

流名称文件描述符默认设备用途缓冲类型
stdin0键盘标准输入行缓冲(终端)
stdout1显示器标准输出行缓冲(终端)
stderr2显示器标准错误输出无缓冲

关键特性

  • 类型均为 FILE*(文件指针)
  • 定义在 <stdio.h> 中
  • 生命周期与程序相同(自动打开/关闭)

2. 底层原理

(1) 声明方式

// stdio.h 中的声明
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

(2) 与文件描述符的关系

#include <unistd.h>
// 验证文件描述符
printf("stdin fd: %d\n",  fileno(stdin));  // 输出 0
printf("stdout fd: %d\n", fileno(stdout)); // 输出 1
printf("stderr fd: %d\n", fileno(stderr)); // 输出 2

(3) 缓冲机制差异

缓冲行为典型场景
stdout行缓冲(遇到\n或满缓冲才输出)printf("Hello\n")
stderr无缓冲(立即输出)perror("Error")
stdin行缓冲(等待回车键)scanf("%s", buf)

缓冲验证代码

#include <stdio.h>
#include <unistd.h>int main() {// stdout 有缓冲(可能不会立即显示)fprintf(stdout, "This is stdout");sleep(2);  // 等待2秒// stderr 无缓冲(立即显示)fprintf(stderr, "\nThis is stderr");return 0;
}

运行结果
先等待2秒,然后同时显示:

This is stderr
This is stdout

3. 实际应用场景

(1) 输入重定向

#include <stdio.h>int main() {char buf[100];// 从stdin读取(可以是键盘或重定向文件)while (fgets(buf, sizeof(buf), stdin) != NULL) {fprintf(stdout, "Read: %s", buf);}return 0;
}

使用方式

# 键盘输入
$ ./program
Hello
Read: Hello# 文件重定向
$ ./program < input.txt

(2) 分离正常输出与错误

#include <stdio.h>int main() {// 正常输出到stdout(可被重定向)fprintf(stdout, "Program started\n");// 错误输出到stderr(始终显示在终端)fprintf(stderr, "[ERROR] Invalid operation\n");return 0;
}

重定向效果

$ ./program > output.txt  # stdout重定向到文件
[ERROR] Invalid operation # stderr仍在终端显示$ cat output.txt
Program started

(3) 错误诊断

#include <stdio.h>
#include <errno.h>int main() {FILE *fp = fopen("nonexist.txt", "r");if (fp == NULL) {// 输出到stderr(无缓冲确保及时显示)perror("fopen failed"); fprintf(stderr, "Error code: %d\n", errno);}return 0;
}

输出

fopen failed: No such file or directory
Error code: 2

4. 高级用法

(1) 流重定向

#include <stdio.h>int main() {// 临时重定向stdout到文件FILE *log = fopen("log.txt", "w");stdout = log;  // 重定向printf("This goes to log.txt");  // 写入文件fclose(log);stdout = fdopen(1, "w");  // 恢复默认return 0;
}

(2) 多流协同

#include <stdio.h>int main() {int value;// 提示用户输入(stderr确保即时显示)fprintf(stderr, "Enter a number: ");// 从stdin读取scanf("%d", &value);// 结果输出到stdoutprintf("Square: %d\n", value * value);return 0;
}

5. 重要注意事项

  1. 不要手动关闭
    这三个流会在程序结束时自动关闭,显式关闭可能导致未定义行为:

    fclose(stdin);  // ❌ 危险操作!
    
  2. 缓冲同步
    在混合使用stdoutstderr时,使用fflush强制同步:

    printf("Processing...");
    fflush(stdout);  // 确保先显示
    fprintf(stderr, "[WARN] Low memory");
    
  3. 重定向安全
    需要即时显示的提示信息应使用stderr

    // 正确方式(重定向时仍显示提示)
    fprintf(stderr, "Enter password: ");
    
  4. 二进制模式
    在Windows系统中,使用_setmode切换二进制模式以避免换行符转换:

    #include <io.h>
    #include <fcntl.h>
    _setmode(_fileno(stdout), _O_BINARY);  // Windows专用
    

5. 打开文件的方式

r     Open text file for reading.The stream is positioned at the beginning of the file.r+     Open for reading and writing.The stream is positioned at the beginning of the file.w     Truncate(缩短) file to zero length or create text file for writing.The stream is positioned at the beginning of the file.w+     Open for reading and writing.The file is created if it does not exist, otherwise it is truncated.The stream is positioned at the beginning of the file.a     Open for appending (writing at end of file).The file is created if it does not exist.The stream is positioned at the end of the file.a+     Open for reading and appending (writing at end of file).The file is created if it does not exist. The initial file positionfor reading is at the beginning of the file,but output is always appended to the end of the file.

1. 基本模式

模式描述文件存在文件不存在缓冲区行为
"r"只读(文本文件)打开文件返回 NULL输入缓冲区
"w"只写(文本文件)清空内容创建新文件输出缓冲区
"a"追加(文本文件)保留内容,追加写入创建新文件输出缓冲区
"rb"只读(二进制文件)打开文件返回 NULL输入缓冲区
"wb"只写(二进制文件)清空内容创建新文件输出缓冲区
"ab"追加(二进制文件)保留内容,追加写入创建新文件输出缓冲区

关键说明

  • "r" 和 "rb" 要求文件必须存在,否则失败 。
  • "w"/"wb" 会无条件清空文件(易错点!)。
  • "a"/"ab" 的写入位置始终在文件末尾 。

2. 扩展读写模式(+号组合)

模式描述读操作位置写操作位置
"r+"读写(文本文件)文件开头当前指针位置
"w+"读写(文本文件)文件开头先清空内容
"a+"读写(文本文件)文件开头始终在文件末尾
"rb+"读写(二进制文件)文件开头当前指针位置
"wb+"读写(二进制文件)文件开头先清空内容
"ab+"读写(二进制文件)文件开头始终在文件末尾

核心特性

  • "w+" 和 "wb+" 会先清空文件再打开 。
  • "a+"/"ab+" 的写操作不受 fseek() 影响,永远追加到末尾 。
  • 读写切换时需用 fseek() 或 rewind() 重定位指针 。
  • 换行符差异

    • 文本模式(无 b)在 Windows 中自动转换 \r\n ↔ \n,Linux/macOS 无此转换 。
    • 二进制模式(带 b)在所有平台直接读写原始字节 。
  • 权限问题

    • "w" 和 "a" 模式需文件可写权限,否则返回 NULL 。
    • Linux 系统可通过 chmod() 提前设置权限。

总结

  • 核心口诀

    r 读,w 写(清空!),a 追加,b 二进制,+ 读写。

  • 最佳实践

    1. 明确需求后选择精准模式(如避免误用 "w" 导致数据清空)。
    2. 二进制文件操作必须加 b(避免换行符问题)。
    3. 读写混合时用 fseek() 同步指针位置 。
    4. 始终检查返回值并处理错误 。

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

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

相关文章

构建智能可视化分析系统:RTSP|RTMP播放器与AI行为识别的融合实践

技术背景 随着人工智能向边缘侧、实时化方向加速演进&#xff0c;视频已从传统的“记录媒介”跃升为支撑智能感知与自动决策的关键数据入口。在安防监控、工业安全、交通治理等复杂应用场景中&#xff0c;行为识别系统的准确性和响应效率&#xff0c;越来越依赖于视频源的时效…

AI入门学习-Python 最主流的机器学习库Scikit-learn

一、Scikit-learn 核心定位是什么&#xff1a;Python 最主流的机器学习库&#xff0c;涵盖从数据预处理到模型评估的全流程。 为什么测试工程师必学&#xff1a;✅ 80% 的测试机器学习问题可用它解决✅ 无需深厚数学基础&#xff0c;API 设计极简✅ 与 Pandas/Numpy 无缝集成&a…

apache-doris安装兼datax-web配置

Doris安装 官方快速开始链接 下载2.1.10&#xff0c;解压。我这边个人服务器CPU是J1900&#xff0c;是没有 avx2的&#xff0c;所以选no 配置JAVA_HOME&#xff0c;这里没有配置的要配置下&#xff0c;注意要Oracle的jdk&#xff0c;openjdk没有jps等工具集&#xff0c;后面跑…

问题实例:4G网络下语音呼叫失败

问题描述 测试机 拨号呼出后&#xff0c;一直在4G&#xff0c;超时后自动挂断。 对比机可以呼出成功&#xff0c;呼出时回落3G。 日志分析 测试机和对比机一样发起了CSFB 呼叫。 只是测试机后面没有回落3G。 03:44:40.373264 [0xB0ED] LTE NAS EMM Plain OTA Outgoing Message …

MATLAB 2024b深度学习新特性全面解析与DeepSeek大模型集成开发技术

随着人工智能技术向多学科交叉融合与工程实践领域纵深发展&#xff0c;MATLAB 2024b深度学习工具箱通过架构创新与功能强化&#xff0c;为科研创新和行业应用提供了全栈式解决方案。基于该版本工具链的三大革新方向展开&#xff1a;一是构建覆盖经典模型与前沿架构的体系化&…

Springboot美食分享平台

一、 绪论 1.1 研究意义 当今社会作为一个飞速的发展社会&#xff0c;网络已经完全渗入人们的生活&#xff0c; 网络信息已成为传播的第一大媒介&#xff0c; 可以毫不夸张说网络资源获取已逐步改变了人们以前的生活方式&#xff0c;网络已成为人们日常&#xff0c;休闲主要工…

微信小程序——世界天气小助手

哈喽&#xff0c;大家好&#xff01; 最近小编开发了一个简单的微信小程序——世界天气小助手&#xff0c;希望大家喜欢。 No.1: 为大家介绍下开发者工具下的页面结构。一共有三个界面{主页、搜索页、详情页}No.2&#xff1a; 具体页面展示&#xff1a;当前页面是主页&…

基于单片机的智能家居安防系统设计

摘 要 为了应对目前人们提出的对生活越来越智能的要求&#xff0c;在提高生活品质的同时降低意外事件发生对用户造成的经济损失或其他损失。针对日常生活中经常发生的火灾&#xff0c;失窃&#xff0c;电力资源浪费等生活问题&#xff0c;本设计正是在这种需求背景下展开研究…

腾讯研究院 | AI 浪潮中的中国品牌优势解码:华为、小米、大疆、科大讯飞等品牌从技术破壁到生态领跑的全维突围

当 DeepSeek-R1 模型在 2025 年掀起大众 AI 热潮&#xff0c;当腾讯混元大模型与京东言犀大模型在产业场景中落地生根&#xff0c;中国品牌正在 AI 技术革命的浪潮中完成从追随者到引领者的蜕变。腾讯营销洞察&#xff08;TMI&#xff09;联合京东消费及产业研究院、腾讯研究院…

FreeRTOS学习笔记——空闲任务prvIdleTask

文章目录任务创建任务的内容推荐阅读任务创建 prvIdleTask任务&#xff0c;是由任务调度函数vTaskStartScheduler创建的&#xff0c;任务优先级0&#xff0c;任务堆栈深度由配置选项configMINIMAL_STACK_SIZE定义。 void vTaskStartScheduler(void) {/* 其他代码*//* Add the…

初识卷积神经网络CNN

卷积神经网络CNN 全连接神经网络存在的问题: 输入的形式应该是列向量&#xff0c;但是卷积神经网络中的输入是图像(2D矩阵)&#xff0c;那么就需要对图片进行展平处理&#xff0c;原本图像中蕴含的空间等信息就被打乱了输入的特征多了&#xff0c;那么神经元的参数就会很多&…

高层功能架构详解 - openExo

高层功能架构详解1. 系统整体结构与模块化设计2. 两大核心类&#xff1a;ExoData 与 ExoA. ExoDataB. ExoC. 数据结构的层级关系3. 多微控制器协作与BLE通信4. 主控软件运行流程&#xff08;主循环伪代码&#xff09;5. 架构优点小结6. 与 Code Structure 的关系实用建议1. 系统…

【西北工业大学公开课】导引系统原理(全61讲)周军 -个人笔记版 5000字

【严正声明】此文档为个人笔记&#xff1a;仅供个人与同学参考学习&#xff0c;记录学习过程&#xff0c;严谨商业转载&#xff0c;或商业售卖&#xff01;感谢西北工业大学公开课知识分享&#xff0c;公开资料开源&#xff01;视频链接&#xff1a;【【西北工业大学】导引系统…

《命令行参数与环境变量:从使用到原理的全方位解析》

前言 当我们在终端输入 ls -l /home 查看目录详情&#xff0c;或用 gcc -o hello hello.c 编译代码时&#xff0c;或许很少思考&#xff1a;这些空格分隔的 “指令 选项 路径” 是如何被程序识别的&#xff1f;为什么 PATH 变量能让系统找到可执行文件&#xff0c;而 HOME 变…

C++设计模式:单例模式 (现代C++主流实现方式Meyer‘s Singleton + 使用CRTP模板化)

文章目录单例模式创建单例类饿汉式or懒汉式现代C单例模式的主流实现方式——Meyers Singleton使用 CRTP 模板化单例类单例模式 单例模式是指程序中只需要一个实例化对象&#xff0c;在全局作用域或整个代码架构中&#xff0c;此对象只被实例化一次&#xff0c;就可以达到在整个…

Eureka 和 Nacos

一、基本介绍EurekaEureka 是 Netflix 公司开发的一款基于 REST 风格的服务注册与发现组件&#xff0c;专为分布式系统设计。它遵循 AP 原则&#xff08;可用性、分区容错性优先&#xff09;&#xff0c;强调在网络分区等异常情况下的服务可用性&#xff0c;是 Spring Cloud Ne…

文件IO笔试题

目录前言一、核心概念&#xff1a;二、关键操作步骤&#xff1a;三、为什么需要文件IO&#xff1f;四、常见类型&#xff1a;五、标准IO源码六、笔试真题和练习1.代码实现1代码实现22.代码实现3.代码实现4.代码实现5.代码实现七、总结前言 文件IO&#xff08;文件输入/输出&am…

前端学习 5:DFT

DFT技术 DFT &#xff08;design for testability&#xff09;&#xff1a;指在设计系统和电路的同时&#xff0c;考虑测试的需求&#xff0c;通过增加一定的硬件开销&#xff0c;获得最大可测性的设计过程。&#xff08;因为增加了硬件&#xff0c;所以也带来了不足&#xff…

最长递增子序列(LIS)问题详解

最长递增子序列LIS问题详解一、问题定义与核心特征1.1 问题描述1.2 核心特征二、基础解法&#xff1a;动态规划&#xff08;DP&#xff09;2.1 解法思路2.2 Java代码实现2.3 复杂度分析三、优化解法&#xff1a;二分查找贪心3.1 核心思路3.2 二分查找的作用3.3 Java代码实现代码…

什么是HTTP长连接、短连接?谁更能抗DoS攻击?

想象你在快餐店点餐&#xff1a; 你&#xff1a;“一个汉堡”收银员&#xff1a;“好的&#xff0c;15元”交易结束&#xff0c;你离开队伍你想加杯可乐&#xff0c;重新排队你&#xff1a;“一杯可乐”收银员&#xff1a;“好的&#xff0c;8元”再次离开… 这种每次沟通后立即…