【C/C++】字符函数和字符串函数

文章目录

  • 前言
  • 字符函数和字符串函数
    • 1.字符分类函数
    • 2.字符转换函数
    • 3.strlen的使用和模拟实现
      • 3.1 代码演示
      • 3.2 strlen返回值
      • 3.3 strlen的模拟实现
    • 4.strcpy的使用和模拟实现
      • 4.1 代码演示
      • 4.2 模拟实现
    • 5.strcat的使用和模拟实现
      • 5.1 代码演示
      • 5.2 模拟实现
    • 6.strcmp的使用和模拟实现
      • 6.1 代码演示:
      • 6.2 模拟实现:
    • 7.strncpy函数的使用
      • 7.1 代码演示
      • 7.2 ⽐较strcpy和strncpy函数
    • 8.strncat函数的使用
      • 8.1 代码演示
      • 8.2 strcat和strncat对比
    • 9.strncmp函数的使用
      • 9.1 代码演示
      • 9.2 strcmp和strncmp⽐较
    • 10.strstr的使用和模拟实现
      • 10.1 代码演示
      • 10.2 strstr的模拟实现
    • 11.strtok函数的使用
      • 11.1 代码演示
      • 11.2 注意事项
    • 12.strerror函数的使用
      • 12.1 代码演示
      • 12.2 perror

前言

在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了 ⼀系列库函数,接下来我们就学习⼀下这些函数。

字符函数和字符串函数

1.字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。 这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

在这里插入图片描述

这些函数的使⽤⽅法⾮常类似,我们就讲解⼀个函数的事情,其他的⾮常类似:

int islower ( int c );

islower 是能够判断参数部分的 c 是否是⼩写字⺟的。 通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。

练习:

写⼀个代码,将字符串中的⼩写字⺟转⼤写,其他字符不变。

#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 (islower(c)) c -= 32;putchar(c);i++;}return 0;
}

也可以写成

while(str[i]!='\0')
{if(islower(str[i])){str[i]=toupper(str[i]);}i++;
}

2.字符转换函数

C语⾔提供了2个字符转换函数:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写  
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写 

上⾯的代码,我们将⼩写转⼤写,是-32完成的效果,有了转换函数,就可以直接使⽤ tolower 函 数。

#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 (islower(c)) c = toupper(c);putchar(c);i++;}return 0;
}

3.strlen的使用和模拟实现

size_t strlen ( const char * str );//size_t是无符号整型

功能:统计参数 str 指向的字符串的⻓度。统计的是字符串中 ‘\0’ 之前的字符的个数。

参数:

• str :指针,指向了要统计⻓度的字符串。 返回值:返回了 str 指向的字符串的⻓度,返回的⻓度不会是负数,所以返回类型是 size_t 。

if((strlen("abc")-strlen("abcdef"))>0)//size_t为无符号整型,所以3-6一定大于0
{printf(">\n");//所以输出>
}
else
{printf("<=\n");
}

解决方案

(int)strlen("abc")-(int)strlen("abcdef")

3.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{const char* str = "abcdef";printf("%zd\n", strlen(str));return 0;
}

使⽤注意事项:

• 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包 含 ‘\0’ )。

• 参数指向的字符串必须要以 ‘\0’ 结束。

• 注意函数的返回值为 size_t ,是⽆符号的( 易错 )

• strlen的使⽤需要包含头⽂件

3.2 strlen返回值

#include <stdio.h>
#include <string.h>
int main()
{const char* str1 = "abcdef";const char* str2 = "bbb";if(strlen(str2) - strlen(str1) > 0)//size_t类型恒大于0{printf("str2 > str1\n");} else{printf("srt1 > str2\n");}return 0;
}

3.3 strlen的模拟实现

⽅式1:

//计数器⽅式 
int my_strlen(const char * str)
{int count = 0;assert(str);//assert断言 头文件<assert.h>while(*str){count++;str++;}return count;
}

⽅式2:

//不能创建临时变量计数器 
int my_strlen(const char * str)
{assert(str);if(*str == '\0')return 0;elsereturn 1 + my_strlen(str+1);//str+1是下一个字符的地址
}
比如
my_strlen("abcdef")=1+my_strlen("bcdef")

⽅式3:

//指针-指针的⽅式 
int my_strlen(char *s)
{assert(str);char *p = s;while(*p != '\0')p++;return p - s;
}

