C语言 字符串

news2024/11/19 17:29:55

C语言 字符串

  • 引言
  • 一、字符串的创建方式
  • 二、字符串函数
    • 1. strlen 函数
      • 使用示例1
      • 使用示例2
      • 模拟 strlen 函数
    • 2. strcpy 函数
      • 使用示例
      • 模拟 strcpy 函数
    • 3. strcat 函数
      • 使用示例
      • 模拟 strcat 函数
    • 4. strcmp 函数
      • 使用示例
      • 模拟 strcmp 函数
    • 5. strncpy、strncat、strncmp
    • 6. strstr 函数
      • 使用示例
      • 模拟 strstr 函数
    • 7. strtok 函数
      • 使用示例1
      • 使用示例2
  • 三、字符函数
    • 使用示例
  • 四、内存操作函数
    • 1. memset 函数
      • 使用示例
    • 2. memcmp
      • 使用示例
    • 3. memcpy 函数
      • 使用示例
    • 4. memmove 函数
      • 使用示例

引言

C语言中对字符和字符串的处理很频繁,但 C语言本身是没有字符串类型的,所以字符串通常放在常量字符串中或者字符数组中。

一、字符串的创建方式

程序清单:

#include <stdio.h>
#include <string.h>

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abc\0def";
	char arr3[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
	char arr4[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0'};

	printf("%s\n", arr1);
	printf("%s\n", arr2);
	printf("%s\n", arr3);
	printf("%s\n\n", arr4);

	printf("%d\n", strlen(arr1));
	printf("%d\n", strlen(arr2));
	printf("%d\n", strlen(arr3)); // 随机值
	printf("%d\n", strlen(arr4));

	return 0;
}

输出结果:

1-1

调试窗口:

1-2

注意事项:

① 在 C语言中,被双引号括起来是字符串字面值,简称为字符串。同样地,字符串也只能被双引号括起来。

② 字符串的结束标志是一个 ’ \0 ’ 的转义字符。在使用格式化输出时,’ \0 ’ 的作用相当于告诉了编译器,它是一个停止的标志。在使用 strlen 这个库函数计算字符串的长度时,也是一样的道理,它只计算 ’ \0 ’ 之前的长度。

③ 对比 arr1 和 arr3 这两个创建字符数组的方式,可以发现,由于在 C语言 中,内存具有连续性,所以如果没有 ’ \0 ’ 作为结束标志,就会导致我们使用 printf / strlen 的时候,一直向后找 ’ \0 ’ 这个结束标志。

1-3

二、字符串函数

1. strlen 函数

strlen - string length - 计算字符串长度

size_t strlen ( const char* str );

// 返回值:字符串中出现的字符个数(不包含 '\0')
// 参数:需要计算的起始位置的指针

这里应该注意 strlen 返回的类型为无符号数。

使用示例1

#include <stdio.h>
#include <string.h>

int main() {

	char arr[] = "abcdef";
	char arr2[] = "abc\0def";
	printf("%d\n", strlen(arr)); // arr 表示数组名,即数组的起始地址
	printf("%d\n", strlen(arr2));

	return 0;
}

// 输出结果:
// 6
// 3

使用示例2

#include <stdio.h>
#include <string.h>

int main(){
	const char* str1 = "abcdef";  // 6
	const char* str2 = "bbb";	  // 3

	if (strlen(str2) - strlen(str1) < 0){
		printf("正确\n");
	}else{
		printf("错误\n");
	}

	return 0;
}

// 输出结果:错误

注意: 由于 strlen 函数的返回值是无符号类型的,所以我们所理解的 " -3 ",其实输出的是一个很大的正整数。

模拟 strlen 函数

#include <stdio.h>
#include <assert.h>

size_t my_strlen(const char* start) {
	assert(start != NULL);

	int count = 0;
	while (*start != '\0') {
		start++;
		count++;
	}
	return count;
}

int main() {

	char arr[] = "abcdef";
	char arr2[] = "abc\0def";
	printf("%d\n", my_strlen(arr));
	printf("%d\n", my_strlen(arr2));

	return 0;
}

// 输出结果:
// 6
// 3

2. strcpy 函数

strcpy - string copy - 字符串拷贝

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

// 返回值:返回 destination 的副本
// 参数:destination 为粘贴的起始指针,source 为字符串复制的起始指针

注意事项:

① 源字符串必须以 ‘\0’ 结束。
② 拷贝操作会将源字符串中的 ‘\0’ 拷贝到目标空间。
③ 目标空间必须足够大,以确保能存放源字符串。
④ 目标空间必须为一个可修改的字符串,而不是字符串常量值。

使用示例

#include <stdio.h>
#include <string.h>

int main() {

	char arr1[] = "hello world";
	char arr2[] = "xxxxxxxxxxxxxx";

	printf("%s\n", arr2);
	strcpy(arr2, arr1);

	printf("%s\n", arr2);

	return 0;
}

// 输出结果:
// xxxxxxxxxxxxxx
// hello world

调试过程:

1-4

注意事项:

在调试窗口中,我们可以看到 arr2 数组中也被存入了 ‘\0’ 字符。由于 printf 打印的时候,是将 ‘\0’ 之前的字符作为输出内容的,所以后面的 XX 便不会被打印出来。

模拟 strcpy 函数

模拟思想:将目标空间的字符,进行逐个替换。

#include <stdio.h> 
#include <assert.h>

char* my_strcpy(char* end, char* start) {

	assert(start != NULL);		// 断言
	assert(end != NULL);

	char* ret = end;			// 返回粘贴数组的起始地址

	while (*start != '\0') {
		*end = *start;			// 解引用替换值
		start++;
		end++;
	}
	*end = *start;				// 把 '\0' 也进行替换

	return ret;
}

int main() {

	char arr1[] = "hello world";
	char arr2[] = "xxxxxxxxxxxxxx";

	printf("%s\n", arr2);
	printf("%s\n", my_strcpy(arr2, arr1)); // 函数的链式访问

	return 0;
}

// 输出结果:
// xxxxxxxxxxxxxx
// hello world

3. strcat 函数

strcat - 字符串追踪

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

// 返回值:返回 destination 的副本
// 参数:destination 追踪目标的指针,source 为字符串的源头指针

注意事项:

① 源字符串必须以 ‘\0’ 结束。
② 追踪操作会将源字符串中的 ‘\0’ 放到目标空间。
② 目标空间必须有足够的大,能容纳下源字符串的内容。
③ 目标空间必须为一个可修改的字符串,而不是字符串常量值。

使用示例

#include <stdio.h>
#include <string.h>

int main() {

	char arr1[20] = "hello";
	char arr2[] = "world";
	printf("%s\n", arr1);

	strcat(arr1, arr2);
	printf("%s\n", arr1);

	return 0;
}

// 输出结果:
// hello
// helloworld

模拟 strcat 函数

模拟思想:

1. 找到目标空间的 ‘\0’.
2. 对目标空间 ‘\0’ 之后的字符,进行字符串替换。

#include <stdio.h>
#include <string.h>
#include <assert.h>

char* my_strcat(char* dest, const char* source) {
	assert(dest != NULL);
	assert(source != NULL);
	char* ret = dest;

	// 1. 找到目标空间的 '\0'
	while (*dest != '\0') {
		dest++;
	}

	// 2. 进行字符拷贝
	while (*source != '\0') {
		*dest = *source;
		dest++;
		source++;
	}
	*dest = *source;
	return ret;
}

int main() {

	char arr1[20] = "hello";
	char arr2[] = "world";
	printf("%s\n", arr1);
	printf("%s\n", my_strcat(arr1, arr2));

	return 0;
}

// 输出结果:
// hello
// helloworld

4. strcmp 函数

strcmp - string compare - 字符串比较

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

// 参数:两个待比较字符串的起始指针
// 返回值:
// 第一个字符串大于第二个字符串,则返回大于 0 的数字
// 第一个字符串等于第二个字符串,则返回 0
// 第一个字符串小于第二个字符串,则返回小于 0 的数字

注意事项:

strcmp 函数比较不是字符串的长度,而是比较字符串中对应位置上的字符大小,如果相同就比较下一对,直到两个比较的字符不同或者都遇到了 ‘\0’ 才会停止。实际上,在 C语言 中,比较的也就是字符对应的 ASCII 码值。

使用示例

#include <stdio.h>
#include <string.h>

int main() {

	char arr1[] = "abcd";
	char arr2[] = "abc";
	char arr3[] = "abcz";
	char arr4[] = "abcd";
	char arr5[] = "abz";

	printf("%d\n", strcmp(arr1, arr2));
	printf("%d\n", strcmp(arr1, arr3));
	printf("%d\n", strcmp(arr1, arr4));
	printf("%d\n", strcmp(arr1, arr5));

	return 0;
}

// 输出结果:
// 1
// -1
// 0
// -1

注意事项: 虽然我们看到在 VS 编译器底下输出的 1,-1,0. 但在官方的标准文档中,输出规定的是大于0,小于0,或者为0.

模拟 strcmp 函数

模拟思想:挨个比较字符之间的 ASCII 码值,相同的字符就直接往后跳,如果遇到两个不同的字符,则开始比较。直至遇到 ‘\0’ 结束。

#include <stdio.h>
#include <assert.h>

int my_strcmp(const char* str1, const char* str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	
	int ret = 0;
	
	while (*str1 == *str2) {
		if (*str1 == '\0' || *str2 == '\0') {
			break;
		}
		str1++;
		str2++;
	}

	if (*str1 < *str2) {
		ret = -1;
	}else if (*str1 > *str2) {
		ret = 1;
	}

	return ret;
}

int main() {

	char arr1[] = "abcd";
	char arr2[] = "abc";
	char arr3[] = "abcz";
	char arr4[] = "abcd";
	char arr5[] = "abz";
	
	printf("%d\n", my_strcmp(arr1, arr2));
	printf("%d\n", my_strcmp(arr1, arr3));
	printf("%d\n", my_strcmp(arr1, arr4));
	printf("%d\n", my_strcmp(arr1, arr5));

	return 0;
}

// 输出结果:
// 1
// -1
// 0
// -1

5. strncpy、strncat、strncmp

strcpy、strcat、strcmp 是一组长度不受限制的字符串函数。
而 strncpy、strncat、strncmp 是一组长度受限制的字符串函数。

所谓长度受限制,就是相比于前者,多了一个 size_t 类型的参数。例如:strncpy 就可以指定拷贝字符的数量、strncat 就可以指定追踪字符的个数、strncmp 就可以指定比较的字符个数。

6. strstr 函数

strstr - string string - 找子串

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

// 返回值:返回 str1 中的子串起始指针
// 参数:str1 为主串,str2 为子串

使用示例

#include <stdio.h>
#include <string.h>

int main() {

	char arr1[] = "abcdefxyxyzwe";
	char arr2[] = "bcd";
	char arr3[] = "xyz";
	char arr4[] = "xyw";

	printf("%s\n", strstr(arr1, arr2));
	printf("%s\n", strstr(arr1, arr3));
	printf("%s\n", strstr(arr1, arr4));

	return 0;
}

// 输出结果:
// bcdefxyxyzwe
// xyzwe
// (null)

模拟 strstr 函数

模拟思路:额外创建三个指针,s1, s2, flag.
flag 指针作为标志主串中子串的起始位置,s2 指针用来重置子串的开头,s1 指针用来和 s2 进行比较是否为相同字符。

模拟的三个场景:

1-5

#include <stdio.h>
#include <assert.h>

char* my_strstr(const char* str1,  const char* str2) {

	assert(str1 != NULL);
	assert(str2 != NULL);

	const char* s1 = str1;			
	const char* s2 = str2;			// str2 用来重置 s2
	char* flag = str1;				// flag 指针用来记录需要返回的位置

	while (*flag != '\0') {
		s1 = flag;
		s2 = str2;
		while ( (*s1 == *s2) && (*s1 != '\0') && (*s2 != '\0') ) {
			s1++;
			s2++;
		}
		if (*s2 == '\0') {
			// s2 走到字符串末尾,说明子串已经被找到
			return flag;
		}
		flag++;
	}

	return NULL;
}

int main() {

	char arr1[] = "abcdefxyxyzwe";
	char arr2[] = "bcd";
	char arr3[] = "xyz";
	char arr4[] = "xyw";

	printf("%s\n", my_strstr(arr1, arr2));
	printf("%s\n", my_strstr(arr1, arr3));
	printf("%s\n", my_strstr(arr1, arr4));

	return 0;
}

// 输出结果:
// bcdefxyxyzwe
// xyzwe
// (null)

7. strtok 函数

strtok - 字符串分割函数

char* strtok ( char* str, const char* sep );

// 返回值:返回被分割的标记指针,若字符串被分割没有更多的标记,则返回 NULL
// 参数:str 为目标字符串,sep 为标记分隔符

使用示例1

1-6

经过上面的程序,可以得出结论:

① 字符串的内容经 strtok 函数分割后,会被改变,标记分隔符处会被改变为 ‘\0’.
② 当 strtok 函数的第一个参数不为 NULL 时,则会找到字符串的第一个起始指针;当 strtok 函数的第一个参数为 NULL 时,则表示从分隔符后继续寻找。

分割过程如下:

hello | world , 你好 | 世界

hello \0 world , 你好 | 世界			-> return 'h' 的地址
hello \0 world \0 你好 | 世界		-> return 'w' 的地址
hello \0 world \0 你好 \0 世界		-> return '你' 的地址
									-> return NULL

使用示例2

#include <stdio.h>
#include <string.h>

int main() {

	char arr[] = "hello|world,你好|世界";
	const char* sep = ",|";
	char* str = NULL;

	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep)) {
		printf("%s\n", str);
	}

	printf("\n%s\n", arr);

	return 0;
}

