驚!printf 不往屏幕輸?都是 fd 在搞鬼!爆肝拆解 Linux 文件描述符 + 重定向底層,學會直接在終端橫著走

文 章 目 錄

  • 一、文 件
    • 1、基 礎 知 識
    • 2、C 文 件 接 口
      • (1)代 碼 示 例
      • (2)當 前 路 徑
      • (3)文 件 權 限
      • (4)w
      • (5)a
      • (6)三 個 輸 入 輸 出 流
    • 3、分 開 顯 示 stdout 和 stderr
    • 4、基 礎 知 識
      • (1)open
      • (2)close
      • (3)write
      • (4)標 志 位 傳 遞 方 式
  • 二、訪 問 文 件 的 本 質
    • 1、struct file
    • 2、FILE
    • 3、close(1)
    • 4、fd
    • 5、read
    • 6、引 用 計 數 與 關 閉 文 件
  • 三、重 定 向
    • 1、文 件 描 述 符 的 分 配 規 則
      • (1)原 版 代 碼
      • (2)close(0)
      • (3)close(1)
      • (4)close(2)
      • (5)總 結
    • 2、重 定 向 的 原 理
    • 3、dup2
    • 4、輸 入 重 定 向
    • 5、追 加 重 定 向
    • 6、輸 入 重 定 向
    • 7、printf 與 fprintf
  • 四、總 結

💻作 者 簡 介:曾 與 你 一 樣 迷 茫,現 以 經 驗 助 你 入 門 Linux。
💡個 人 主 頁:@笑口常開xpr 的 個 人 主 頁
📚系 列 專 欄:Linux 探 索 之 旅:從 命 令 行 到 系 統 內 核
?代 碼 趣 語:當 0、1、2 先 占 滿 文 件 描 述 符 的 “插 槽”,open 總 會 尋 著 最 小 的 空 缺 安 家 - - - 每 個 fd 的 數 字,都 是 進 程 與 文 件 牽 手 的 “門 牌 號 碼”,藏 著 讀 寫 消 息 的 去 向。
💪代 碼 千 行,始 于 堅 持,每 日 敲 碼,進 階 編 程 之 路。
📦gitee 鏈 接:gitee

在這里插入圖片描述

?????????Linux 初 學 者 常 困 惑:會 用 > 重 定 向 卻 不 懂 原 理,知 道 printf 輸 出 卻 不 明 其 與 “文 件” 的 關 聯,對 0、1、2 文 件 描 述 符 更 是 茫 然。這 些 疑 問 的 核 心,正 是 “進 程 與 文 件 的 交 互 邏 輯” - - - 本 文 以 實 操 + 原 理 為 核 心,從 “文 件 = 內 容 + 屬 性” 切 入,講 清 C 庫 / 系 統 調 用 用 法,拆 解 文 件 描 述 符 規 則 與 重 定 向 本 質,搭 配 代 碼 截 圖 幫 你 打 通 “命 令 - 代 碼 - 內 核” 鏈 路。


一、文 件

1、基 礎 知 識

  1. 文 件 = 內 容 + 屬 性
  2. 文 件 分 為 打 開 的 文 件 和 沒 有 打 開 的 文 件。進 程 打 開 的 文 件,沒 打 開 的 文 件 存 儲 在 磁 盤 上,沒 有 打 開 的 文 件 非 常 多。本 質 上 是 研 究 進 程 和 文 件 的 關 系,要 快 速 的 對 文 件 進 行 增 刪 查 改。
  3. 文 件 想 要 被 打 開 首 先 應 該 被 加 載 到 內 存。
  4. 進 程 :打 開 文 件 = 1:n,一 個 進 程 可 以 打 開 多 個 文 件。操 作 系 統 內 部 一 定 存 在 大 量 的 被 打 開 的 文 件。操 作 系 統 要 管 理 被 打 開 的 文 件,先 描 述,再 組 織。
  5. 在 Linux 內 核 中,一 個 被 打 開 的 文 件 都 必 須 有 自 己 的 文 件 打 開 對 象,包 含 文 件 的 很 多 屬 性。

2、C 文 件 接 口

C 語 言 文 件 操 作

(1)代 碼 示 例

