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

【C语言】字符函数、字符串函数与内存函数

简单不先于复杂,而是在复杂之后。

89efcc89ac61428db4d5b6639b2bd948.jpeg

目录

0. 前言 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

1.1.2.2 递归方法 

1.1.2.3 指针 - 指针方法 

1.2 strcpy 

1.2.1 介绍

1.2.2 strcpy 函数模拟实现

1.3 strcat

1.3.1 介绍

1.3.2 strcat 函数模拟实现

 1.4 strcmp

1.4.1 介绍 

1.4.2 strcmp 函数模拟实现   

1.5 strncpy

 1.5.1 函数介绍

1.6 strncat 

1.6.1 函数介绍 

 1.7 strncmp

 1.7.1 函数介绍 

1.8 strstr 

1.8.1 函数介绍 

1.8.2  strstr 函数模拟实现

1.9 strtok 

1.9.1 函数介绍 

1.10  sterror

1.10.1  函数介绍

1.11  memcpy

1.11.1 函数介绍 

1.11.2 memcpy 函数模拟实现

1.12 memmove 

1.12.1 函数介绍 

 1.12.2 memmove 函数模拟实现

1.13 memcmp

1.13.1 函数介绍 

1.14 memset 

 


0. 前言 

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

字符串常量适用于那些对它不做修改的字符串函数。 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

 

计算字符串长度。 

  •  字符串以 '\0' 为结束标志, strlen 函数返回的是在字符串中 '\0' 前面的字符个数(不包含 \0)。
  • 参数指向的字符串必须要以 \0 结束。
  • 注意函数的返回类型是 size_t 是无符号的。
  • 学会 strlen 的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{//char arr[] = "abcdef";//a b c d e f \0char arr[] = { 'w','o','w' };//[][][][][][][][][w][o][w][][][][][][][][]int len = strlen(arr);//随机值printf("%d\n", len); return 0;
}

 

 

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>size_t my_strlen(const char* str)
{assert(*str);size_t count = 0;while (*str != '\0'){str++;count++;}return count;
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}
1.1.2.2 递归方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>size_t my_strlen(const char* str)
{if (*str == '\0'){return 0;}else{return 1 + my_strlen(str + 1);}
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}
1.1.2.3 指针 - 指针方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>size_t my_strlen(const char* str)
{assert(*str);char* start = str;while (*str != '\0'){str++;}return str - start;
}int main()
{char arr[] = "abcdef";size_t n = my_strlen(arr);printf("%d\n", n);return 0;
}

1.2 strcpy 

1.2.1 介绍

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.2.2 strcpy 函数模拟实现

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char *src)
{//实现字符串拷贝只有需要解引用操作才能找到字符串内容//故两个指针不可为空指针,要对其断言assert(dest);assert(src);char* ret = dest;while (*src){*dest++ = *src++;}*dest = *src;return ret;
}int main()
{char arr1[] = { "abcdef" };char arr2[20] = { 0 };my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

以上代码不够简练,可以优化:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char* src)
{//实现字符串拷贝只有需要解引用操作才能找到字符串内容//故两个指针不可为空指针,要对其断言assert(dest && src);char* ret = dest;while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[] = { "abcdef" };char arr2[20] = { 0 };my_strcpy(arr2, arr1);printf("%s\n", arr2);return 0;
}

这样的话 *dest++ = *src++ 这个语句就做到了既赋值又判断。

1.3 strcat

1.3.1 介绍

 

 字符串追加。

  • 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‘结束。
  • 目标空间必须足够大,能容纳下源字符串的内容.
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
//字符串追加
int main()
{char arr1[20] = "hello";strcat(arr1, "world");printf("%s\n", arr1);return 0;
}

1.3.2 strcat 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>//字符串追加
char* my_strcat(char* dest, const char* src)
{ assert(dest && src);char* ret = *dest;while (*dest != '\0'){dest++;}while (*dest++ = *src++){;}return ret;
}int main()
{char arr1[20] = "hello ";my_strcat(arr1, "world");printf("%s\n", arr1);return 0;
}

如果自己给自己追加,程序会崩溃。

因为当把源字符串的字符逐个拷贝到目标字符串后面的时候,直到该拷贝‘\0’的时候,源字符串的‘\0‘被第一个拷贝过来的字符覆盖掉了,会陷入死循环。

所以我们要尽量避免字符串自己给自己追加。 

 1.4 strcmp

1.4.1 介绍 

 

  • 比较两个字符串是否相等。
  •  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.
  • 标准规定:

                      1. 第一个字符串大于第二个字符串,则返回大于0的数字

                      2. 第一个字符串等于第二个字符串,则返回0

                      3. 第一个字符串小于第二个字符串,则返回小于0的数字