// 输出结果:
// hello
// world
// 你好
// 世界

三、字符函数

1-7

使用示例

#include <stdio.h>
#include <ctype.h>

int main() {

	char ch = 'A';
	int ret = islower(ch);
	printf("%d\n", ret); 			// 0

	printf("%c\n", tolower(ch)); 	// a
	return 0;
}

四、内存操作函数

注意事项:

内存操作函数,顾名思义,它是对内存操作的,换言之,它就是以字节为单位来操作数据的,明白这一点很重要。单位既不是字符、也不是整型…

1. memset 函数

memset - memory set - 内存设置函数 - 以字节为单位设置数据

void* memset( void* dest, int ch, size_t count );

// 返回值:dest 的副本
// 参数:dest 表示需要操作的起始指针位, ch 表示需要填充的数据, count 表示需要设置字节的数量

使用示例

将 arr 数组的前 8 个字节分别设置成 1;千万不要理解成将前两个元素设置成 1.

1-8

2. memcmp

memcmp - memory compare - 内存比较函数 - 以字节为单位比较两个数据

int memcmp( const void* str1, const void* str2, size_t count );

// 返回值:
// 第一个数据大于第二个数据,则返回大于 0 的数字
// 第一个数据等于第二个数据,则返回 0
// 第一个数据小于第二个数据,则返回小于 0 的数字