4.strcpy的使用和模拟实现

string copy

char* strcpy(char * destination, const char * source );

功能:字符串拷⻉,拷⻉到源头字符串中的 \0 为⽌

参数:

destination :指针,指向⽬的地空间

source :指针,指向源头数据

返回值:

strcpy 函数返回的⽬标空间的起始地址

4.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{char arr1[10] = {0};char arr2[] = "hello";strcpy(arr1, arr2);//\0也会拷贝进去printf("%s\n", arr1);return 0;
}

使⽤注意事项:

•源字符串必须以 ‘\0’ 结束.。

• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。

• ⽬标空间必须⾜够⼤,以确保能存放源字符串。

• ⽬标空间必须可修改。(不能是常量字符串,因为常量字符串不可以修改)

4.2 模拟实现

#include <stdio.h>
#include <assert.h>
//1.参数顺序 
//2.函数的功能,停⽌条件 
//3.assert
//4.const修饰指针 
//5.函数返回值 
char* my_strcpy(char *dest, const char*src)//src不能修改
{ char *ret = dest;//dest++后变了 所以先存起来assert(dest != NULL);assert(src != NULL);while((*dest++ = *src++))//先用再++,当*src为\0时,终止循环{;}return ret;
}
int main()
{char arr1[10] = {0};char arr2[] = "hello";my_strcpy(arr1, arr2);printf("%s\n", arr1);return 0;
}
void my_strcpy(char* dest,char* src)
{
//拷贝\0前面的内容
while(*src!='\0'){*dest=*src;dest++;src++;}*dest=*src;//拷贝\0
}

5.strcat的使用和模拟实现

连接字符串

char * strcat ( char * destination, const char * source );

功能:字符串追加,把 source 指向的源字符串中的所有字符都追加到 destination 指向的空间 中。

参数:

destination :指针,指向⽬的地空间

source :指针,指向源头数据

返回值:

strcat 函数返回的⽬标空间的起始地址

5.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello ";char arr2[] = "world";strcat(arr1, arr2);printf("%s\n", arr1);return 0;//输出hello world
}

使用注意事项:

• 源字符串必须以 ‘\0’ 结束。

• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。

• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• ⽬标空间必须可修改。

5.2 模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);//这两行等价于assert(dest&&src)//1.找到目标空间中的\0while(*dest)//while(*dest!='\0'){dest++;}while((*dest++ = *src++)){;}return ret;
}
int main()
{char arr1[20] = "hello ";char arr2[] = "world";my_strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}

那如果是自拼接呢

my_strcat(arr1,arr1)
//自拼接会:1.死循环2.系统崩溃            

在这里插入图片描述

6.strcmp的使用和模拟实现

两个字符串比较应用场景 登录: 输入 :用户名 密码

​ 数据库 用户名 密码

int strcmp ( const char * str1, const char * str2 );

功能:⽤来⽐较 str1 和 str2 指向的字符串,从两个字符串的第⼀个字符开始⽐较,如果两个字符 的ASCII码值相等,就⽐较下⼀个字符。直到遇到不相等的两个字符,或者字符串结束。

参数:

str1 :指针,指向要⽐较的第⼀个字符串

str2 :指针,指向要⽐较的第⼆个字符串

返回值:

• 标准规定:

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0

◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

6.1 代码演示:

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abq";int ret = strcmp(arr1, arr2);printf("%d\n", ret);if(ret > 0)printf("arr1 > arr2\n");else if(ret == 0)printf("arr1 == arr2\n");elseprintf("arr1 < arr2\n");return 0;
}

6.2 模拟实现:

int my_strcmp (const char * str1, const char * str2)
{int ret = 0 ;assert(str1 != NULL);assert(str2 != NULL);while(*str1 == *str2){if(*str1 == '\0')return 0;str1++;str2++;}return *str1-*str2;//最后比较的ASII码值的差
}

7.strncpy函数的使用

strcpy strcat strcmp 是长度不受限的字符串比较 不安全
strncpy strncat strncmp 长度受限函数

char * strncpy ( char * destination, const char * source, size_t num );

功能:字符串拷⻉;将 source 指向的字符串拷⻉到 destination 指向的空间中,最多拷⻉ num 个字符。

参数

destination :指针,指向⽬的地空间

source :指针,指向源头数据