#include<stdio.h>
#include<unistd.h>
int main()
{printf("pid:%d\n",getpid());//打開文件的路徑和文件名,默認在當前路徑下創建一個文件FILE* pf = fopen("test.txt","w");if(pf == NULL){perror("fopen fail");return 1;}fclose(pf);sleep(100);return 0;
}

在這里插入圖片描述


(2)當 前 路 徑

?????????當 前 路 徑 指 的 是 進 程 的 當 前 路 徑 cwd,如 果 更 改 了 當 前 進 程 的 cwd,就 可 以 把 文 件 新 建 到 其 他 目 錄。

?????????可 以 使 用 ll /proc/進 程 的 PID 來 查 看 進 程 的 當 前 路 徑。
在這里插入圖片描述


chdir
更 改 進 程 的 工 作 目 錄。
在這里插入圖片描述
?????????在 上 面 的 代 碼 中 添 加 chdir("/home/xpr/linux"); 可 以 更 改 進 程 的 路 徑。
在這里插入圖片描述


(3)文 件 權 限

在這里插入圖片描述


(4)w

?????????將 字 符 寫 入 文 件。如 果 沒 有 文 件 則 會 創 建 文 件,如 果 文 件 有 內 容 則 會 清 空。


fwrite
將 字 符 寫 入 到 文 件 中。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打開文件的路徑和文件名,默認在當前路徑下創建一個文件FILE* pf = fopen("test.txt","w");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fwrite(str,strlen(str),1,pf);fclose(pf);return 0;
}

在這里插入圖片描述


?????????這 里 strlen 不 需 要 加 1 原 因 是 因 為 如 果 加 1 會 出 現 亂 碼,如 下 圖 所 示。字 符 串 以 \0 結 尾 是 C 語 言 的 規 定,和 文 件 沒 有 關 系。

strlen + 1
strlen + 1 會 在 文 件 中 出 現 ^@,這 個 字 符 就 是 \0
在這里插入圖片描述


echo 及 輸 入 重 定 向
?????????類 似 的,echo 的 輸 入 重 定 向 和 w 類 似,如 果 沒 有 文 件 則 會 創 建,文 件 有 內 容 則 會 清 空。
在這里插入圖片描述


(5)a

?????????在 文 件 結 尾 追 加 字 符 串,如 果 沒 有 文 件 則 會 創 建 文 件。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打開文件的路徑和文件名,默認在當前路徑下創建一個文件FILE* pf = fopen("test.txt","a");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fwrite(str,strlen(str)+1,1,pf);fclose(pf);return 0;
}

在這里插入圖片描述


echo 及 輸 出 重 定 向
在這里插入圖片描述


(6)三 個 輸 入 輸 出 流

?????????所 有 的 語 言 在 啟 動 時 默 認 都 會 打 開 對 應 的 設 備 文 件,原 因 是 因 為 電 腦 開 機 時 就 會 打 開 顯 示 器 和 鍵 盤,編 寫 代 碼 時 使 用 鍵 盤 輸 入,用 顯 示 器 顯 示。C 語 言 的 3 個 輸 入 輸 出 流。C 程 序 默 認 在 啟 動 時 會 打 開 三 個 標 準 輸 入 輸 出 流(文 件)。
所 有 的 語 言 對 于 文 件 的 操 作 都 包 括 文 件 描 述 符 fd

stdin:鍵 盤
stdout:顯 示 器 文 件
stderr:顯 示 器 文 件
在這里插入圖片描述


3、分 開 顯 示 stdout 和 stderr

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stdout,"hello normal message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");fprintf(stderr,"hello error message\n");return 0;
}

在這里插入圖片描述
?????????重 定 向 以 后,向 1 里 面 寫 入 的 內 容 都 會 寫 入 normal.txt 文 件 中。只 對 1 重 定 向,沒 有 對 2 重 定 向。
在這里插入圖片描述
?????????1 可 以 省 略 不 寫。stdout 和 stderr 可 以 重 定 向 到 1 個 文 件 中。
?????????./mytest >err.txt 2>&1 先 表 示 把 1 號 文 件 描 述 符 的 內 容 寫 入 err.txt 中,然 后 2>&1 表 示 把 2 號 文 件 描 述 符 中 的 內 容 寫 入 1 號 文 件 描 述 符 中。