// 参数:str1 为第一个数据的起始指针,str2 为第二个数据的起始指针, count 表示需要比较的字节数

使用示例

#include <stdio.h>
#include <string.h>

int main() {

	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,4,0x11223305 };
	int ret1 = memcmp(arr1, arr2, 16);
	int ret2 = memcmp(arr1, arr2, 18);
	
	printf("%d, %d\n", ret1, ret2);

	return 0;
}

// 输出结果: 0, -1

// 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 (十六进制 arr1)
// 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 33 22 11 (十六进制 arr2)

3. memcpy 函数

memcpy - memory copy - 内存拷贝函数 - 以字节为单位拷贝数据

void* memcpy ( void* destination, const void* source, size_t count );

// 返回值:destination 的副本
// 参数:destination 为目标空间、source 为源数据、count 表示需要拷贝的字节数

memcpy 函数的使用思想和 strncpy 基本一致,但 memcpy 更加强大,它能够针对各种数据类型进行拷贝,只要涉及内存的,都可以。

使用示例

1-9

4. memmove 函数

memmove 函数和 memcpy 使用的思想基本相同,但早期的 memcpy 在使用时,若源空间和目标空间重叠,就可能出现数据覆盖的情况,所以才有 memmove 的诞生。然而,现在两者几乎没有区别,因为主流的 VS 编译器已经将两者实现差不多了。

