C语言进阶(3)--字符函数和字符串函数
重点介绍处理字符和字符串的库函数的使用和注意事项
目录
0.前言
1.函数介绍
1.1 strlen - 计算字符串长度
1.2 strcpy - 复制字符串
1.3 strcat - 追加字符串
1.4 strcmp - 字符串比较
1.5 strncpy - 受限制复制
1.6 strncat - 受限制追加
1.7 strncmp - 受限制比较
1.8 strstr
1.9 strtok
1.10 strerror - 返回错误信息
1.11 memcpy - 内存复制
1.12 memmove
1.13 memcmp - 比较两个内存块
2. 库函数的模拟实现
2.1 模拟实现strlen
2.2 模拟实现strcpy
2.3 模拟实现strcat
2.4 模拟实现strstr
2.5 模拟实现strcmp
2.6 模拟实现memcpy
2.7 模拟实现memmove
- strlen
- strcpy
- strcat
- strcmp
- strncpy
- strncat
- strncmp
- strstr
- strtok
- strerror
- memcpy
- memmove
- memset
- memcmp
0.前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数.
1.函数介绍
1.1 strlen - 计算字符串长度
#include<sdio.h> //头文件size_t strlen ( const char * str );解析:计算sizeof - 操作符 - 计算大小size_t -> unsigned int;
- 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。
- 参数指向的字符串必须要以 '\0' 结束。
- 注意函数的返回值为size_t,是无符号的( 易错 )
- 学会strlen函数的模拟实现
C语言中 strlen 和 sizeof 的区别
1. strlen 是一个库函数使用时需要引用 #include<sdio.h> 这个头文件,而sizeof是一个运算符号;
2.strlen 计算的是'\0'之前的字符个数,sizeof计算的是所占空间内存的大小,单位是字节;3.strlen计算式不包含'\0',而sizeof 包含'\0';4.strlen 遇到 '\0' 才结束;5.sizeof的类型是unsigned int, 是一个无符号的整型;6.strlen 只能用char 做参数,sizeof可以用类型做参数;总结:以上是sizeof和strlen的区别,需要特别注意的是,strlen只有在遇到'\0'时,才会结束,就是只计算'\0'之前的字符,所以我们在使用时一定要记得加上'\0';在使用sizeof 时,必须要记住,数组名是首元素地址,有两个除外:1. sizeof(数组名),计算的是整个数组的大小,单位是字节;2. &数组名,表示的是整个数组的地址;#include<stdio.h> #include<string.h> #include<assert.h>int my_strlen(const char* str) {assert(str);int count = 0;while (*str != '\0'){count++;str++;}return count; } int main() {int len = strlen("abcdef");int len1 = my_strlen("abcdefaaa");printf("%d\n", len);printf("%d\n", len1);return 0; }
#include <stdio.h>
int main()
{const char*str1 = "abcdef";const char*str2 = "bbb";if(strlen(str2)-strlen(str1)>0){printf("str2>str1\n");} else{printf("srt1>str2\n");}return 0;
}
1.指针不知道赋什么值,就给NULL;
2.指针使用完后,赋值NULL;
1.2 strcpy - 复制字符串
#include<string.h>char* strcpy ( char * destination , const char * source );解释:把源文件中的字符串拷贝到目标文件中;
- Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
- 源字符串必须以 '\0' 结束。
- 会将源字符串中的 '\0' 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
- 学会模拟实现。
1.3 strcat - 追加字符串
char * strcat ( char * destination , const char * source );解析:把源文件追加到目标文件后
- Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
- 源字符串必须以 '\0' 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串自己给自己追加,如何?
1.4 strcmp - 字符串比较
int strcmp ( const char * str1 , const char * str2 );
- This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
标准规定:
- 第一个字符串大于第二个字符串,则返回大于0的数字 //>0
- 第一个字符串等于第二个字符串,则返回0 //=0
- 第一个字符串小于第二个字符串,则返回小于0的数字 //<0
- 那么如何判断两个字符串?
1.5 strncpy - 受限制复制字符串
char * strncpy ( char * destination , const char * source , size_t num );
- Copies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
1.6 strncat - 受限制追加字符串
char * strncat ( char * destination , const char * source , size_t num );
- Appends the first num characters of source to destination, plus a terminating null-character.
- If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.
- 译:将源字符串的num个字符追加到目标字符串后,加上一个NULL;
- 译:如果源字符串的长度小于num,则只包含到终止null字符被追加;
/* strncat example */
#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}