fprintf
?????????將 字 符 寫 入 文 件 或 使 用 流。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{printf("pid:%d\n",getpid());//打開文件的路徑和文件名,默認在當前路徑下創建一個文件FILE* pf = fopen("test.txt","a");if(pf == NULL){perror("fopen fail");return 1;}const char* str = "hello linux";fprintf(stdout,"%s,%d\n",str,1234);fclose(pf);return 0;
}

在這里插入圖片描述


4、基 礎 知 識

?????????文 件 其 實 是 在 磁 盤 上 的,磁 盤 是 外 部 設 備,訪 問 文 件 其 實 是 訪 問 硬 件。操 作 系 統 是 硬 件 的 管 理 者。幾 乎 所 有 的 庫 只 要 是 訪 問 硬 件 設 備,必 定 要 封 裝 系 統 調 用。


(1)open

?????????打 開 或 者 創 建 文 件 或 者 設 備,可 以 指 定 文 件 的 權 限,即 文 件 是 否 存 在。
在這里插入圖片描述
flags
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{    umask(0); // 文件掩碼int fd = open("log.txt",O_WRONLY|O_CREAT,0666);if(fd<0){printf("open fail\n");return 1;}return 0;
}

在這里插入圖片描述
在這里插入圖片描述


(2)close

關 閉 文 件

文 件 描 述 符
file descriptor:文 件 描 述 符,是 int 類 型。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{    umask(0); // 文件掩碼int fd = open("log.txt",O_WRONLY|O_CREAT,0666);if(fd<0){printf("open fail\n");return 1;}close(fd);return 0;
}

(3)write

?????????向 文 件 中 寫 入 文 件 描 述 符,返 回 值 是 實 際 寫 入 的 字 節 數。默 認 從 文 件 的 開 始 處 寫,不 會 對 文 件 清 空,讓 新 增 加 的 字 符 替 換 掉 舊 的 字 符。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{    umask(0); // 文件掩碼int fd = open("log.txt",O_WRONLY|O_CREAT,0666);if(fd<0){printf("open fail\n");return 1;}const char* str = "hello world";write(fd,str,strlen(str));close(fd);return 0;
}

在這里插入圖片描述


(4)標 志 位 傳 遞 方 式

1 個 整 數 可 以 傳 遞 1 個 標 志 位。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define ONE (1 << 0)  //1
#define TWO (1 << 1)  //2
#define THREE (1 << 2)//4
#define FOUR (1 << 3) //8
void show(int flags)
{if(flags&ONE){printf("hello function1\n");}if(flags&TWO){printf("hello function2\n");}if(flags&THREE){printf("hello function3\n");}if(flags&FOUR){printf("hello function4\n");}
}
int main()
{    show(ONE);printf("-----------\n");show(ONE|TWO);printf("-----------\n");show(ONE|TWO|THREE);printf("-----------\n");return 0;
}

在這里插入圖片描述


二、訪 問 文 件 的 本 質

1、struct file

?????????操 作 系 統 內 描 述 一 個 被 打 開 文 件 的 信 息。

直 接 或 者 間 接 包 含 以 下 屬 性:

  1. 被 打 開 的 文 件 在 哪 個 位 置
  2. 基 本 屬 性、權 限、大 小、讀 寫 位 置、誰 打 開 的。
  3. 文 件 的 內 核 緩 沖 區 信 息
  4. struct file *next 指 針。

?????????對 文 件 的 操 作 改 為 對 雙 向 鏈 表 的 增 刪 查 改。

?????????一 個 進 程 可 以 打 開 多 個 文 件,要 建 立 進 程 PCB 和 打 開 文 件 的 關 系。
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述


2、FILE

?????????C 語 言 中 的 FILE 是 C 庫 中 自 己 封 裝 的 結 構 體,里 面 包 含 文 件 描 述 符。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);return 0;
}

在這里插入圖片描述


3、close(1)

printf
?????????可 以 使 用 close(1); 關 閉 顯 示 器 使 printf 無 法 顯 示 在 顯 示 屏 上。說 明 printf 的 底 層 使 用 了 1 號 文 件 描 述 符。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{  close(1);printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);return 0;
}