这种写法是在比较两个数组首元素的地址。 

 两个字符串比较是否相等,应该使用 strcmp

一对字符在比较的时候比较的是 ASCII 码值。

1.4.2 strcmp 函数模拟实现   

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>int my_strcmp(const char* str1,const char* str2)
{assert(str1 && str2);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}if (*str1 > *str2)return 1;elsereturn -1;
}int main()
{char arr1[20] = "abc";char arr2[20] = "abc";//比较一下两个字符串是否相等int ret = my_strcmp(arr1, arr2);if (ret < 0)printf("<\0");else if (ret == 0)printf("==\0");elseprintf(">\0");//arr1 和 arr2 是数组名,是数组首元素的地址,必然不相等//if (arr1 == arr2)//{//	printf("==\0");//}//else//{//	printf("!=\0");//}return 0;
}

函数还可以简化:

int my_strcmp(const char* str1,const char* str2)
{assert(str1 && str2);while (*str1 == *str2){if (*str1 == '\0')return 0;str1++;str2++;}return (*str1 > *str2);
}

当目标空间不够时,会产生越界访问导致程序崩溃,但是函数仍然可以将大小超出目标空间的字符串拷贝。 

这是潜在的安全隐患。

1.5 strncpy

 1.5.1 函数介绍

 

  •  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个。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "abcdef";char arr2[] = "hello world";strncpy(arr1, arr2, 5);printf("%s\n", arr1);return 0;
}

 

因为在源字符串后面追加了0,也就是\0, 所以在源字符串小于num时,数组里存放的虽然追加两个0,后面有字符‘f’,但是打印字符串时到第一个‘\0’ 就已经终止了,只能打印源字符串的内容。

1.6 strncat 

1.6.1 函数介绍 

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.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = "hello\0xxxxxxxx ";char arr2[] = "world";strncat(arr1, arr2, 3);return 0;
}

如果 num 大于源字符串,也不会像 strncpy 一样多追加几个 \0 。

 1.7 strncmp

 1.7.1 函数介绍 

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

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>int main()
{char arr1[] = "abcdef";char arr2[] = "abc";int ret = strncmp(arr1, arr2, 3);if (ret == 0)printf("==");else if (ret < 0)printf("<");elseprintf(">");return 0;
}

我们以后在使用字符串函数的时候尽量使用带n的版本,更严谨一些。

1.8 strstr 

1.8.1 函数介绍 

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.
  • 查找子串(str2 是子串)

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{char email[] = "lxz@code.com";char substr[] = "code";char* ret = strstr(email, substr);if (ret == NULL){printf("子串不存在");}else{printf("%s\n", ret);}return 0;
}

1.8.2  strstr 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* s1 = str1;const char* s2 = str2;const char* p = str1;while (*p){s1 = p;s2 = str2;while (*s1 != '\0' && s2 != '\0' && *s1 == *s2){s1++;s2++;}if (*s2 == '\0'){return (char*)p;}p++;}return NULL;
}int main()
{char email[] = "lxz@code.com";char substr[] = "code";char* ret = my_strstr(email, substr);if (ret == NULL){printf("子串不存在");}else{printf("%s\n", ret);}return 0;
}

这样找子串是不够高效的,有一个 KMP 算法,用来实现在一个字符串中查找子字符串,效率高但是实现难度大。 

这里不做赘述。

1.9 strtok 

1.9.1 函数介绍 

char * strtok ( char * str, const char * sep );
  • 切割字符串
  • sep 参数是个字符串,定义了用作分隔符的字符集合。
  • 第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或多个分隔符分割的标记。
  • strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok 函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok 函数的第一个参数不为 NULL,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串中的位置。
  • strtok 函数的第一个参数为 NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{const char* sep = "@.";char email[] = "lxz@code.com";char cp[30] = { 0 };strcpy(cp, email);char* ret = strtok(cp, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);ret = strtok(NULL, sep);printf("%s\n", ret);return 0;
}

因为我们不知道字符串中有几个字段,所以不知道应该调用几次 strtok 函数,所以换一种写法。 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{const char* sep = "@.";char email[] = "lxz@code.com";char cp[30] = { 0 };strcpy(cp, email);char* ret = NULL;for (ret = strtok(cp, sep);ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}//char* ret = strtok(cp, sep);//printf("%s\n", ret);//ret = strtok(NULL, sep);//printf("%s\n", ret);//ret = strtok(NULL, sep);//printf("%s\n", ret);return 0;
}

 这样写利用 for 循环可以适应任意数量字段的字符串。

1.10  sterror

1.10.1  函数介绍

char * strerror ( int errnum );
  •  返回错误码,所对应的错误信息

C语言的库函数,在执行失败的时候,都会设置错误码。

 

 

