当前位置: 首页 > news >正文

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~zA~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 );
  • 函数memcpysource的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果sourcedestination有任何的重叠,复制的结果都是未定义的。
/* 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,函数在找到空字符后不会停止比较。

  • 比较从ptr1ptr2指针开始的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
注:可以自己研究一下 KMP 算法
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、有个微软的系统更新&#xff0c;就想着更新看看&#xff08;能否冲掉问题&#xff09;4、更新没成功&#xff0c;自动重启电脑5、风险文件&#xff08;好家伙命名还挺规范&#xff0c;一看名字就知道出问题了&#xff09;6、开机有一些注册表…...

计算机xinput1_4.dll丢失怎么修复?

电脑运行时常见问题及修复指南 作为软件开发从业者&#xff0c;深知电脑在日常使用中难免会遇到各种问题&#xff0c;如文件丢失、文件损坏和系统报错等。这些问题不仅影响工作效率&#xff0c;还可能带来数据丢失的风险。本文将详细介绍一些常见问题及其解决办法&#xff0c;…...

高等数学学习笔记 ☞ 连续函数的运算与性质

1. 连续函数的运算 1. 连续函数的四则运算&#xff1a; &#xff08;1&#xff09;若函数在点处连续&#xff0c;则函数在点处也连续。 &#xff08;2&#xff09;若函数在区间上连续&#xff0c;则函数在区间上也连续。 2. 反函数的连续性&#xff1a; 若函数在定义域上是单…...

k8s基础(4)—Kubernetes-Service

Service概述 抽象层 ‌k8s的Service是一种抽象层&#xff0c;用于为一组具有相同功能的Pod提供一个统一的入口地址&#xff0c;并通过负载均衡将网络流量分发到这些Pod上。‌ Service解决了Pod动态变化的问题&#xff0c;例如Pod的IP地址和端口可能会发生变化&#xff0c;通过…...

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可解释神经网络回归模型&#xff08;敏感性分析方法&#xff09; 引言 该文章实现了一个可解释的神经网络回归模型&#xff0c;使用BP神经网络&#xff08;BPNN&#xff09;来预测特征输出。该模型利用七个变量参数作为输入特征进行训练。为…...

【Shell编程 / 4】函数定义、脚本执行与输入输出操作

文章目录 函数 与 脚本定义函数示例&#xff1a;简单的 Shell 函数函数参数返回值 脚本执行创建脚本执行脚本 输入输出输出&#xff1a;echo 和 printf输入&#xff1a;read 命令 命令行参数示例&#xff1a;传递参数 函数 与 脚本 在 Shell 编程中&#xff0c;函数和脚本是组…...

RK3588+麒麟国产系统+FPGA+AI在电力和轨道交通视觉与采集系统的应用

工业视觉识别系统厂家提供的功能主要包括&#xff1a; 这些厂家通过先进的视觉识别技术&#xff0c;实现图像的采集、处理与分析。系统能够自动化地完成质量检测、物料分拣、设备监控等任务&#xff0c;显著提升生产效率和产品质量。同时&#xff0c;系统具备高度的灵活性和可扩…...

MySQL 01 02 章——数据库概述与MySQL安装篇

一、数据库概述 &#xff08;1&#xff09;为什么要使用数据库 数据库可以实现持久化&#xff0c;什么是持久化&#xff1a;数据持久化意味着将内存中的数据保存到硬盘上加以“固化”持久化的主要作用是&#xff1a;将内存中的数据存储在关系型数据库中&#xff0c;当然也可以…...

运行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——记一次二开工具的经历

明天开始考试周&#xff0c;百无聊赖开了一把CTF&#xff0c;还顺带体验了下二开工具&#xff0c;让无聊的Z3很开心&#x1f642; CachedVisitor这题 大概描述一下&#xff1a;从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 随着大型语言模型&#xff08;LLMs&#xff09;的迅速发展&#xff0c;提高其计算效率和存储效率成为研究的重要方向。为了实现这一目标&#xff0c;诸多压缩技术应运而生。本文将深入探讨几种有效的压缩技术&#xff0c;这些技术不仅能够降低…...

Nexus Message Transaction Services(MTS)

Nexus 系列交换机遇到以下情形时&#xff0c;可以尝试查看是否是 MTS 消息卡在缓冲区过多&#xff0c;因为 MTS 负责处理模块内以及跨模块&#xff08;包括跨管理引擎&#xff09;的各服务之间的消息路由和排队。 • CPU 高 • 命令行无响应、响应慢 • 控制平面中断 • 流量问…...

2025年Stable Diffusion安装教程(超详细)

StableDiffusion的安装部署其实并不困难&#xff0c;只需简单点击几下&#xff0c;几分钟就能安装好&#xff0c;不管是windows还是苹果mac电脑&#xff0c;关于StableDiffusion的各种安装方式&#xff0c;这片文章一一来给大家讲明白。&#xff08;所有安装资料都给大家整理好…...

力扣【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含规划路线内容测评分析

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

【Axure高保真原型】引导弹窗

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

Zustand 状态管理库:极简而强大的解决方案

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

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

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

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

macOS 终端智能代理检测

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

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...

用鸿蒙HarmonyOS5实现国际象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码&#xff0c;使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...