C語言入門指南:字符函數和字符串函數

目錄

前言:

一. 字符分類函數:精準識別字符的“身份”

1.1 ???????核心函數

1.2 經典應用示例:

二、?字符轉換函數:優雅地改變字符形態

三、strlen:計算長度的基石與無符號陷阱

3.1 關鍵特性

3.2 致命陷阱:無符號整數的減法

3.3 模擬實現:三種經典方法

3.3.1 計數器法:最直觀,遍歷計數

3.3.2?遞歸法:利用數學歸納思想。簡潔優雅,但可能導致棧溢出,不適用于長字符串

3.3.3?指針相減法:效率最高,僅需一次遍歷。讓指針 p 指向字符串末尾,然后 p - str 即為長度。

四、strcpy:拷貝的雙刃劍與安全邊界

4.1 關鍵特性

4.2 致命風險:緩沖區溢出 (Buffer Overflow)

4.3?模擬實現:經典的指針自增賦值

五、strcat:拼接的隱憂

5.1 關鍵特性:

5.2 常見誤區:

5.3 模擬實現:

六、strcmp:字典序比較的藝術

6.1 返回值規則:

6.2 模擬實現:

七、strncpy:帶長度限制的strcpy——安全嗎?

7.1 關鍵特性:

7.2?典型錯誤用法:

八、strncat:相對安全的拼接

關鍵特性:

九、strncmp:限定長度的比較

十一、strtok:字符串分割的利器

11.1 工作方式:

11.2?核心特點與警告:

11.3?經典應用:解析IP地址

十二、strerror & perror:調試的明燈

總結:


前言:

errno 的值只是一個數字(如 2),strerror(2) 返回 "No such file or directory",這使得程序的錯誤信息變得人性化,極大地提升了調試效率。引言:

在C語言編程中,字符(char)字符串(string) 是最核心的數據類型之一。無論是讀取用戶輸入、解析配置文件、處理網絡數據包,還是進行簡單的文本格式化,我們幾乎無時無刻不在與它們打交道。C語言標準庫為我們提供了一套精巧而強大的函數集合,主要位于 <ctype.h><string.h><errno.h> 等頭文件中。這些函數是高效、可靠地操作字符串的基石。本篇博客帶你系統掌握這些關鍵函數的用法、原理及注意事項。

讓我們開始吧!

一. 字符分類函數:精準識別字符的“身份”

在處理文本時,我們常常需要判斷一個字符屬于何種類型。C標準庫提供了豐富的字符分類函數,所有這些函數都定義在 <ctype.h> 頭文件

1.1 ???????核心函數

  • int islower(int c);?判斷 c 是否為小寫字母(a-z)。
  • int isupper(int c);?判斷 c 是否為大寫字母(A-Z)。
  • int isdigit(int c);?判斷 c 是否為十進制數字(0-9)。
  • int isalpha(int c);?判斷 c 是否為字母(大小寫均可)。
  • int isalnum(int c);?判斷 c 是否為字母或數字。
  • int isspace(int c);?判斷 c 是否為空白字符(空格、制表符 \t、換行符 \n、回車符 \r、垂直制表符 \v、換頁符 \f)。
  • int ispunct(int c);?判斷 c 是否為標點符號(非字母、非數字、非空白的可打印字符)。
  • int isprint(int c);?判斷 c 是否為可打印字符(包括空格)。
  • int isgraph(int c);?判斷 c 是否為圖形字符(不包括空格)。
  • int iscntrl(int c);?判斷 c 是否為控制字符(ASCII 0-31 和 127)。

工作原理:這些函數接收一個 int 類型的參數(通常是一個 char 類型的值,但在內部會被提升為 int)。如果該字符滿足特定條件,則返回一個非零整數(真);否則返回 0(假)。注意:返回值不一定是 1,只要是非零即可。

1.2 經典應用示例

字符串中的小寫字母轉換為大寫,其他字符保持不變