字符分类函数: 

函数如果他的参数符合下列条件就返回真
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 );//转大写

1.11  memcpy

1.11.1 函数介绍 

void * memcpy ( void * destination, const void * source, size_t num );
  • 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
  • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  • 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的。

memcpy 函数可以用于复制任何类型的数据,无论是字符、整数、浮点数还是自定义数据结构。它不关心数据的具体类型,只是按照指定的字节数进行复制。

由于 memcpy 的参数是 void* 类型,可以轻松地将不同数据类型的数据复制到目标内存中,而不需要进行类型转换。这使得代码更加灵活和可维护。

1.11.2 memcpy 函数模拟实现

 C 语言中 void* 类型的指针不能直接解引用的原因是因为 void* 是一种通用的指针类型,它可以用来存储任何数据类型的地址,但它本身并不知道指向的是什么类型的数据。因此,直接解引用 void* 指针是不允许的,因为编译器无法确定要访问多少字节的内存以及如何解释这些字节。

为了解引用 void* 指针,需要将其转换为一个特定的数据类型的指针,这通常涉及到类型转换。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;	}return ret;
}int main()
{int arr1[] = { 1,2,3,4,5,6,7 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, 28);return 0;
}

memcpy 负责拷贝两块独立空间中的数据,对于重叠的空间,比如将自身空间中的数据拷贝到自身空间中,是不支持的。

重叠空间的拷贝,要用到 memmove 

1.12 memmove 

1.12.1 函数介绍 

 

void * memmove ( void * destination, const void * source, size_t num );
  • 和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠, 就得使用 memmove 函数处理。

   

 1.12.2 memmove 函数模拟实现

         

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);void* ret = dest;if (dest < src){//前->后while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{//后->前while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}void test()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}
}int main()
{test();return 0;
}

1.13 memcmp

1.13.1 函数介绍 

int memcmp ( const void * ptr1,
const void * ptr2,
size_t num );
  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>int main()
{int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00int arr2[] = { 1,3,2 };    //01 00 00 00 03 00 00 00 02 00 00 00int ret = memcmp(arr1, arr2, 12);printf("%d\n", ret);return 0;
}

strcmp 只能比较字符串

memcmp 可以比较任意类型的数据 

1.14 memset 

  • 内存设置 

这个函数以字节为单位初始化内容,会把每个字节改变为要改的值。 

int main()
{int arr[10] = { 0 };memset(arr, 1, 40);int i = 0;for (i = 0; i < 10; i++){printf("%d\n", arr[i]);}return 0;
}

 

相关文章:

【C语言】字符函数、字符串函数与内存函数

简单不先于复杂&#xff0c;而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…...

生成树协议:监控 STP 端口和交换机

什么是生成树协议 生成树协议 &#xff08;STP&#xff09; 用于网络交换机&#xff0c;以防止循环和广播风暴。在局域网 &#xff08;LAN&#xff09; 中&#xff0c;两条或多条冗余路径可以连接到同一网段。当交换机或网桥从所有可用端口传输帧时&#xff0c;这些帧开始在网…...

【黑产攻防道03】利用JS参数更新检测黑产的协议破解

任何业务在运营一段时间之后都会面临黑产大量的破解。验证码和各种爬虫的关系就像猫和老鼠一样, 会永远持续地进行博弈。极验根据十一年和黑产博弈对抗的经验&#xff0c;将黑产的破解方式分为三类&#xff1a; 1.通过识别出验证码图片答案实现批量破解验证&#xff0c;即图片…...

什么是web3.0?

Web 3.0&#xff0c;也常被称为下一代互联网&#xff0c;代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识&#xff0c;但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念&#xff1a; 1. 去中心化 Web 3.0旨在减少…...

二、W5100S/W5500+RP2040树莓派Pico<DHCP>

文章目录 1 前言2 简介2 .1 什么是DHCP&#xff1f;2.2 为什么要使用DHCP&#xff1f;2.3 DHCP工作原理2.4 DHCP应用场景 3 WIZnet以太网芯片4 DHCP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 …...

【开源】基于SpringBoot的天然气工程业务管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…...

讯飞星火大模型V3.0 WebApi使用

讯飞星火大模型V3.0 WebApi使用 文档说明&#xff1a;星火认知大模型Web文档 | 讯飞开放平台文档中心 (xfyun.cn) 实现效果 初始化 首先构建一个基础脚手架项目 npm init vuelatest用到如下依赖 "dependencies": {"crypto-js": "^4.2.0",&q…...

拥有DOM力量的你究竟可以干什么

如果你希望访问 HTML 页面中的任何元素&#xff0c;那么您总是从访问 document 对象开始&#xff01; 查找HTML元素 document.getElementById(id) 通过元素 id 来查找元素 <!DOCTYPE html> <html> <head><meta charset…...