在這里插入圖片描述
fprintf

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{  close(1);int ret = printf("stdin->fd:%d\n",stdin->_fileno);printf("stdout->fd:%d\n",stdout->_fileno);printf("stderr->fd:%d\n",stderr->_fileno);fprintf(stderr,"printf ret:%d\n",ret);return 0;
}

在這里插入圖片描述
?????????如 果 關 閉 了 1 號 文 件 描 述 符,使 用 2 號 文 件 描 述 符 也 可 以 在 顯 示 器 上 輸 出。


4、fd

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{    umask(0); // 文件掩碼int fd1 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd2 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd3 = open("log.txt",O_WRONLY|O_CREAT,0666);int fd4 = open("log.txt",O_WRONLY|O_CREAT,0666);printf("fd1:%d\n",fd1);printf("fd2:%d\n",fd2);printf("fd3:%d\n",fd3);printf("fd4:%d\n",fd4);close(fd1);close(fd2);close(fd3);close(fd4);return 0;
}

在這里插入圖片描述
?????????返 回 的 整 數 值 都 是 數 組 的 下 標 且 都 是 整 數,返 回 的 整 數 值 都 是 從 3 開 始 的。0 是 stdin(鍵 盤 文 件),1 是 stdout(顯 示 器 文 件),2 是 stderr(顯 示 器 文 件)。


驗 證

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   const char* str = "hello linux";write(1,str,strlen(str));write(2,str,strlen(str));return 0;
}

在這里插入圖片描述


5、read

?????????從 文 件 描 述 符 中 讀 取。
在這里插入圖片描述

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{   char buf[100];ssize_t count = read(0,buf,sizeof(buf));if(count < 0){return 1;}buf[count] = '\0';printf("%s\n",buf);return 0;
}

在這里插入圖片描述


6、引 用 計 數 與 關 閉 文 件

引 用 計 數
?????????關 閉 文 件 時,使 用 close 時,對 1 號 描 述 符 的 引 用 計 數 減 1,然 后 將 1 號 指 針 位 置 置 空 即 可,然 后 判 斷 引 用 計 數 是 否 為 0,如 果 為 0,則 說 明 沒 有 文 件 被 使 用,系 統 會 回 收 struct 對 象。如 果 不 為 0,則 說 明 還 有 文 件 被 使 用。


三、重 定 向

1、文 件 描 述 符 的 分 配 規 則

(1)原 版 代 碼

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}printf("fd:%d\n",fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(fd,str,strlen(str));cnt--;}close(fd);return 0;
}

在這里插入圖片描述
?????????此 時 文 件 描 述 符 為 3,log.txt 所 對 應 的 文 件 權 限 為 664。


(2)close(0)

在 代 碼 最 前 面 添 加 close(0),輸 出 的 文 件 描 述 符 為 0。
在這里插入圖片描述


(3)close(1)

在 代 碼 最 前 面 添 加 close(1)
在這里插入圖片描述
?????????因 為 printf 的 底 層 使 用 了 stdout,stdout 的 文 件 描 述 符 為 1,這 里 將 1 關 閉,無 法 在 顯 示 器 上 輸 出。


(4)close(2)

在 代 碼 最 前 面 添 加 close(2)
在這里插入圖片描述
關 閉 2 號 文 件 描 述 符 后,輸 出 的 文 件 描 述 符 為 2。

(5)總 結

?????????關 閉 幾 號 文 件 描 述 符,文 件 描 述 符 就 輸 出 幾 號,說 明 文 件 描 述 符 對 應 的 分 配 規 則 是 從 0 下 標 開 始,尋 找 最 小 的 沒 有 使 用 的 數 組 位 置,它 的 下 標 就 是 新 文 件 的 文 件 描 述 符。

2、重 定 向 的 原 理

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  close(1);int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在這里插入圖片描述
?????????關 閉 1 號 文 件 描 述 符 后,結 果 沒 有 在 顯 示 器 中 顯 示,卻 寫 入 了 文 件 中。
在這里插入圖片描述
?????????關 閉 1 號 文 件 描 述 符 后,此 時 打 開 文 件,文 件 原 來 應 該 指 向 3 號 文 件 描 述 符,現 在 被 改 成 了 1 號 文 件 描 述 符,此 時 發 生 了 輸 入 重 定 向。
?????????重 定 向 的 本 質 是 對 數 組 下 標 的 內 容 進 行 了 修 改。如 果 想 要 發 生 重 定 向 需 要 將 原 來 文 件 描 述 符 中 的 內 容 關 閉 或 者 覆 蓋 掉 即可。