#include <stdio.h>
#include <ctype.h>int main() {char str[] = "Hello, World! 123";int i = 0;char c;while (str[i] != '\0') { // 遍歷每個字符,直到遇到'\0'c = str[i];if (islower(c)) { // 如果是小寫字母c = toupper(c); // 使用轉換函數,而非手動 -32}putchar(c); // 輸出處理后的字符i++;}printf("\n"); // 換行return 0;
}

輸出結果:
??

重要提示:這些函數的參數必須是 unsigned char 類型的值或 EOF。如果傳入一個負的 char 值(在某些系統上 char 是有符號的),行為是未定義的。為確保安全,建議在調用前進行類型轉換:islower((unsigned char)c)

二、?字符轉換函數:優雅地改變字符形態

與分類函數相輔相成的是兩個專門用于大小寫轉換的函數:

  • int tolower(int c);?如果 c 是一個大寫字母(A-Z),則將其轉換為對應的小寫字母(a-z)并返回;否則,原樣返回 c

  • int toupper(int c);?如果 c 是一個小寫字母(a-z),則將其轉換為對應的大寫字母(A-Z)并返回;否則,原樣返回 c

為什么推薦使用它們呢?

在之前的示例中,我們曾看到通過 c -= 32 來實現大小寫轉換。這種方法雖然在ASCII編碼下可行,但極其脆弱且不具可移植性。它假設了字符編碼是ASCII,并且大小寫字母的差值恰好是32。現代編碼標準(如Unicode)和某些嵌入式系統可能并非如此。touppertolower 函數是標準庫的一部分,它們會根據當前的本地化設置(locale)進行正確的轉換,保證了代碼的健壯性和跨平臺兼容性。

應用:上述字符分類函數的示例已經完美展示了 toupper 的使用,它比手動計算 c - 'A' + 'a'c - 32 更加清晰、安全。

三、strlen:計算長度的基石與無符號陷阱

size_t strlen(const char *str); 返回以空字符 '\0' 結尾的字符串中有效字符的個數不包含終止符 '\0' 本身。

3.1 關鍵特性

  • 返回類型size_t。這是一個無符號整數類型(通常是 unsigned intunsigned long)。這是所有strlen相關錯誤的根源
  • 前提條件str 必須指向一個以 '\0' 結尾的有效字符串。否則,函數會一直向后查找,直到找到一個 '\0' 或訪問非法內存,導致程序崩潰(段錯誤)。
  • 頭文件<string.h>

3.2 致命陷阱:無符號整數的減法

#include <stdio.h>
#include <string.h>int main() {const char *str1 = "abcdef"; // 長度6const char *str2 = "bbb";    // 長度3// ? 錯誤!strlen 返回 size_t (無符號)if (strlen(str2) - strlen(str1) > 0) { // 3 - 6 = -3printf("str2 > str1\n");} else {printf("str1 > str2\n"); // 實際執行這里!因為 -3 被解釋為一個巨大的正數 (如 4294967293)}// ? 正確做法1:直接比較長度if (strlen(str2) > strlen(str1)) {printf("str2 > str1\n");} else {printf("str1 >= str2\n");}// ? 正確做法2:強制轉換為有符號數if ((long)strlen(str2) - (long)strlen(str1) > 0) {printf("str2 > str1\n");}return 0;
}

3.3 模擬實現:三種經典方法

3.3.1 計數器法:最直觀,遍歷計數

size_t my_strlen(const char *str) {size_t count = 0;while (*str != '\0') {count++;str++;}return count;
}

3.3.2?遞歸法:利用數學歸納思想。簡潔優雅,但可能導致棧溢出,不適用于長字符串

size_t my_strlen(const char *str) {if (*str == '\0') {return 0;}return 1 + my_strlen(str + 1);
}

3.3.3?指針相減法:效率最高,僅需一次遍歷。讓指針 p 指向字符串末尾,然后 p - str 即為長度。

size_t my_strlen(const char *str) {const char *p = str;while (*p != '\0') {p++;}return p - str;
}

注意:所有實現都應包含 assert(str != NULL) 來檢查空指針,提高程序健壯性。