GnuTLS recv error (-110): The TLS connection was non-properly terminated

ubuntu git下载提示 GnuTLS recv error (-110): The TLS connection was non-properly terminated解决方法 git config --global --unset http.https://github.com.proxy...

Notepad++安装插件和配置快捷键

Notepad是一款轻量级、开源的文件编辑工具&#xff0c;可以编辑、浏览文本文件、二进制文件、.cpp、.java、*.cs等文件。Notepad每隔1个月&#xff0c;就有一个新版本&#xff0c;其官网是&#xff1a; https://github.com/notepad-plus-plus/notepad-plus-plus。这里介绍其插件…...

iOS Autolayout 约束设置【顺序】的重要性!

0x00 顺序不同&#xff0c;结果不同 看图说话 1 代码是这样滴~ 设置好约束&#xff0c;让 4 个按钮&#xff0c;宽度均分~ 结果如上图 [_pastButton.topAnchor constraintEqualToAnchor:_textView.bottomAnchor constant:6].active YES;[_pastButton.leftAnchor constraintEq…...

Echarts渲染不报错但是没有内容

&#x1f525;博客主页&#xff1a; 破浪前进 &#x1f516;系列专栏&#xff1a; Vue、React、PHP ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 问题&#xff1a;在开发项目的时候使用了Echarts但是好端端的忽然就不渲染了 感觉很无语啊&#xff0c;毕竟好好的就不渲染了&am…...

数据结构 | 算法的时间复杂度和空间复杂度【详解】

数据结构 | 算法的时间复杂度和空间复杂度【详解】 1. 什么是数据结构&#xff1f; 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。 2. 什么是算法&#xff1f; 算法(Algorithm):就是定义良好的计算过…...

高级篇之ENC编码器多机位帧同步配置详解

高级篇之ENC编码器多机位帧同步配置详解 一 帧同步方案多样性1. 配合vMIX导播的帧同步方案3. 配合硬件导播的帧同步方案3. 配合芯象导播的帧同步 二 帧同步方案1实现步骤1. 准备设备2. 搭建环境3 配置设备3.1 配置固定机位3.2 配置帧同步转发端3.3 配置vMIX 三 效果对比1 不开帧…...

matlab simulink 四旋翼跟拍无人机仿真

1、内容简介 略 7-可以交流、咨询、答疑 2、内容说明 四旋翼跟拍无人机仿真 四旋翼、无人机 需求分析 背景介绍 无人飞行机器人&#xff0c;是无人驾驶且具有一定智能的空中飞行器。这是一种融合了计算机技术、人工智能技术、传感器技术、自动控制技术、新型材料技术、导航…...

jenkins、ant、selenium、testng搭建自动化测试框架

如果在你的理解中自动化测试就是在eclipse里面讲webdriver的包引入&#xff0c;然后写一些测试脚本&#xff0c;这就是你所说的自动化测试&#xff0c;其实这个还不能算是真正的自动化测试&#xff0c;你见过每次需要运行的时候还需要打开eclipse然后去选择运行文件吗&#xff…...

【阅读和学习代码】VoxelNet

文章目录 将点特征 转换为 voxel 特征稀疏张量 到 稠密张量&#xff0c;反向索引参考博客 将点特征 转换为 voxel 特征 https://github.com/skyhehe123/VoxelNet-pytorch/blob/master/data/kitti.py 【Python】np.unique() 介绍与使用 self.T &#xff1a; # maxiumum numbe…...

【23种设计模式】接口隔离原则

个人主页&#xff1a;金鳞踏雨 个人简介&#xff1a;大家好&#xff0c;我是金鳞&#xff0c;一个初出茅庐的Java小白 目前状况&#xff1a;22届普通本科毕业生&#xff0c;几经波折了&#xff0c;现在任职于一家国内大型知名日化公司&#xff0c;从事Java开发工作 我的博客&am…...

【Python机器学习】零基础掌握PartialDependenceDisplay检验、检查

如何更好地理解模型对特定特征的依赖性?如何使用历史数据来预测明天股票市场的走势? 想象一下,作为一名数据分析师,面对海量的数据,如何准确地预测明天股票市场的走势?这是一个复杂且具有挑战性的问题。但别担心,有一种神奇的工具可以帮助解析模型对各种因素(特征)的…...

Jmeter的接口自动化测试

在去年实施了一年的三端&#xff08;PC、无线M站、无线APP【Android、IOS】&#xff09;后&#xff0c;今年7月份开始&#xff0c;我们开始进行接口自动化的实施&#xff0c;目前已完成了整个框架的搭建以及接口的持续测试集成。今天做个简单的分享。 在开始自动化投入前&#…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...