num :从source指向的字符串中最多拷⻉的字符个数

返回值:

strncpy 函数返回的⽬标空间的起始地址

7.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = {0};char arr2[] = "abcdefghi";char* str = strncpy(arr1, arr2, 5);printf("%s\n", arr1);printf("%s\n", str);return 0;
}

长度足够,让拷贝几个就几个,长度小于num补\0

7.2 ⽐较strcpy和strncpy函数

strcpy 函数拷⻉到 \0 为⽌,如果⽬标空间不够的话,容易出现越界⾏为。

strncpy 函数指定了拷⻉的⻓度,源字符串不⼀定要有 \0 ,同时在设计参数的时候,就会多⼀层 思考:⽬标空间的⼤⼩是否够⽤, strncpy 相对 strcpy 函数更加安全。

8.strncat函数的使用

char * strncat ( char * destination, const char * source, size_t num );

功能:字符串追加;将 source 指向的字符串的内容,追加到 destination 指向的空间,最多追 加 num 个字符。

参数

destination :指针,指向了⽬标空间

source :指针,指向了源头数据

num :最多追加的字符的个数

返回值:返回的是⽬标空间的起始地址

8.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello ";char arr2[] = "world";char* str = strncat(arr1, arr2, 5);//从\0开始追加,追加万还加\0printf("%s\n", arr1);printf("%s\n", str);//若num>长度,则追加\0return 0;
}

8.2 strcat和strncat对比

• 参数不同, strncat 多了⼀个参数

• strcat 函数在追加的时候要将源字符串的所有内容,包含 \0 都追加过去,但是 strncat 函 数指定了追加的⻓度。

strncat 函数中源字符串中不⼀定要有 \0 了。

• strncat 更加灵活,也更加安全。

9.strncmp函数的使用

int strncmp ( const char * str1, const char * str2, size_t num );

功能:字符串⽐较;⽐较 str1 和 str2 指向的两个字符串的内容,最多⽐较 num 字符。

参数:

str1 :指针,指向⼀个⽐较的字符串

str2 :指针,指向另外⼀个⽐较的字符串

num :最多⽐较的字符个数

返回值:

• 标准规定:

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0

◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

在这里插入图片描述

9.1 代码演示

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcqw";int ret1 = strncmp(arr1, arr2, 3);printf("%d\n", ret1);int ret2 = strncmp(arr1, arr2, 4);printf("%d\n", ret2);return 0;
}

9.2 strcmp和strncmp⽐较

• 参数不同

• strncmp可以⽐较任意⻓度了

• strncmp函数更加灵活,更加安全

10.strstr的使用和模拟实现

char * strstr ( const char * str1, const char * str2);

功能:strstr 函数,查找 str2 指向的字符串在 str1 指向的字符串中第⼀次出现的位置。 简⽽⾔之:在⼀个字符串中查找⼦字符串。 strstr 的使⽤得包含<string.h>

参数:

str1 :指针,指向了被查找的字符串

str2 :指针,指向了要查找的字符串
返回值:

• 如果str1指向的字符串中存在str2指向的字符串,那么返回第⼀次出现位置的指针

• 如果str1指向的字符串中不存在str2指向的字符串,那么返回NULL(空指针)

10.1 代码演示

/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");if (pch != NULL)printf("%s\n", pch);elseprintf("查找的字符串不存在\n");return 0;
}
int main()
{char arr1[]="this is an apple\n";const char* p="is";//放的是i的地址char* ret = strstr(arr1,p);printf("%s\n",ret);return 0;
}

10.2 strstr的模拟实现

char * strstr (const char * str1, const char * str2)//str1 str2不希望被修改
{char *cp = (char *) str1;char *s1, *s2;//特殊情况:str2是空字符串时,直接返回str1 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); //找不到则返回NULL 
}

先来一种简单情况 在abcdef 中找 bcd

在这里插入图片描述

str1指向a时,不符合,所以++指向b,此时与*str2相等,然后str2++,再str1++,直到str2指向\0时结束

再来一种复杂情况

在这里插入图片描述

从第一个b开始时没有
可能存在多次匹配
还得有两个指针变量 存放他们两个的起始变量 然后对他们++ 让起始位置向后平移
char* my_strstr(const char* str1,const char* str2)
{const char* s1=NULL;const char* s2=NULL;const char* cur=str1;while(*cur){s1=cur;s2=str2;while(*s1!='\0'&&*s2!='\0'&&*s1==*s2){s1++;s2++;}if(*s2=='\0'){return char* cur;}cur++;}return NULL;
}