3、dup2

?????????拷 貝 文 件 描 述 符 的 指 針 內 容,將 新 的 文 件 描 述 符 的 內 容 拷 貝 給 舊 的 文 件 描 述 符,然 后 關 閉 新 的 文 件 描 述 符。
在這里插入圖片描述

4、輸 入 重 定 向

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_TRUNC,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);close(fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在這里插入圖片描述
?????????原 來 1 號 文 件 描 述 符 可 以 將 內 容 輸 出 到 顯 示 器 中,重 定 向 以 后 顯 示 器 無 法 輸 出 內 容,輸 出 的 是 文 件 的 內 容。


5、追 加 重 定 向

將 write 中 的 O_TRUNC 改 成 O_APPEND 即 可 實 現 追 加 重 定 向。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);close(fd);const char* str = "hello world\n";int cnt = 5;while(cnt){write(1,str,strlen(str));cnt--;}close(fd);return 0;
}

在這里插入圖片描述


6、輸 入 重 定 向

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{int fd = open(filename,O_RDONLY);if(fd < 0){perror("open");return 1;}dup2(fd,0);//從標準輸入讀取改為從文件中讀取char buf[1024];ssize_t s = read(0,buf,sizeof(buf)-1);if(s>0){buf[s]='\0';printf("echo:%s\n",buf);}return 0;
}

在這里插入圖片描述


cat 的 輸 入 重 定 向
從 文 件 中 讀 取 改 為 從 鍵 盤 中 讀 取。
在這里插入圖片描述


7、printf 與 fprintf

?????????printf 和 fprintf 用 的 都 是 stdin,可 以 修 改 文 件 描 述 符,改 變 輸 出 的 位 置。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#define filename "log.txt"
int main()
{  int fd = open(filename,O_CREAT|O_WRONLY|O_APPEND,0666);if(fd < 0){perror("open fail");return 1;}//重定向dup2(fd,1);printf("fd:%d\n",fd);printf("hello printf\n");fprintf(stdout,"hello fprintf\n");close(fd);return 0;
}

在這里插入圖片描述


如 何 理 解 “linux 中 一 切 皆 文 件”
?????????所 有 操 作 計 算 機 的 動 作 都 是 以 進 程 的 形 式 操 作 的,所 有 訪 問 文 件 的 操 作 都 是 用 進 程 的 方 式 訪 問 文 件 的。


在這里插入圖片描述


四、總 結

?????????本 文 已 幫 你 掌 握 Linux 文 件 操 作 核 心:文 件 定 義、文 件 描 述 符、重 定 向 本 質,及 C 庫 與 系 統 調 用 的 關 系,也 理 解 了 “一 切 皆 文 件” 的 設 計。這 些 知 識 是 后 續 進 程 通 信、網 絡 編 程 的 基 礎。建 議 動 手 修 改 代 碼 加 深 理 解,關 注 專 欄 Linux 探 索 之 旅:從 命 令 行 到 系 統 內 核,后 續 將 解 鎖 更 多 進 階 內 容,幫 你 搭 建 系 統 編 程 知 識 體 系。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95967.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【高分論文密碼】大尺度空間模擬與不確定性分析及數字制圖技術應用

大尺度模擬技術能夠從不同的時空尺度揭示農業生態環境領域的內在機理和時空變化規律&#xff0c;為復雜過程模型的模擬提供技術基礎。一&#xff1a;R語言空間數據及數據挖掘關鍵技術1、R語言空間數據講解及應用特點 1)R語言基礎與數據科學 2)R空間矢量數據 3)R柵格數據2、R語言…

Git 工作流與分支管理實戰:rebase vs merge 對比、沖突解決、規范 Commit Message 與主干穩定性最佳實踐