1.7 strncmp - 受限制比较字符串
int strncmp ( const char * str1 , const char * str2 , size_t num );
- 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

/* strncmp example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}
1.8 strstr
char * strstr ( const char * str1 , const char * str2 );
- Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");strncpy (pch,"sample",6);puts (str);return 0;
}
1.9 strtok
char * strtok ( char * str , const char * sep );
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
- strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok 函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容 并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}
#include <stdio.h>
int main()
{char *p = "zhangpengwei@bitedu.tech";const char* sep = ".@";char arr[30];char *str = NULL;strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep)){printf("%s\n", str);}
}
1.10 strerror - 返回错误信息
char * strerror ( int errnum );
返回错误码,所对应的错误信息。
/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>//必须包含的头文件
int main ()
{ FILE * pFile;pFile = fopen ("unexist.ent","r");if (pFile == NULL)printf ("Error opening file unexist.ent: %s\n",strerror(errno));//errno: Last error numberreturn 0;
}
Edit & Run
函数 | 如果他的参数符合下列条件就返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v' |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a~z或A~Z |
isalnum | 字母或者数字,a~z,A~Z,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
int tolower ( int c );int toupper ( int c);
/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main ()
{int i=0;char str[]="Test String.\n";char c;while (str[i]){c=str[i];if (isupper(c)) c=tolower(c);putchar (c);i++;}return 0;
}
1.11 memcpy - 内存复制
void * memcpy ( void * destination , const void * source , size_t num );
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 '\0' 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
/* memcpy example */
#include <stdio.h>
#include <string.h>
struct {char name[40];int age;
} person, person_copy;
int main ()
{char myname[] = "Pierre de Fermat";/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)+1 );person.age = 46;/* using memcpy to copy structure: */memcpy ( &person_copy, &person, sizeof(person) );printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );return 0;
}
结果:
1.12 memmove-内存移动
void * memmove ( void * destination , const void * source , size_t num );
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
/* memmove example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[] = "memmove can be very useful......";memmove (str+20,str+15,11);puts (str);return 0;
}
结果:
1.13 memcmp - 比较两个内存块
int memcmp ( const void * ptr1 ,const void * ptr2 ,size_t num );
比较两个内存块
比较第一个数字指向的内存块的字节数ptr1到第一个数字指向的字节数ptr2,如果它们都匹配,则返回零;如果不匹配,则返回一个不同于零的值,表示哪个值更大。
注意,不像strcmp,函数在找到空字符后不会停止比较。
- 比较从ptr1和ptr2指针开始的num个字节
- 返回值如下:

/* memcmp example */
#include <stdio.h>
#include <string.h>int main ()
{char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n=memcmp ( buffer1, buffer2, sizeof(buffer1) );if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);return 0;
}
输出:
'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'.
DWgAOtp12Df0大于DWGAOTP12DF0因为两个单词中第一个不匹配的字符是' g '和' G '分别为,和' g '(103)评估为大于' G ' (71).
2. 库函数的模拟实现
2.1 模拟实现strlen
三种方式:方式 1 ://计数器方式 int my_strlen(const char * str) {int count = 0;while(*str){count++;str++;}return count; }
方式 2 ://不能创建临时变量计数器 int my_strlen(const char * str) {if(*str == '\0')return 0;elsereturn 1+my_strlen(str+1); }
方式 3 ://指针-指针的方式 int my_strlen(char *s) {char *p = s;while(*p != ‘\0’ )p++;return p-s; }
2.2 模拟实现strcpy
//1.参数顺序
//2.函数的功能,停止条件
//3.assert
//4.const修饰指针
//5.函数返回值
//6.题目出自《高质量C/C++编程》书籍最后的试题部分
char *my_strcpy(char *dest, const char*src)
{ char *ret = dest;assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++)){;}return ret;
}
2.3 模拟实现strcat
char *my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);while(*dest){dest++;}while((*dest++ = *src++)){;}return ret;
}
2.4 模拟实现strstr
char* strstr(const char* str1, const char* str2)
{char* cp = (char*)str1;char* s1, * s2;if (!*str2)return((char*)str1);while (*cp){s1 = cp;s2 = (char*)str2;while (*s1 && *s2 && !(*s1 - *s2))s1++, s2++;if (!*s2)return(cp);cp++;}return(NULL);
}
2.5 模拟实现strcmp
int my_strcmp(const char* src, const char* dst)
{int ret = 0;assert(src != NULL);assert(dest != NULL);while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)++src, ++dst;if (ret < 0)ret = -1;else if (ret > 0)ret = 1;return(ret);
}
2.6 模拟实现memcpy
void* memcpy(void* dst, const void* src, size_t count)
{void* ret = dst;assert(dst);assert(src);/**copy from lower addresses to higher addresses*/while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}return(ret);
}
2.7 模拟实现memmove
void* memmove(void* dst, const void* src, size_t count)
{void* ret = dst;if (dst <= src || (char*)dst >= ((char*)src + count)) {/** Non-Overlapping Buffers* copy from lower addresses to higher addresses*/while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst + 1;src = (char*)src + 1;}}else {/** Overlapping Buffers* copy from higher addresses to lower addresses*/dst = (char*)dst + count - 1;src = (char*)src + count - 1;while (count--) {*(char*)dst = *(char*)src;dst = (char*)dst - 1;src = (char*)src - 1;}}return(ret);
}
相关文章:

C语言进阶(3)--字符函数和字符串函数
本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 目录 0.前言 1.函数介绍 1.1 strlen - 计算字符串长度 1.2 strcpy - 复制字符串 1.3 strcat - 追加字符串 1.4 strcmp - 字符串比较 1.5 strncpy - 受限制复制 1.6 strncat - 受限制追加 1.7 strncmp - 受限制比…...
微服务拆分的艺术:构建高效、灵活的系统架构
目录 一、微服务拆分的重要性 二、微服务拆分的策略 1. 按照业务领域拆分 2. 按照团队结构拆分 3. 按照业务边界拆分 4. 按照数据和数据库拆分 5. 按照用户界面或外部接口拆分 6. 按照功能模块或领域驱动设计拆分 7. 按照性能和可伸缩性需求拆分 三、微服务拆分的实践…...

记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)
文章目录 0、总结1、背景2、端倪3、有个微软的系统更新,就想着更新看看(能否冲掉问题)4、更新没成功,自动重启电脑5、风险文件(好家伙命名还挺规范,一看名字就知道出问题了)6、开机有一些注册表…...

计算机xinput1_4.dll丢失怎么修复?
电脑运行时常见问题及修复指南 作为软件开发从业者,深知电脑在日常使用中难免会遇到各种问题,如文件丢失、文件损坏和系统报错等。这些问题不仅影响工作效率,还可能带来数据丢失的风险。本文将详细介绍一些常见问题及其解决办法,…...
高等数学学习笔记 ☞ 连续函数的运算与性质
1. 连续函数的运算 1. 连续函数的四则运算: (1)若函数在点处连续,则函数在点处也连续。 (2)若函数在区间上连续,则函数在区间上也连续。 2. 反函数的连续性: 若函数在定义域上是单…...

k8s基础(4)—Kubernetes-Service
Service概述 抽象层 k8s的Service是一种抽象层,用于为一组具有相同功能的Pod提供一个统一的入口地址,并通过负载均衡将网络流量分发到这些Pod上。 Service解决了Pod动态变化的问题,例如Pod的IP地址和端口可能会发生变化,通过…...
CAN或者CANFD的Busoff的恢复时间会受到报文周期的影响么?
目录 分析恢复机制角度快恢复和慢恢复策略角度特殊情况分析分析 Busoff的恢复时间通常不会直接受到报文周期的影响,以下是具体分析: 恢复机制角度 CAN总线的节点在Busoff状态下,恢复过程主要是等待总线上出现128个连续的11bit隐性位,与报文周期并无直接关联。无论报文周…...

【DevOps】Jenkins部署
Jenkins部署 文章目录 Jenkins部署资源列表基础环境一、部署Gilab1.1、安装Gitlab1.2、修改配置文件1.3、加载配置文件1.4、访问Gitlab1.5、修改root登录密码1.6、创建demo测试项目1.7、上传代码1.8、验证上传的代码 二、部署Jenkins所需软件2.1、部署JDK2.2、部署Tomcat2.3、部…...