strstr函数的实现有多种,可以暴⼒查找,也有⼀种⾼效⼀些的算法:KMP,有兴趣的可以去学习。

11.strtok函数的使用

char *strtok(char *str, const char *delim);
//delim参数指向了一个字符串,定义了用作分隔符的字符的集合

功能

• 分割字符串:根据delim 参数中指定的分隔符,将输⼊字符串str 拆分成多个⼦字符串。

• 修改原始字符串: strtok 会直接在原始字符串中插⼊’\0’ 终⽌符,替换分隔符的位置,因 此原始字符串会被修改。

参数

1.str :⾸次调⽤时传⼊待分割的字符串;后续调⽤传⼊NULL ,表⽰继续分割同⼀个字符串。

2.delim :包含所有可能分隔符的字符串(每个字符均视为独⽴的分隔符)。

返回值

• 成功时返回指向当前⼦字符串的指针。

• 没有更多⼦字符串时返回NULL 。

使⽤步骤

  1. ⾸次调⽤:传⼊待分割字符串和分隔符。
  2. 后续调⽤:传⼊NULL 和相同的分隔符,继续分割。
  3. 结束条件:当返回NULL 时,表⽰分割完成。

11.1 代码演示

int main()
{char arr[]="fnianxu@yeah.net";char arr2[30]={0};//"fnianxu\0yeah\0net"strcpy(arr2,arr);const char* sep="@.";//传入NULL在\0之后继续进行char* ret=NULL;//初始化ret = strtok(arr2,sep);printf("%s\n",ret);ret = strtok(NULL,sep);printf("%s\n",ret);ret = strtok(NULL,sep);printf("%s\n",ret);
}

运行结果如下:

在这里插入图片描述

但一直传入空指针有些麻烦,所以看以下示例

#include <stdio.h>
#include <string.h>
int main()
{char arr[] = "192.168.6.111";const char* sep = ".";const char* str = NULL;char buf[30] = {0};strcpy(buf, arr); //将arr中的字符串拷⻉到buf中,对buf的内容进⾏切割 for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep)){printf("%s\n", str);}return 0;
}

11.2 注意事项

• 破坏性操作: strtok 会直接修改原始字符串,将其中的分隔符替换为’\0’ 。如果需要保留原字符串,应先拷⻉⼀份。

• 连续分隔符:多个连续的分隔符会被视为单个分隔符,不会返回空字符串。

• 空指针处理:如果输⼊的str 为NULL 且没有前序调⽤,⾏为未定义。

12.strerror函数的使用

char* strerror ( int errnum );

功能

1.strerror 函数可以通过参数部分的errnum 表示错误码,得到对应的错误信息,并且返回这个错误信息字符串⾸字符的地址

2.strerror 函数只针对标准库中的函数发⽣错误后设置的错误码的转换。

3.strerror 的使⽤需要包含<string.h>

在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头⽂件中说 明的,C语⾔程序启动的时候就会使⽤⼀个全局的变量 errno 来记录程序的当前错误码,只不过程序启动的时候errno 是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误, 就会将对应的错误码,存放在 errno 中,⽽⼀个错误码的数字是整数,很难理解是什么意思,所 以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误码对应的错误信息字符串的地 址返回。

参数:

errnum :表示错误码

这个错误码⼀般传递的是 errno 这个变量的值,在C语⾔有⼀个全局的变量叫: errno ,当库函数 的调⽤发⽣错误的时候,就会讲本次错误的错误码存放在 errno 这个变量中,使⽤这个全局变量需要 包含⼀个头⽂件 errno.h 。

返回值:

函数返回通过错误码得到的错误信息字符串的⾸字符的地址。

12.1 代码演示

#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息 
int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%d: %s\n", i, strerror(i));}return 0;
}

在Windows11+VS2022环境下输出的结果如下:

0: No error
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted function call
5: Input/output error
6: No such device or address
7: Arg list too long
8: Exec format error
9: Bad file descriptor
10: No child processes