四、strcpy:拷貝的雙刃劍與安全邊界

char *strcpy(char *destination, const char *source); 將源字符串 source(包括結尾的 '\0')完整地復制到目標數組 destination 中。

4.1 關鍵特性

  • 覆蓋destination 原有的內容會被完全覆蓋。
  • 包含'\0''\0' 會被一同復制,確保結果是合法的C字符串。

前提條件:

  • source 必須是以 '\0' 結尾的有效字符串。
  • destination 必須是可修改的內存(例如,數組或動態分配的內存),不能是字符串字面量(如 "hello")。
  • destination 必須有足夠的空間容納 source 的所有字符 + 1個 '\0'這是最大的安全隱患!

4.2 致命風險:緩沖區溢出 (Buffer Overflow)

如果 destination 空間不足,strcpy 會繼續往內存里寫,覆蓋相鄰的變量、函數返回地址等,這正是黑客利用來執行任意代碼(如棧溢出攻擊)的主要手段。

char dest[5]; // 只能存4個字符+1個\0
strcpy(dest, "This is too long!"); // ? 絕對危險!會破壞棧

4.3?模擬實現:經典的指針自增賦值

strcpy 的實現是C語言編程的經典范例,體現了“賦值即判斷”的精妙:

char *my_strcpy(char *dest, const char *src) {char *ret = dest; // 保存原始目的地址,用于返回assert(dest != NULL); // 檢查參數有效性assert(src != NULL);// 核心循環:逐字符賦值,同時判斷是否為'\0'// (*dest++ = *src++) 的含義:先取 *src 的值,賦給 *dest,然后兩個指針都自增// 整個表達式的值就是被賦的值,當這個值為0(即'\0')時,循環結束while ((*dest++ = *src++) != '\0') {; // 空語句,循環體為空}return ret;
}

要點

  • 保存 dest 的初始值 ret,以便函數返回。
  • 使用 assert 檢查指針非空。
  • 利用賦值表達式的結果作為循環條件,一行代碼完成賦值、移動指針和判斷三件事。

五、strcat:拼接的隱憂

char *strcat(char *destination, const char *source); 將源字符串 source 追加到目標字符串 destination 的末尾。

5.1 關鍵特性:

  • 覆蓋'\0':首先,它會覆蓋掉 destination 原有的 '\0'
  • 追加'\0':然后,在 source 的所有字符之后添加一個新的 '\0'

前提條件:

  • source 必須是以 '\0' 結尾的有效字符串。
  • destination 必須是一個以 '\0' 結尾的有效字符串(否則它不知道從哪里開始追加)。
  • destination 必須有足夠的空間容納 destination 原有內容 + source 內容 + 1個 '\0'
  • destination 必須是可修改的。

5.2 常見誤區:

  • strcat(dest, dest);:這是災難性的dest'\0' 被覆蓋后,strcat 會無限循環地從 dest 開始尋找下一個 '\0',最終導致棧溢出或程序崩潰。
  • char dest[5] = "abc"; strcat(dest, "de");dest 最終需要存儲 "abcde\0",共6個字符,但只分配了5個字節,同樣導致溢出。

5.3 模擬實現:

char *my_strcat(char *dest, const char *src) {char *ret = dest;assert(dest != NULL);assert(src != NULL);// 第一步:找到 destination 的末尾(跳過原有的'\0')while (*dest != '\0') {dest++;}// 第二步:從destination的末尾開始,復制source的內容while ((*dest++ = *src++) != '\0') {;}return ret;
}

流程:先定位,再拷貝。

六、strcmp:字典序比較的藝術

int strcmp(const char *str1, const char *str2); 按字典序(lexicographical order)比較兩個字符串。

6.1 返回值規則:

  • 如果 str1 在字典序上大于 str2,返回一個大于0的整數。
  • 如果 str1 等于 str2,返回 0
  • 如果 str1 在字典序上小于 str2,返回一個小于0的整數。