【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法)
【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法) 引言 该文章实现了一个可解释的神经网络回归模型,使用BP神经网络(BPNN)来预测特征输出。该模型利用七个变量参数作为输入特征进行训练。为…...
【Shell编程 / 4】函数定义、脚本执行与输入输出操作
文章目录 函数 与 脚本定义函数示例:简单的 Shell 函数函数参数返回值 脚本执行创建脚本执行脚本 输入输出输出:echo 和 printf输入:read 命令 命令行参数示例:传递参数 函数 与 脚本 在 Shell 编程中,函数和脚本是组…...

RK3588+麒麟国产系统+FPGA+AI在电力和轨道交通视觉与采集系统的应用
工业视觉识别系统厂家提供的功能主要包括: 这些厂家通过先进的视觉识别技术,实现图像的采集、处理与分析。系统能够自动化地完成质量检测、物料分拣、设备监控等任务,显著提升生产效率和产品质量。同时,系统具备高度的灵活性和可扩…...

MySQL 01 02 章——数据库概述与MySQL安装篇
一、数据库概述 (1)为什么要使用数据库 数据库可以实现持久化,什么是持久化:数据持久化意味着将内存中的数据保存到硬盘上加以“固化”持久化的主要作用是:将内存中的数据存储在关系型数据库中,当然也可以…...

运行framework7
安装 framework7 下载地址https://gitcode.com/gh_mirrors/fr/framework7-vue node 下载 https://nodejs.cn/#ionic 配置npm 的镜像源 npm config set registry https://registry.npmmirror.com 下载nvm 进行nvm管理https://www.downza.cn/soft/352547.html 我一开始使用node…...

【Web】软件系统安全赛CachedVisitor——记一次二开工具的经历
明天开始考试周,百无聊赖开了一把CTF,还顺带体验了下二开工具,让无聊的Z3很开心🙂 CachedVisitor这题 大概描述一下:从main.lua加载一段visit.script中被##LUA_START##(.-)##LUA_END##包裹的lua代码 main.lua loca…...
实现自定义集合类:深入理解C#中的IEnumerable<T>接口
文章目录 介绍主要成员示例代码约束常见的约束类型示例代码介绍 在C#中,IEnumerable<T> 是一个泛型接口,用于表示可以被枚举的集合。它定义了用于遍历集合中元素的方法和属性。IEnumerable<T> 是 IEnumerable 的泛型版本,提供了类型安全的枚举功能。 当我们实…...
Compression Techniques for LLMs
Compression Techniques for LLMs 随着大型语言模型(LLMs)的迅速发展,提高其计算效率和存储效率成为研究的重要方向。为了实现这一目标,诸多压缩技术应运而生。本文将深入探讨几种有效的压缩技术,这些技术不仅能够降低…...
Nexus Message Transaction Services(MTS)
Nexus 系列交换机遇到以下情形时,可以尝试查看是否是 MTS 消息卡在缓冲区过多,因为 MTS 负责处理模块内以及跨模块(包括跨管理引擎)的各服务之间的消息路由和排队。 • CPU 高 • 命令行无响应、响应慢 • 控制平面中断 • 流量问…...

2025年Stable Diffusion安装教程(超详细)
StableDiffusion的安装部署其实并不困难,只需简单点击几下,几分钟就能安装好,不管是windows还是苹果mac电脑,关于StableDiffusion的各种安装方式,这片文章一一来给大家讲明白。(所有安装资料都给大家整理好…...

力扣【SQL连续问题】
180. 连续出现的数字 SELECT DISTINCT if(a.num b.num AND b.num c.num,a.num,null) AS ConsecutiveNums FROM Logs a LEFT OUTER JOIN Logs b ON a.id1 b.id LEFT OUTER JOIN Logs c ON a.id2 c.id WHERE if(a.num b.num AND b.num c.num,a.num,null) IS NOT NULL603. 连…...

深圳市-地铁线路和站点名称shp矢量数据(精品)2021年-2030最新arcmap含规划路线内容测评分析
深圳市的地铁网络是城市公共交通系统的重要组成部分,随着城市的发展,其规模和覆盖范围也在不断扩大。这份"深圳市-地铁线路和站点名称shp矢量数据(精品)2021年-2030最新arcmap含规划路线.zip"压缩包提供了全面而详细的信…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...