举例:

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{FILE * pFile = NULL;//fopen函数以读的形式打开⽂件,如果⽂件不存在,则打开失败。 pFile = fopen ("unexist.ent", "r");if (pFile == NULL){printf ("错误信息是:%s\n", strerror(errno));return 1;//错误返回 }//读文件 fclose(pf);//关闭文件return 0;//空指针不能解引用
}

输出:

错误信息是:No such file or directory

12.2 perror

也可以了解⼀下 perror 函数, perror 函数相当于⼀次将上述代码中的第11⾏完成了,直接将错误 信息打印出来。 perror 函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误 信息。

perror有能力直接打印错误信息,打印的时候,先打印传给perror的字符串,然后打印冒号,再打印空格,最后打印错误码对应信息

perrpr=printf+strerror

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
{FILE * pFile = NULL;pFile = fopen ("unexist.ent", "r");if (pFile == NULL){perror("错误信息是");return 1;}return 0;
}

输出:

错误信息是: No such file or directory

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/80029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spark-core-RDD入门

RDD基本概念 Resilient Distributed Dataset 叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据抽象&#xff0c;是分布式计算的实现载体&#xff0c;代表一个不可变&#xff0c;可分区&#xff0c;里面的元素并行计算的集合。 - Dataset&#xff1a; 一个数据集合&…

缓存套餐-01.Spring Cache介绍和常用注解

一.Spring Cache 要使用直接导入坐标即可。 如何选择底层的缓存实现呢&#xff1f;只要导入对应的缓存坐标即可。如果要使用redis作为缓存实现&#xff0c;那么只需要导入redis的maven坐标。 二.常用注解 Cacheable&#xff1a;不光往缓存中写缓存数据&#xff0c;而且会从缓…

STM32智能空气净化器项目开发

一、项目概述 本空气净化器项目基于STM32F4系列微控制器&#xff0c;整合多传感器数据采集、环境参数显示、网络通信及执行机构控制等功能&#xff0c;实现智能化空气质量管理。项目采用FreeRTOS实时操作系统进行多任务调度&#xff0c;结合TFT触摸屏实现人机交互&#xff0c;…

[数据处理] 6. 数据可视化

&#x1f44b; 你好&#xff01;这里有实用干货与深度分享✨✨ 若有帮助&#xff0c;欢迎&#xff1a;​ &#x1f44d; 点赞 | ⭐ 收藏 | &#x1f4ac; 评论 | ➕ 关注 &#xff0c;解锁更多精彩&#xff01;​ &#x1f4c1; 收藏专栏即可第一时间获取最新推送&#x1f514;…

嵌入式学习笔记 - STM32 SRAM控制器FSMC

一 SRAM控制器内部结构图&#xff1a; 以下以512K SRAM芯片为例 二 SRAM地址矩阵/寻址方式&#xff1a; SRAM的地址寻址方式通过行地址与列地址交互的方式存储数据 三 STM32 地址映射 从STM32的地址映射中可以看出&#xff0c;FSMC控制器支持扩展4块外部存储器区域&#xff0…

python基础:序列和索引-->Python的特殊属性

一.序列和索引 1.1 用索引检索字符串中的元素 # 正向递增 shelloworld for i in range (0,len(s)):# i是索引print(i,s[i],end\t\t) print(\n--------------------------) # 反向递减 for i in range (-10,0):print(i,s[i],end\t\t)print(\n--------------------------) print(…

phpstudy升级新版apache

1.首先下载要升级到的apache版本&#xff0c;这里apache版本为Apache 2.4.63-250207 Win64下载地址&#xff1a;Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压&#xff0c; 将Apache24复制一份到ph…

开源业务流程:jBPM

一、什么是 jBPM&#xff1f; jBPM 是一个灵活的业务流程管理 (BPM) 套件。它不仅仅是一个流程引擎&#xff0c;而是一个集成了多种功能的平台&#xff0c;旨在帮助企业建模、自动化和监控业务流程。jBPM 遵循业界标准&#xff0c;特别是 BPMN 2.0&#xff08;业务流程模型和标…

JAVA:使用 JMH 进行基准测试的技术指南

1、简述 在性能优化中,写高效代码离不开准确的基准测试。而 Java 的 JIT 编译器会对代码进行优化(如方法内联、死代码消除等),导致简单的测试方法可能得不到真实的性能数据。这时候,JMH(Java Microbenchmark Harness)就派上用场了。 JMH 是 Java 官方提供的基准测试框…