比較機制?:從左到右逐個字符比較它們的ASCII碼值。一旦發現不同的字符,立即根據這兩個字符的ASCII碼差值返回結果。如果所有字符都相同,但其中一個字符串先遇到 '\0',則較短的字符串被認為較小。

6.2 模擬實現:

int my_strcmp(const char *str1, const char *str2) {assert(str1 != NULL);assert(str2 != NULL);// 逐字符比較while (*str1 == *str2) {// 如果到達字符串末尾(都是'\0'),則相等if (*str1 == '\0') {return 0;}str1++;str2++;}// 找到了第一個不同的字符,返回它們的ASCII碼差值return *str1 - *str2;
}

精髓return *str1 - *str2; 這一行直接利用了字符的數值屬性,簡潔高效。

七、strncpy:帶長度限制的strcpy——安全嗎?

7.1 關鍵特性:

  • 長度可控:防止了 strcpy 的無限拷貝。
  • 填充'\0':如果 source 的長度(不含'\0'小于 num,那么 strncpy 會在 destination 的剩余部分用 '\0' 填充,直到總共寫了 num 個字符。
  • 不保證'\0'終止這是最大的陷阱! 如果 source 的長度大于等于 numstrncpy 不會destination 的末尾添加 '\0'

7.2?典型錯誤用法:

char dest[5];
strncpy(dest, "Hello", 5); // source長度為5("Hello"),num=5
// dest 現在是 {'H','e','l','l','o'},沒有 '\0'!
// 下面的printf會崩潰,因為它會一直找'\0'
printf("%s\n", dest); // ? 未定義行為!

正確用法:

char dest[5];
strncpy(dest, "Hi", sizeof(dest) - 1); // 保證留出空間給'\0'
dest[sizeof(dest) - 1] = '\0'; // ? 手動確保終止

總結:

strncpy 并不比 strcpy 安全,它只是把溢出的風險從“必然發生”變成了“可能忘記”。它的設計存在缺陷。現代編程實踐中,更推薦使用 snprintfstrlcpy(非標準,但廣泛支持)。

八、strncat:相對安全的拼接

char *strncat(char *destination, const char *source, size_t num); 最多追加 num 個字符,并總是在最后添加一個 '\0'

關鍵特性:

  • 自動終止:無論 source 的長度如何,strncat 都會確保 destination'\0' 結尾。
  • 追加上限:最多追加 num 個字符。如果 source 的長度小于 num,則只追加到 '\0' 為止。

優勢:相比 strcat,它提供了長度控制,避免了因 source 過長而導致的溢出。只要 destination 本身的空間足夠(包含了原有內容、要追加的內容和\0),它是安全的。

示例:

char dest[20] = "To be";
char src[] = "or not to be";
strncat(dest, src, 6); // 追加 "or not" 的前6個字符
printf("%s\n", dest); // 輸出: To beor not

九、strncmp:限定長度的比較

int strncmp(const char *str1, const char *str2, size_t num); 比較兩個字符串的前 num 個字符。

  • 返回值:指向 haystack 中匹配位置的指針。如果未找到,返回 NULL

  • 核心應用:字符串搜索和替換。

char str[] = "This is a simple string";
char *pch = strstr(str, "simple");
if (pch != NULL) {strncpy(pch, "sample", 6); // 將 "simple" 替換為 "sample"// 注意:這里用 strncpy 是因為知道長度,且 "sample" 長度等于 "simple"// 更安全的做法是使用 snprintf(pch, 7, "sample");
}
printf("%s\n", str); // 輸出: This is a sample string

模擬實現(經典算法):

char *my_strstr(const char *haystack, const char *needle) {if (!*needle) return (char *)haystack; // 空字符串總是匹配const char *h, *n;while (*haystack) {h = haystack;n = needle;// 嘗試從當前位置開始匹配while (*h && *n && *h == *n) {h++;n++;}// 如果needle完全匹配了if (!*n) {return (char *)haystack;}haystack++; // 移動到下一個起始位置}return NULL;
}

思路:遍歷 haystack 的每一個位置,嘗試與 needle 匹配。十一、strtok:字符串分割的利器

十一、strtok:字符串分割的利器

char *strtok(char *str, const char *delim); 將一個字符串按照指定的分隔符序列切分成一系列“標記”(token)。

11.1 工作方式:

首次調用:str 指向要分割的字符串。strtok 會修改 str,在遇到的每個分隔符處插入 '\0',并返回指向第一個標記的指針。
后續調用:str 傳入 NULL。strtok 會記住上次分割的位置,繼續從那里開始查找下一個標記。
結束:當找不到更多標記時,返回 NULL。

11.2?核心特點與警告

  • 修改原字符串:這是最重要的特性!你傳入的字符串會被永久修改。
  • 線程不安全:它使用靜態變量記錄狀態,因此在多線程環境下不可用(可用 strtok_r 替代)。
  • 分隔符集合delim 是一個包含所有可能分隔符的字符串。例如 ". " 表示空格和點號都是分隔符。
  • 連續分隔符:多個連續的分隔符被視為一個分隔符。

11.3?經典應用:解析IP地址

#include <stdio.h>
#include <string.h>int main() {char ip[] = "192.168.6.111"; // 必須是可修改的數組char *sep = ".";char *token;printf("IP Address Parts:\n");for (token = strtok(ip, sep); token != NULL; token = strtok(NULL, sep)) {printf("%s\n", token);}return 0;
}

