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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…