使用示例

1-10

2-1

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

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

相关文章

STC 51单片机55——加速度计GY-29 ADXL345

//实现与VB模拟鼠标通信&#xff0c;但是噪声很大 //采用输出角度的方式&#xff0c;输出x与z的角度和y与z的角度 //在VB中将屏幕水平与垂直等分1800份&#xff08;角度*10得到的结果&#xff09; //*************************************** // GY-29 ADXL345 IIC测试程序 // …

VIVADO时序约束之时序例外(set_false_path)

前言 当FPGA设计中的逻辑行为不能满足默认的时序要求时&#xff0c;设计者需要使用时序例外语法对该逻辑行为进行处理&#xff0c;例如&#xff1a;有些结果只需每个一个或多个时钟周期捕获一次。 vivado开发工具支持4个时序例外约束的语法&#xff0c;如下表所示&#xff1a;…

html5播放器禁止拖拽功能实例(教学内容禁止拖动观看)

html5播放器禁止拖拽功能实例&#xff08;常用于场景&#xff1a;企业培训、在线教学内容禁止学员拖动视频进行观看&#xff09; 实例1&#xff1a;参数开启后&#xff0c;视频教学内容或视频课件将不允许拖动进度条。 <div id"player"></div> <scr…

MAC执行graalvm并编译