輸出:

十二、strerror & perror:調試的明燈

當程序調用系統級函數(如 fopen, malloc, socket)失敗時,C運行時庫會設置一個全局變量 errno,其中包含一個表示錯誤類型的整數。

  • char *strerror(int errnum);:將 errno 中的錯誤碼 errnum 轉換為人類可讀的英文錯誤信息字符串。

  • void perror(const char *s);:這是一個更便捷的封裝函數。它會:

  1. 打印你提供的字符串 s
  2. 打印一個冒號和一個空格 ": "
  3. 打印由 strerror(errno) 得到的錯誤信息。
  4. 最后打印一個換行符。

使用場景:診斷I/O、內存分配、文件權限等錯誤。

#include <stdio.h>
#include <errno.h>
#include <string.h>int main() {FILE *fp = fopen("nonexistent.txt", "r");if (fp == NULL) {// 方法1:使用 strerrorprintf("Error opening file: %s\n", strerror(errno));// 方法2:使用 perror (推薦)perror("Error opening file");// 輸出: Error opening file: No such file or directory}return 0;
}

errno 的值只是一個數字(如 2),strerror(2) 返回 "No such file or directory",這使得程序的錯誤信息變得人性化,極大地提升了調試效率。

總結:

黃金法則:

永遠檢查邊界strcpy, strcat 是定時炸彈。優先考慮 strncpy/strncat,并務必手動確保目標緩沖區有 '\0' 終止。

警惕無符號陷阱:任何涉及 strlen 的算術運算,都要重新審視。

理解副作用strtok 修改原串,strncpy 可能不終止。

善用調試工具strerrorperror 是你的第一道防線。

???????擬實現是檢驗真理的標準:親手實現 strlen, strcpy, strcmp,能讓你深刻理解指針、內存和循環的本質,避免在面試和工作中犯下低級錯誤。

熟練運用這些函數,你就能在C語言的世界中游刃有余,寫出既高效又安全的代碼。

? ? ? ? ? ? ??

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

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

相關文章

閃電科創-交通信號燈仿真SUMO

閃電科創計算機人工智sci/ei會議/ccf/核心&#xff0c;擅長機器學習&#xff0c;深度學習&#xff0c;神經網絡&#xff0c;語義分割等計算機視覺&#xff0c;精通大小論文潤色修改&#xff0c;代碼復現&#xff0c;創新點改進等等

2025智能制造研發效率提升指南:從“項目-流程-數據”閉環看工具選型