1. 版本控制與協作流程&#xff08;Git 工作流、分支管理、合并沖突&#xff09; 雖然 Git 用得多&#xff0c;但“rebase vs. merge”、如何解決沖突、如何編寫規范的 commit message、如何維護主干的穩定性&#xff0c;都需要一段時間才能形成體系化的理解。 摘要 在日常團隊…

調試 cuda kernel

調試 CUDA Kernel 并進入 __device__ 函數是 CUDA 開發中一項非常重要的技能。這主要依賴于 NVIDIA 的官方調試器 NVIDIA Nsight Systems (用于系統級分析) 和 NVIDIA Nsight Compute (用于內核級分析) 以及經典的 cuda-gdb (命令行調試器)。 這里將重點介紹兩種最常用和強大的…

GD32自學筆記:4.ADC

while(1)里測試ADC是否正常首先&#xff0c;ADC引腳說明如下&#xff1a;ADC 通道引腳描述ADC_CHANNEL_0PA0端口 A 的引腳 0&#xff0c;可用于模擬信號輸入&#xff0c;如傳感器或外部電壓。ADC_CHANNEL_1PA1端口 A 的引腳 1&#xff0c;常用于模擬輸入&#xff0c;適用于一般…

漸變背景色和漸變字體顏色的實現方法

一、漸變背景色&#xff08;Gradient Background&#xff09;1. 線性漸變&#xff08;Linear Gradient&#xff09;通過 linear-gradient 創建從一種顏色到另一種顏色的線性漸變。代碼示例<div class"linear-gradient"></div><style> .linear-grad…

Wi-Fi技術——傳播與損耗

一、頻段和信道 Wi-Fi通過發射無線電進行傳輸&#xff0c;而無線電的一個重要特性是頻率。 頻段&#xff1a;一個大的頻率范圍&#xff0c;如Wi-Fi工作在2.4GHz、5GHz、6GHz&#xff0c;其并不是一個值&#xff0c;而是一個范圍信道&#xff1a;在每個頻段中劃分小的頻率范圍…

【Mysql-installer-community-8.0.26.0】Mysql 社區版(8.0.26.0) 在Window 系統的默認安裝配置

??大家好&#xff0c;我是練小杰&#xff0c;好久不見了&#xff0c;周末愉快&#xff0c;今天周六了&#xff01;&#xff01;做了CSDN博客才發現&#xff0c;堅持不斷發文是那么的困難&#xff0c;大家都是好樣的&#xff01;&#xff01;&#x1f606; 本文是針對 Mysql 的…

【RabbitMQ】----初識 RabbitMQ

1. MQ 是什么&#xff1f; 在互聯網中&#xff0c;會經常使用 MQ 來作為消息通信服務&#xff0c;我們一起來看一下什么是 MQ 吧&#xff01; 1.1 MQ 本質 【MQ】&#xff08;Message queue&#xff09;&#xff0c;消息隊列&#xff0c;字面意思來看&#xff0c;本質是一個…

深度學習:歸一化技術

在深度學習中&#xff0c;歸一化技術是提高模型訓練效率和性能的重要手段。歸一化通過調整輸入數據的分布&#xff0c;使得模型在訓練過程中更易于收斂&#xff0c;減少過擬合的風險。本文將介紹幾種常見的歸一化技術&#xff0c;包括特征歸一化、批歸一化、層歸一化和實例歸一…

【Javaweb學習|實訓總結|Week1】html基礎,CSS(選擇器、常用樣式、盒子模型、彈性盒布局、CSS定位、動畫),js(基本類型、運算符典例)

開學前三周先進行企業實訓&#xff0c;主要學習Javaweb并實現一些小的項目&#xff0c;本篇筆記主要記錄第一周實訓的知識總結以及個人遇到的問題及解答&#xff0c;用于日后復習回顧和知識鞏固&#xff0c;希望可以幫到同樣在學Javaweb的大家 文章目錄D1html基礎D2塊元素與行…

SQL 拓展指南:不同數據庫差異對比(MySQL/Oracle/SQL Server 基礎區別)

在學習 SQL 的過程中&#xff0c;你可能會發現&#xff1a;同樣的 “建表語句” 在 MySQL 能運行&#xff0c;在 Oracle 卻報錯&#xff1b;“分頁查詢” 的寫法在 SQL Server 和 MySQL 完全不同。這是因為 MySQL、Oracle、SQL Server 是三大主流關系型數據庫&#xff0c;雖都支…