Thinkphp开发自适应职业学生证书查询系统职业资格等级会员证书管理网站

环境&#xff1a;php7.2mysql5.7think伪静态 1.上传压缩包到服务器解压 2.还原数据库 3.配置数据库信息application/database.php 4.后台&#xff1a;http://你的域名/abc.php 用户&#xff1a;admin 密码&#xff1a;123456 程序说明&#xff1a; 【修复版】Thinkphp5开发的自…

(二)毛子整洁架构(CQRS/Dapper/领域事件处理器/垂直切片)

文章目录 项目地址一、Application 层1.1 定义CQRS的接口以及其他服务1. Command2. IQuery查询3. 当前时间服务接口4. 邮件发送服务接口 1.2 ReserveBooking Command1. 处理传入的参数2. ReserveBookingCommandHandler3. BookingReservedDomainEvent 1.3 Query使用Sql查询1. 创…

详解Redis

一.Redis的基本概念 首先&#xff0c;什么是Redis&#xff1f; Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的键值对内存数据库&#xff0c;常被用作缓存、消息队列、分布式锁等。 二.Redis的基本数据类型 1. 字符串&#xff08;String&am…

智慧医院的可视化变革:可视化工具助力数字化转型

在科技飞速发展的当下&#xff0c;智慧医院已从概念逐步落地&#xff0c;深刻改变着传统医疗模式。它借助互联网、数字孪生及人工智能等前沿技术&#xff0c;在医疗服务领域掀起革新&#xff0c;涵盖面向医务人员的“智慧医疗”、面向患者的“智慧服务”以及面向医院的“智慧管…

Ubuntu Linux系统配置账号无密码sudo

在Linux系统中&#xff0c;配置无密码sudo可以通过修改sudoers文件来实现。以下是具体的配置步骤 一、编辑sudoers文件 输入sudo visudo命令来编辑sudo的配置文件。visudo是一个专门用于编辑sudoers文件的命令&#xff0c;它会在保存前检查语法错误&#xff0c;从而防止可能的…

graphviz和dot绘制流程图

graphviz和dot绘制流程图 指令 1.写后端需求文档 2.用中文输出结果 3.必须详细全面 4.必须搭配相关流程图step1:下载graphviz&#xff0c;https://graphviz.org/download/ step2&#xff1a;安装&#xff0c;记得添加环境变量 step3&#xff1a;验证是否安装成功 dot --versio…

MongoDB常用操作示例

以下是基于 MongoDB Shell 的完整操作示例&#xff0c;覆盖数据库管理、集合操作、文档处理、聚合分析、索引管理等核心功能&#xff0c;并结合实际场景说明。所有示例均结合搜索结果中的技术要点整理而成。 一、连接与配置管理 1. 启动 MongoDB Shell 并连接实例 # 默认连接…

C++ 模板方法模式详解与实例

模板方法模式概念​ 模板方法模式(Template Method Pattern)属于行为型设计模式,其核心思想是在一个抽象类中定义一个算法的骨架,而将一些步骤延迟到子类中实现。这样可以使得子类在不改变算法结构的情况下,重新定义算法中的某些步骤。它通过继承机制,实现代码复用和行为…

MySQL基础关键_012_事务

目 录 一、概述 二、ACID 四大特性 三、MySQL 事务 四、事务隔离级别 1.说明 2.现象 &#xff08;1&#xff09;脏读 &#xff08;2&#xff09;不可重复读 &#xff08;3&#xff09;幻读 3.查看隔离级别 4.设置隔离级别 5.隔离级别 &#xff08;1&#xff09;初始…

Hutool中的Pair类详解

1. Pair类概述 Hutool工具库中的Pair类是一个简单的键值对数据结构&#xff0c;用于存储两个相关联的对象。它类似于Map的Entry&#xff0c;但更加轻量级&#xff0c;适用于需要临时存储两个相关联数据的场景。 2. Pair类的主要特点 简单轻量&#xff1a;不依赖复杂的数据结…

02-GBase 8s 事务型数据库 客户端工具dbaccess

dbaccess概述 数据库产品通常会提供一个命令行客户端工具。 数据库厂商 命令行客户端 Oracle sqlplus MySQL mysql Marladb mysql GBase 8s dbaccess Kingbase ES ksql DM8 disql dbaccess 是 GBase 8s 数…