一、引言&#xff1a;12年智能制造老兵的一線觀察我在智能制造領域從業12年&#xff0c;先后主導過5家制造企業的研發流程數字化轉型&#xff0c;從汽車零部件到高端裝備制造&#xff0c;見證了太多研發團隊因工具選型不當導致的效率損耗&#xff1a;項目進度卡在審批流程里、測…

spring中case一直返回else中的值-問題和原理詳解

目錄 案例背景 問題現象 問題根源 解決過程 最終結論 經驗總結 案例背景 在基于 Spring Boot MyBatis 的項目中&#xff0c;需要通過 SQL 的 CASE WHEN 語句生成 user_Name字段&#xff08;表示是否有關聯用戶名稱&#xff0c;1 為有關聯&#xff0c;0 為無關聯&#xf…

Apache IoTDB V1.3.5 發布|優化加密算法,優化內核穩定性,修復社區反饋問題

Release AnnouncementVersion 1.3.5 Apache IoTDB V1.3.5 已經發布&#xff01;V1.3.5 作為之前 1.3.x 的 bugfix 版本升級&#xff0c;主要調整用戶密碼加密算法&#xff0c;進一步強化數據訪問安全&#xff0c;同時優化內核穩定性&#xff0c;修復社區反饋問題。歡迎點擊閱讀…

開源好用的博客系統簡介和詳細安裝教程

目錄 看效果 ① 搜索一鍵安裝包 ② 填寫安裝信息 ③ 使用界面安裝向導 ④ 安裝完成 使用普通模式安裝 看效果 下面直接來安裝教程 ① 搜索一鍵安裝包 登錄寶塔后臺系統&#xff0c;進入軟件商店 → 一鍵部署&#xff0c;搜索 “ModStart”。 ② 填寫安裝信息 點擊“一鍵…

醫院高值耗材智能化管理路徑分析(下)

醫保協同:政策適配與編碼聯動的精準付費 國家醫保局"帶碼采購、帶碼使用、帶碼結算"政策推動下,AI系統通過編碼映射與實時規則引擎實現醫保支付的動態適配。國醫科技構建的UDI編碼、醫保編碼與收費編碼三碼聯動體系,可在耗材使用時自動匹配國家醫保醫用耗材分類與…

硬件開發2-ARM裸機開發1-I.MX6ULL - 匯編點燈

一、概念概要1、LED原理圖2、內核中對應的引腳 — GPIO&#xff08;1&#xff09;概念GPIO&#xff08;通用輸入/輸出&#xff09;詳解GPlO&#xff08;General-PurposeInput/Output&#xff09;是嵌入式系統和微控制器中最基本的外設接口&#xff0c;用于 實現數字信號的輸入和…

Qwen3-80B-A3B混合注意力機制

一、注意力機制背景&#xff1a; 在Transformer架構中&#xff0c;自注意力&#xff08;Self-Attention&#xff09;是核心組件。其基本公式為&#xff1a; 其中&#xff1a; Q (Query)&#xff1a;查詢向量&#xff0c;表示問詢量。用于與其他位置的Key交互&#xff0…

數據庫(一)數據庫基礎及MySql 5.7+的編譯安裝

文章目錄前言一、數據庫概述1.1 前置知識1.1.1 LAMP / LNMP 架構1.1.2 數據庫的定位1.2 數據庫基本概念1.2.1 數據1.2.2 表1.2.3 數據庫1.2.4 數據庫管理系統&#xff08;DBMS&#xff09;1.2.5 數據庫系統&#xff08;DBS&#xff09;1.3 數據庫發展史1.3.1 第一階段&#xff…

Elasticsearch HTTPS訪問錯誤解決指南

文章目錄&#x1f50d; 原因分析? 正確的訪問方式&#xff1a;使用 curl -k https://...&#x1f510; 你需要知道 elastic 用戶的密碼方法 1&#xff1a;查看首次生成的密碼&#xff08;如果剛安裝&#xff09;方法 2&#xff1a;重置密碼? 成功示例&#x1f389; 總結&…

Neural ODE原理與PyTorch實現:深度學習模型的自適應深度調節