論文閱讀:DMD | Improved Distribution Matching Distillation for Fast Image Synthesis

論文地址&#xff1a;https://arxiv.org/abs/2405.14867 項目官網&#xff1a;https://tianweiy.github.io/dmd2/ 代碼地址&#xff1a;https://github.com/tianweiy/DMD2 發表時間&#xff1a;2024年5月24日 分布匹配蒸餾&#xff08;DMD&#xff09;生成的一步生成器能夠與教…

嵌入式 Linux 啟動流程詳解 (以 ARM + U-Boot 為例)

嵌入式 Linux 啟動流程詳解 (以 ARM U-Boot 為例) 對于嵌入式開發者而言&#xff0c;深入理解系統的啟動流程至關重要。這不僅有助于進行底層驅動開發和系統移植&#xff0c;還能在遇到啟動失敗等問題時&#xff0c;快速定位和解決。本文將詳細分解基于 ARM 架構的嵌入式 Linu…

在前端開發中,html中script 的type分別有哪幾種?分別什么情況用到?

以下是 HTML 中<script>標簽type屬性的常見取值、說明及使用場景&#xff1a;type 值說明使用場景不寫&#xff08;空值&#xff09;HTML5 中默認等同于text/javascript&#xff0c;表示普通 JavaScript 腳本絕大多數傳統 JavaScript 代碼&#xff0c;包括內聯腳本和外部…

2025職教技能大賽汽車制造與維修賽道速遞-產教融合實戰亮劍?

各位職教同仁&#xff0c;2025年世界職業院校技能大賽總決賽爭奪賽&#xff08;汽車制造與維修賽道&#xff09;國內賽區的戰報新鮮出爐&#xff01;本次大賽以“技炫青春 能創未來”為主題&#xff0c;聚焦汽車產業鏈高質量發展需求&#xff0c;在真實場景中比拼技能&#xff…

日志 | Spring Boot 日志配置通用規律(AI問答)

Spring Boot 日志配置通用規律。想看特定日志&#xff0c;怎么打開日志開關 文章目錄一、一句話總結二、AI問答版提問詞AI的響應&#x1f4ca; Spring Boot 日志配置通用規律1. 基本語法結構2. 日志級別&#xff08;從詳細到簡潔&#xff09;&#x1f3af; 常用日志配置分類1. …

DJANGO后端服務啟動報錯及解決

1.報錯信息[2025-09-05 17:08:54 0800] [23438] [INFO] Worker exiting (pid: 23438) [2025-09-05 17:08:54 0800] [23440] [ERROR] Exception in worker process Traceback (most recent call last):File "/www/SOP/lib64/python3.11/site-packages/gunicorn/arbiter.py&…

Qt 中的 Q_OBJECT 宏詳解 —— 從源碼到底層機制的全面剖析

Qt 中的 Q_OBJECT 宏詳解 —— 從源碼到底層機制的全面剖析 文章目錄Qt 中的 Q_OBJECT 宏詳解 —— 從源碼到底層機制的全面剖析摘要一、Q_OBJECT 宏是什么&#xff1f;二、Q_OBJECT 宏背后的源碼三、moc 工具的作用四、信號與槽調用流程五、沒有 Q_OBJECT 會怎樣&#xff1f;六…

GD32自學筆記:5.定時器中斷

定時器中斷功能主要是兩點&#xff1a;1.怎么配置的定時器中斷時間間隔&#xff1b;2.中斷里長什么樣一、定時器中斷配置函數直接在bsp_basic_timer.c里找到下面函數&#xff1a;void basic_timer_config(uint16_t pre,uint16_t per) {/* T 1/f, time T * pre,pertime (pre …

[Godot入門大全]目錄

1 免責聲明 資源分享免責聲明&#xff1a; 本平臺/本人所分享的各類資源&#xff08;包括但不限于文字、圖片、音頻、視頻、文檔等&#xff09;&#xff0c;均來源于公開網絡環境中的可分享內容或已獲授權的傳播素材。 本平臺/本人僅出于信息交流、資源共享之目的進行傳播&…