1.先下载 https://github.com/graalvm/graalvm-ce-builds/releases 解压后放到/Library/Java/JavaVirtualMachines 然后执行sudo xattr -r -d com.apple.quarantine path/to/graalvm/folder/ IDEA添加JDK就是这个包 然后这时候可以正常启动了 原项目启动7秒&#xff0c;用这…

[附源码]计算机毕业设计基于Springboot校园订餐管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于BP神经网络进行手写体识别(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 字符识别长期以来都是采用传统的识别方法, 对印刷体字符的识别率一般只是稳定在96%左右, 未能进一步提高, 而对手写体字符的识…

推荐一款语音识别软件

一、简介 使用接口转换需要输入的语音为文字。 给大家带来一款语音识别软件&#xff0c;想做智能识别语音设备或者想给项目增加功能的同学可以看下 这款软件是使用python写的&#xff0c;其实开发语言无所谓用其他语言也可以写 代码还是挺简单的。 这款软件主要使用接口完成识…

SWMM排水管网水力、水质建模及在海绵城市与水环境保护中的应用

随着计算机的广泛应用和各类模型软件的发展&#xff0c;将排水系统模型作为城市洪灾评价与防治的技术手段已经成为防洪防灾的重要技术途径。美国环保局的雨水管理模型&#xff08;SWMM&#xff09;&#xff0c;是当今世界最为著名的排水系统模型。SWMM能模拟降雨和污染物质经过…

基于树莓派开发板的智能家居系统的设计和实现

目 录 摘 要 I Abstract II 前 言 1 开发工具和技术简介 1 1.1 硬件工具简介 1 1.1.1树莓派2代B板简介 1 1.1.2 其他硬件模块 1 1.2 软件工具介绍 3 1.2.1 Qt 3 1.2.2 Espeak TTS 3 1.2.3 WiringPi 3 1.2.4 PuTTY 5 1.2.5 Win32 Disk Imager 5 1.2.6 SDFormatter4exe 5 1.3 系…

【深度梯度投影网络:遥感图像】

Deep Gradient Projection Networks for Pan-sharpening &#xff08;用于全色锐化的深度梯度投影网络&#xff09; 全色锐化是遥感成像系统获取高分辨率多光谱图像的重要技术。最近&#xff0c;深度学习已经成为最流行的泛锐化工具。提出了一种基于模型的深度全色锐化方法。…

【电动车优化调度】基于模型预测控制(MPC)的凸优化算法的电动车优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

【WLAN】Android 13 WiFi Display 介绍和常规问题分析

Miracast依赖的Wi-Fi技术项有: Wi-Fi Direct:也就是Wi-Fi P2P。它支持在没有AP(Access Point)的情况下,两个Wi-Fi设备直连并通信。 Wi-Fi Protected Setup:用于帮助用户自动配置Wi-Fi网络、添加Wi-Fi设备等。 11n/WMM/WPA2:其中,11n就是802.11n协议,它将11a和11g提供…

python3通过winrm远程执行windows服务器dos命令

Background 在实际项目中&#xff0c;一般使用Linux作为生产服务器&#xff0c;但有时就会出现一些特殊情况&#xff0c;你只能使用windows作为作为服务器&#xff0c;比如说一个用fortran编写的仿真程序&#xff0c;编译环境用的intel的oneAPI&#xff0c;按理说这个编译器是是…

C/C++ 课程设计 | 银行管理系统

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

DP83TG720SWRHARQ1 IC TRANSCEIVER 接口芯片、TCAN1051VDRBTQ1

1、TCAN1051VDRBTQ1 具有 CAN FD 和故障保护功能的汽车类 CAN 收发器。 详细参数 类型&#xff1a;收发器 协议&#xff1a;CANbus 驱动器/接收器数&#xff1a;1/1 双工&#xff1a;半 接收器滞后&#xff1a;120 mV 数据速率&#xff1a;2Mbps 电压 - 供电&#xff1a;4.5V ~…

黄菊华老师,Java Servlet毕业设计毕设辅导课(5):Servlet配置虚拟路径映射

Servlet配置虚拟路径映射 在 web.xml 文件中&#xff0c;一个 <servlert-mapping> 元素用于映射一个 Servlet 的对外访问路径&#xff0c;该路径也称为虚拟路径。例如&#xff0c;在《第一个Servlet程序》教程中&#xff0c;hello 所映射的虚拟路径为“/hi”。 创建好的…

数据结构—平衡二叉树

文章目录查询数据的时间复杂度平衡二叉树旋转策略1、LL型旋转&#xff1a;2、RR型旋转&#xff1a;3、LR型旋转&#xff1a;4、RL型旋转&#xff1a;补充&#xff1a;————————————————————————————————查询数据的时间复杂度 首先&#xff0c;…

MySQL学习笔记(十二)锁

1.锁的类型 InnoDB实现了如下两种标准的行级锁&#xff1a; 共享锁&#xff08;S Lock&#xff09;&#xff1a;允许事务对一条行数据进行读取 排他锁&#xff08;X Lock&#xff09;&#xff1a;允许事务对一条行数据进行删除或更新 如果一个事务T1已经获得了行r的共享锁&…

委派设计模式

一、委派模式 1、定义 委派模式&#xff08;Delegate Pattern&#xff09;又称作委托模式&#xff0c;是一种面相对性的设计模式&#xff0c;允许对象组合实现与继承相同的代码重用&#xff0c;属于行为型设计模式&#xff0c;不属于GoF的23种设计模式。 委派模式的基本作用是…

Unity与IOS⭐一、百度语音IOS版Demo调试方法

文章目录 🟥 SDK下载与配置官网包名1️⃣ SDK下载地址2️⃣ 配置官网的包名3️⃣ 百度语音IOS版教程地址🟧 配置SDK Demo1️⃣ 配置License2️⃣ 配置唤醒词文件3️⃣ 打包🟨 Demo测试🟥 SDK下载与配置官网包名 1️⃣ SDK下载地址 SDK下载地址:https://ai.baidu.com…