對于神經網絡來說&#xff0c;我們已經習慣了層狀網絡的思維&#xff1a;數據進來&#xff0c;經過第一層&#xff0c;然后第二層&#xff0c;第三層&#xff0c;最后輸出結果。這個過程很像流水線&#xff0c;每一步都是離散的。 但是現實世界的變化是連續的&#xff0c;比如…

Elasticsearch面試精講 Day 16:索引性能優化策略

【Elasticsearch面試精講 Day 16】索引性能優化策略 在“Elasticsearch面試精講”系列的第16天&#xff0c;我們將深入探討索引性能優化策略。這是Elasticsearch高頻面試考點之一&#xff0c;尤其在涉及高并發寫入、海量日志處理或實時數據分析場景時&#xff0c;面試官常通過…

ESP32-C3 入門09:基于 ESP-IDF + LVGL + ST7789 的 1.54寸 WiFi 時鐘(SquareLine Studio 移植)

一. https://github.com/nopnop2002/esp-idf-st7789 1. 前言 2. 開發環境準備 2.1 硬件清單 ESP32-C3 開發板ST7789 1.54 寸 LCD其他輔助元件&#xff08;杜邦線、電源&#xff09; 2.2 軟件安裝 ESP-IDF 環境安裝&#xff08;WindowsVScode&#xff09;VSCode 插件配置LV…

PINN物理信息神經網絡驅動的三維聲波波動方程求解MATLAB代碼

MATLAB 代碼實現了一個基于物理信息神經網絡&#xff08;Physics-Informed Neural Network, PINN&#xff09;的三維波動方程求解器。以下是詳細分析&#xff1a;&#x1f9e0; 一、主要功能&#x1f517; 二、邏輯關聯 代碼結構清晰&#xff0c;分為五個主要部分&#xff1a; …

leetcode33(最小棧)

設計一個支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常數時間內檢索到最小元素的棧。實現 MinStack 類:MinStack() 初始化堆棧對象。void push(int val) 將元素val推入堆棧。void pop() 刪除堆棧頂部的元素。int top() 獲取堆棧頂部的元素。int getMin(…

TDesign學習:(二)i18n配置與使用

配置 src/locales/lang/en_US/pages 目錄下對應的各個模塊語言的對象

k8s 內置的containerd配置阿里云個人鏡像地址及認證

原因&#xff1a;阿里云倉庫必須使用憑證登錄&#xff0c;不然無法進行鏡像拉取&#xff01;1.生成自己的憑證信息# 格式&#xff1a;阿里云倉庫用戶名:憑證密碼 echo -n myuser:mypass | base64 #生成的加密憑證 bXl1c2VyOm15cGFzcw2.修改containerd的鏡像倉庫配置vi /etc/co…

Python實戰:HTTP接口數據獲取與PostgreSQL存儲系統

項目背景 項目結構 關鍵技術點 1. 靈活的HTTP請求處理 2. 自動表結構生成與字段類型推斷 3. 健壯的數據庫操作與錯誤處理 4. 配置驅動的設計理念 功能實現 1. 數據獲取流程 2. 命令行參數支持 2. 數據處理與字段排除 項目擴展與優化方向 結語 項目背景 在日常開發和數據分析工…

遞歸,搜索與回溯算法

遞歸→搜索→回溯 名詞解釋 遞歸 1.什么是遞歸 形象地說就是函數自己調用自己。 例子&#xff1a; 二叉樹的遍歷-后序遍歷 void dfs(treenode* root) {//細節 - 出口if(root NULL) return;dfs(root->left);dfs(root->right);printf(root->val); }快排 void quickSort…

【OpenAPI】OpenAPI 3.0x 格式解析技術指南

OpenAPI 格式解析技術指南 概述 OpenAPI&#xff08;原名 Swagger&#xff09;是一種用于描述 REST API 的規范格式&#xff0c;它提供了標準化的方式來定義 API 的結構、參數、響應等信息。本文將深入探討如何解析 OpenAPI 文檔&#xff0c;并基于實際項目中的 openapi-pars…