C语言之常用字符串函数总结、使用和模拟实现

news2024/11/26 15:30:26


文章目录

目录

一、strlen 的使用和模拟实现

二、strcpy 的使用及模拟实现

三、strcat 的使用和模拟实现

四、strcmp 的使用和模拟实现

五、strncpy 的使用和模拟实现

六、strncat 的使用和模拟实现

七、strncmp 的使用和模拟实现

八、strstr 的使用和模拟实现

九、strtok函数的使用

十、strerror 函数的使用

2.补充:perror 函数的使用



前言

        本文介绍和模拟实现的字符串函数有:strlen、strcpy、strcat、strcmp、strncpy、strncat、strncmp、strstr。另外详细介绍了 strtok 、strerror、perror函数的使用。基本囊括了所有常用的字符串函数。模拟实现有助于我们理解和记忆这些库函数,我们都能够自己实现这些库函数,使用时需要注意的细节我们肯定也更加清楚和深刻。最后,希望本文的内容能够帮助到大家更好的理解这些库函数


注意:字符串函数包含的头文件都为 <string.h>

一、strlen 的使用和模拟实现

1.使用:

功能:strlen 函数,其功能相信大家很熟悉了,就是计算字符串的长度

      

函数声明:size_t strlen ( const char * str );

      

用法:传入字符串首字符的地址,计算出的结果将以 size_t 类型返回

(size_t 是一种无符号整形,是为了代码的可移植性而定义的一种自定义类型,使用 %zd 打印)

使用演示:

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

int main()
{
	char ch1[] = { "abcdefg" };
	char* ch2 = "qwertyuiop";

	printf("%zd\n", strlen(ch1));
	printf("%zd\n", strlen(ch2));

	return 0;
}

运行结果:

解疑:上述ch1是数组名,表示数组首元素地址,ch2是字符指针,指向的是一个字符串字面量的首字符地址


2.模拟实现:

想要模拟实现 strlen ,我们就应该了解其机制,strlen 就是通过寻找字符串结尾处的 '\0' 字符来计算字符串的长度的,像我们平时写在双引号中的字符串,其末尾自动包含了一个'\0',我们也可以在定义字符数组的时候在其末尾手动添加 '\0',只有包含了 '\0'的字符串才能被strlen正确的计算长度

以下演示三种 strlen 的模拟实现

(以下所以代码中包含了 assert 函数,其为断言,用来检查指针是否为空,详细请移步主页指针基础知识,其中有详细讲解)

1:边寻找 '\0' 边统计字符

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

size_t my_strlen(const char* str)
{
	assert(str != NULL);
 
	size_t count = 0;

	while (*str)
	{
		str++;
		count++;
	}

	return count;
}

2:通过指针相减算出元素个数

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

size_t my_strlen(const char* str)
{
	const char* str1 = str;

	assert(str != NULL);

	while (*str1)
	{
		str1++;
	}

	return str1 - str;
}

3:使用递归实现

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

	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}


二、strcpy 的使用及模拟实现

1.使用:

功能:将源字符串拷贝到目标字符串之中,返回目标字符串首地址

    

函数声明:char * strcpy ( char * destination, const char * source );

    

用法:按顺序先传入目标字符串,再传入源字符串,最后 strcpy 返回的目标字符串首地址,另外,函数有以下几个要求和细节:

  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够⼤,以确保能存放源字符串。
  • 目标空间必须可修改。因此目标字符串参数没有使用const修饰

使用演示:

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

int main()
{
	char ch1[20] = { "xxxxxxxxxxxxx" };
	char* ch2 = "abcdefg";

	char* ret = strcpy(ch1, ch2);

	printf("%s\n", ch1);
	printf("%s\n", ret);

	return 0;
}

运行结果

解疑:值得注意的是,ch2中的'\0'也会被拷贝到ch1中我们可以通过调试观察到

另外,目标字符串小于原字符串将导致报错


2.模拟实现:

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

char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);

	char* ret = dest;

	while (*dest++ = *src++)
	{
		;
	}

	return ret;
}

解疑:这里面比较难理解的估计就是这个while循环,*dest++ = *src++,首先 ++ 的优先级高于 *,因此先执行++,但因为是后置++,先使用后++,因此会先解引用,将src的值赋给dest,然后++,两字符串地址向后走一个字节长度,来到下一个字符的地址,依次循环下去,最后 src 解引用遇到'\0'赋值给dest后,整个表达式值为0,循环停止,注意循环体为空语句。最后包括'\0'在内的所有字符都从src中拷贝到了dest中,最后的最后返回目标字符串首地址


三、strcat 的使用和模拟实现

1.使用:

功能:将源字符串追加到目标字符串的末尾

    

函数声明:char * strcat ( char * destination, const char * source );

    

用法:先传入目标字符串首地址,再传入源字符串首地址,追加后返回目标字符串首地址

有以下需要注意的细节和要求:

  • 源字符串必须以 '\0' 结束。
  • 目标字符串中也得有 '\0' ,否则没办法知道追加从哪里开始。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。

使用演示:

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

int main()
{
	char ch1[20] = { "abcdef" };
	char ch2[] = { "qwerty" };

	char* ret = strcat(ch1, ch2);

	printf("%s\n", ch1);
	printf("%s\n", ret);

	return 0;
}

2.模拟实现:


2.模拟实现:

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

char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);

	char* ret = dest;

	while (*dest)
	{
		dest++;
	}

	while (*dest++ = *src++)
	{
		;
	}
	
	return ret;
}

解疑:第一个while循环用来定位 dest 中'\0'位置,也就是dest中第一次出现'\0'的位置,第二个循环与前面 strcpy 一样,将源字符串src内容拷贝到目标字符串dest中,只不过是接在dest第一个'\0'的位置处,最后返回目标字符串首地址


另外考虑一个问题,问:strcat 能不能给自己追加自己?

我们使用自己模拟的strcat试一试:

结果是不可以,因为 src 追加后,使得自己变长,永远到不了'\0',结果就会导致死循环

官方的库函数却可以,但其返回值也不可以,底层逻辑的实现不同,这里不再深究


四、strcmp 的使用和模拟实现

1.使用:

功能:比较两字符串大小,不是比较长度,而是按顺序比较每一位对应字符的ASCII码值

    

函数声明:int strcmp ( const char * str1, const char * str2 );

    

用法:分别传入需要比较的字符串首地址,strcmp 会比较两字符串的对应位字符的ASCII码值,其返回值分为三种:

  1. 返回值 >0,表示 str1 中某一位字符大于 str2 对应位的字符
  2. 返回值 <0,表示 str1 中某一位字符小于 str2 对应位的字符
  3. 返回值 == 0,表示 str1 与 str 2完全相同

使用演示:

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

int main()
{
	char* ch1 = "abcdefg";
	char* ch2 = "abcz";

	int ret = strcmp(ch1, ch2);

	printf("%d\n", ret);

	return 0;
}

运行结果:

解疑:在vs中,strcmp三种返回值为1,0,-1,对应的三种情况,但C语言标准中是按照大于0小于0等于0分的。上图结果为-1,因为ch2中的第四个字符为 'z',大于ch1中第四个字符 'd',因此判定ch1小于ch2,返回-1。也就是返回<0的值


2.模拟实现:

#include <stdio.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++;
	}

	return *str1 - *str2;

    /*if (*str1 > *str2)
    {
	    return 1;
    }
    else
    {
	    return -1;
    }*/
}

解疑:首先while循环,判断两字符串对应位置字符是否相同,相同就进入循环,在进行判断,如果其中有一个字符为'\0',表示这两个字符走到头了,并且完全相等,返回0,如果没有就使两字符串地址向后走一位,再进行循环判断,如果两字符串对应位字符不相等,就跳出循环,直接令这两个字符串对应位置的字符相减,其返回值就能判断两字符串的大小,也可以使用分支判断两字符串,使其返回1或-1,如代码中注释的部分


五、strncpy 的使用和模拟实现

1.使用:

功能:拷贝指定个数的字符从源字符串到目标字符串上

    

函数声明:char * strncpy ( char * destination, const char * source, size_t num );

    

用法:和 strcpy 相比多了一个参数 num,用来指定复制多少个字符,有以下几点需要注意:

  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
  • 如果原字符串的长度大于num,则只拷贝num个字符到目标文件中,目标文件中如果有数据将会被覆盖,并且不会追加'\0'。
  • 目标字符串的容量必须足够大,能存放下拷贝的字符

使用演示:

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

int main()
{
	char ch1[10] = { "xxxxxxxxx" };
	char ch2[] = { "abcdef" };

	char* ret = strncpy(ch1, ch2, 9);

	printf("%s\n", ch1);
	printf("%s\n", ret);

	return 0;
}

运行结果:

监视窗口:

解疑:上述代码符号第一种情况,即如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。


2.模拟实现:

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

char* my_strncpy(char* dest, char* src, size_t num)
{
	assert(dest && src);
	char* ret = dest;
	size_t len = strlen(src);
	int count = (int)num - (int)len;

	while (num && *src)
	{
		*dest = *src;
		dest++;
		src++;
		num--;
	}

	while (count > 0)
	{
		*dest = 0;
		dest++;
		count--;
	}

	return ret;
}

解疑:以上的实现是我个人的想法,不是最优解。首先除了保存目标字符串首地址,计算了源字符串大小,并保存了num与源字符串长度的差值,第一个while循环,在保证拷贝没有超过 num 个字符和原字符串没有走到结尾的情况下,拷贝了能拷贝的字符。然后下面一个while循环用来判断 num是否大于源字符串长度,如果大于,则在目标字符串末尾补0。直至刚好拷贝完num个字符,最后返回目标字符串首地址。


六、strncat 的使用和模拟实现

1.使用:

功能:将源字符串的前num个字符追加到目标字符串指向的字符串末尾,再追加⼀个'\0'字符

    

函数声明:char * strncat ( char * destination, const char * source, size_t num );

    

用法:前两个参数与strcat一致,也是后面多了一个num,用来指定追加多少个字符。这里需要注意的有以下几条:

  • 如果 source 指向的字符串的长度小于num的时候,只会将字符串中到 '\0' 的内容追加到destination指向的字符串末尾。大于num的话,就是源字符串的前num个字符追加到目标字符串指向的字符串末尾,再追加⼀个'\0'字符
  • 目标字符串的容量得足够大,能容下追加的字符

使用演示:

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

int main()
{
	char ch1[20] = { "abcd\0xxxxxxxx" };
	char* ch2 = "qwerty";

	char* ret = strncat(ch1, ch2, 8);

	printf("%s\n", ch1);
	printf("%s\n", ret);

	return 0;
}

运行结果:

监视窗口:

解疑:以上代码就符合num大于源字符串长度的情况,即 source 指向的字符串的长度小于num的时候,只会将字符串中到 '\0' 的内容追加到destination指向的字符串末尾。为了方便观察,我在ch1中插入了'\0'和xxxxxxxx,最后发现末尾确实追加了一个'\0'字符。


2.模拟实现:

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

char* my_strncat(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* ret = dest;

	while (*dest)
	{
		dest++;
	}

	while (num && *src)
	{
		*dest = *src;
		dest++;
		src++;
		num--;
	}
	
	*dest = '\0';

	return ret;
}

解疑:前面步骤与strcat一致,到了第二个while循环,也是在保证没有追加超过num个字符和源字符串地址没有走到字符串末尾的情况下,追加所有能追加的字符,然后无论 num 大于或者小于 源字符串长度,只需要追加一个'\0'即可。最后返回目标字符串首地址。


七、strncmp 的使用和模拟实现

1.使用:

函数声明:int strncmp ( const char * str1, const char * str2, size_t num );

    

功能及用法:比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不一样,就提前结束,大的字符所在的字符串大于另外⼀个。如果num个字符都相等,就是相等返回0。返回值情况与strcmp一致

使用演示:

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

int main()
{
	char* ch1 = "abcde";
	char* ch2 = "abcqwer";

	int ret1 = strncmp(ch1, ch2, 3);
	int ret2 = strncmp(ch1, ch2, 5);
	
	printf("%d\n", ret1);
	printf("%d\n", ret2);

	return 0;
}

运行结果:

解疑:基本和strcmp一样,只是多了指定比较的个数


2.模拟实现:

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

int my_strncmp(const char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);

	while ((*str1 == *str2) && num)
	{
		if (*str1 == '\0')
		{
			return 0;
		}
		str1++;
		str2++;
		num--;
	}

	if (*str1 == *str2)
	{
		return 0;
	}
	else if (*str1 > *str2)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

解疑:模拟过程与strcmp相比,while循环多了一个num的判断,最后的条件判断也多了一条判断相等的情况,因为while循环的终止可能是由于num等于0的情况,此时需要再对字符串进行一次比较。


八、strstr 的使用和模拟实现

1.使用:

功能:在一个字符串中寻找与另一个字符串完全相同的片段

    

函数声明:char * strstr ( const char * str1, const char * str2 );

    

用法:传入两个字符串的首地址,函数返回字符串str2在字符串str1中第一次出现的位置的地址,如果找不到,就返回空指针(NULL)。

使用演示

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

int main()
{
	char ch1[] = "This is a simple string";
	char ch2[] = "simple";

	char* ret = strstr(ch1, ch2);

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

	return 0;
}

运行结果:

解疑:因为函数返回的是str2字符串内容在str1中第一次出现时的地址,所以我们以%s打印时,会从这个地址一直打印到str1字符串末尾遇到'\0'停止


2.模拟实现:

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

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);

	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cur = str1;

	if (*str2 == '\0')
	{
		return (char*)str1;
	}

	while (*cur)
	{
		s1 = cur;
		s2 = str2;

		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}

		if (*s2 == '\0')
		{
			return (char*)cur;
		}

		if (strlen(cur+1) < strlen(str2))
		{
			return NULL;
		}

		cur++;
	}

	return NULL;
}

解疑:

  1. 首先创建了三个指针变量,s1,s1分别用来记录str1和str2比较过程中的地址,cur记录的是str1当前位置的地址,因为途中的比较过程会打乱str1指针的指向,因此需要cur来记录str1当前位置的地址,以便s1在比较过程中没有找到相同字符串时,可以通过cur找回起始位置。而str2本身指向是不会变的,因此不需要另外的指针进行记录当前位置。
  2.  if (*str2 == '\0') ,这个意思是如果str2是个空字符串的话,直接返回str1的地址,这是C语言标准中strstr的规定。并且空字符串本身也不需要寻找,任何字符串都包含空字符串
  3. while (*cur) ,这个循环条件就是cur没有指向字符串末尾。然后给s1赋值为cur,s2赋值为str2,。s1,s2就是用来比较判断两字符串是否有相同的指针。
  4. while (*s1 && *s2 && *s1 == *s2),这个循环意思是,只要s1,s2没有指向字符串末尾并且它两指向的字符相等,就让s1,s2一直往后走,只要有其中一个条件不满足时,循环就终止
  5. 循环终止后就进行一个判断,if (*s2 == '\0'),该判断的意思是,如果s2等于'\0',表示前一个循环是因为s2走到字符串末尾而终止的,s2能走到末尾,就表示s2前面的字符与s1都相同,这就表明能在str1中找到str1,此时只需要终止函数,返回cur,也就是str1当前的地址就行
  6. 而如果s1指向的字符不为'\0',就表示前一个循环的终止是因为s1,s2指向的字符不相同导致的,就再进行一个判断,if (strlen(cur+1) < strlen(str2)),这个判断表示,当前str1指向的下一个位置到字符串末尾的长度,如果小于str2的长度,就表明str1后面一定找不到str2了,为了提高效率,直接返回空指针。
  7. 如果两个判断都不满足,就让str1当前的位置往后走一步,也就是cur++,再进行循环判断。
  8. 如果直到最后cur都指向'\0'了,就直接返回空指针。


九、strtok函数的使用

功能:将一个字符串以指定字符的格式分隔

    

函数声明:char * strtok ( char * str, const char * sep );

    

用法:第一个参数指向了一个字符串,第二个参数指向了需要分隔的字符的集合,并且有以下要求和细节:

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

使用演示:

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

int main()
{
	char ch1[] = "abcd.bbc/123@xp";
	char ch2[] = "./@";

	printf("第一次分割:\n");
	char* ret = strtok(ch1, ch2);
	printf("%s\n", ret);
	printf("%s\n", ch1);

	printf("第二次分割:\n");
	ret = strtok(NULL, ch2);
	printf("%s\n", ret);
	printf("%s\n", ch1);

	printf("第三次分割:\n");
	ret = strtok(NULL, ch2);
	printf("%s\n", ret);
	printf("%s\n", ch1);

	printf("第四次分割:\n");
	ret = strtok(NULL, ch2);
	printf("%s\n", ret);
	printf("%s\n", ch1);

	printf("第五次分割:\n");
	ret = strtok(NULL, ch2);
	printf("%s\n", ret);
	printf("%s\n", ch1);

	return 0;
}

运行结果:

解疑:第一次分割将字符'.'修改为'\0',返回了起始地址,也就是字符'a'的地址,因为改变了源字符串的数据,所以此后以%s打印ch1只能打印abcd。第二次分割将字符'/'修改为'\0',然后返回了第二段起始地址,也就是字符'b'的地址。后面的结果依次类推就行。直到最后没有可分割字符返回空指针

是不是发现上面有大量重复的代码,其实我们可以使用循环来进行打印:

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

int main()
{
	char str[] = "123.4545.446.xpashisdid@qq.com";
	char* sep = ".@";

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

	return 0;
}

运行结果:

解疑:以上for循环使用地非常巧妙,首先初始化部分调用一次strtok,传入需分割的字符串和分割字符。创建一个ret接收strtok的返回值,因为for循环初始化部分只会进行一次。所以该部分不会重复进行,然后判断部分写 ret != NULL,只要返回值不为空指针,循环就不终止。for调整部分写再一次调用strtok,传入空指针即可。strtok具有记忆保存的属性。如此一来就实现了循环分割打印的效果


十、strerror 函数的使用

1.使用:

功能:接收并记录程序运行时的错误码,返回错误码对应的错误信息的字符串地址

    

函数声明:char * strerror ( int errnum );

    

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

打印0~10错误码对应的信息:

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

int main()
{
	int i = 0;

	for (i = 0; i <= 10; i++)
	{
		printf("%s\n", strerror(i));
	}

	return 0;
}

运行结果:

(注:不包含 errno.h 头文件也可以打印)

使用演示:

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

int main()
{
	FILE* pf = fopen("xxx.txt", "r");

	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
	}

	return 0;
}

运行结果:

解疑:定义一个文件指针,以只读的形式打开一个不存在的文件,pf会接收到一个空指针,此时这个文件打开错误会被记录,使用if判断然后打印出这个错误信息,这在我们日常写代码中非常实用。另外记住使用strerror时要传参errno


2.补充:perror 函数的使用
 

函数声明:void perror ( const char * str );

    

功能介绍:perror与strerror类似,都是记录错误信息,但是不同的是:

  • perror使用时会直接打印出错误信息,不需要向strerror那样使用printf进行打印。
  • perror的参数,指我们可以自己添加一个需要打印的字符串信息在错误信息的前面
  • perror函数包含在 <stdio.h> 头文件中

使用演示:

#include <stdio.h>

int main()
{
	FILE* pf = fopen("xxx.txt", "r");

	if (pf == NULL)
	{
		perror("fopen");
	}

	return 0;
}

运行结果:

解疑:如图所示,我们传入perror的字符串参数最终会加上':'打印在屏幕上,我们传入的字符串可以提醒我们哪里或者哪个函数出的问题。更加的方便和实用

关于strerror与perror函数的选择,是根据自己的情况而定,只记录不打印选择strerror,只打印选择perror即可


总结

        以上就是本文的全部内容了,希望对大家有所帮助,感谢支持

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

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

相关文章

Freeswitch-soundtouch-变声开发

文章目录 一、介绍二、安装soundtouch2.1 源码安装方式&#xff08;推荐&#xff09;2.1.1下载源码2.1.2解压2.1.3 编译2.1.4 迁移&#xff08;可选&#xff09; 2.2 apt-get 安装 三、使用3.1 终端使用3.2 Freeswitch使用3.2.1编译Freeswitch的mod_soundtouch3.2.2启用 mod_so…

如何秒杀系统架构设计

原文路径:https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/%e5%a6%82%e4%bd%95%e8%ae%be%e8%ae%a1%e4%b8%80%e4%b8%aa%e7%a7%92%e6%9d%80%e7%b3%bb%e7%bb%9f/00%20%e5%bc%80%e7%af%87%e8%af%8d%20%e7%a7%92%e6%9d%80%e7%b3%bb%e7%bb%9f%e6%9e%b6%e6%9e%84%e8%ae%be%e8%ae%…

为什么选择海外服务器?

如何选择跨境电商服务器&#xff1a;详细指南 选择合适的服务器是跨境电商企业成功的基础。服务器的性能和稳定性直接影响着网站的访问速度、用户体验和安全性&#xff0c;进而影响着企业的销量和利润。那么&#xff0c;跨境电商企业该如何选择服务器呢&#xff1f; ​​​​​…

WeTrade 在印度尼西亚井里汶成功举办研讨会

端午安康!在这欢乐的假日里&#xff0c;WeTrade和各位投资者分享一则喜事!如果有意参加的&#xff0c;可以联系小编! 5 月底&#xff0c;我们在印度尼西亚井里汶成功举办了一场精彩研讨会&#xff0c;聚集了来自印度尼西亚各地交易社区的100多名交易者。 此次研讨会由经验丰富…

【博士每天一篇文献-综述】Modularity in Deep Learning A Survey

阅读时间&#xff1a;2023-12-8 1 介绍 年份&#xff1a;2023 作者&#xff1a;孙浩哲&#xff0c;布朗克斯医疗卫生系统 会议&#xff1a; Science and Information Conference 引用量&#xff1a;4 论文主要探讨了深度学习中的模块化&#xff08;modularity&#xff09;概念…

Linux - 信号概念 信号产生

Linux - 信号概念 & 信号产生 信号概念信号产生软件信号killraiseabortalarm 硬件信号键盘产生信号硬件中断 信号概念 信号是进程之间事件异步通知的一种方式 在Linux命令行中&#xff0c;我们可以通过ctrl c来终止一个前台运行的进程&#xff0c;其实这就是一个发送信号的…

AI全栈工程师的新舞台:Coze(扣子)

前言 在当前科技飞速发展的背景下&#xff0c;Coze作为一款引领潮流的AI应用平台&#xff0c;正以破竹之势重塑着我们对于智能应用的认知。Coze不仅仅是一个工具&#xff0c;它是一个集合了前沿AI技术、高效开发环境与创意无限的应用生态于一体的创新平台&#xff0c;旨在让每…

ctfshow-web入门-命令执行(web53-web55)

目录 1、web53 2、web54 3、web55 1、web53 这里的代码有点不一样&#xff0c;说一下这两种的区别&#xff1a; &#xff08;1&#xff09;直接执行 system($c); system($c);这种方式会直接执行命令 $c 并将命令的输出直接发送到标准输出&#xff08;通常是浏览器&#xff…

如何理解external

external 函数应该只被外部函数调用但也可以被内部调用&#xff0c;但是这种内部调用也是有外部调用机制&#xff0c;即新产生message! 例子1 // SPDX-License-Identifier: GPL-3.0pragma solidity >0.8.2 <0.9.0;contract ExternalDemo{address public caller;functi…

【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现(附源码)(下篇)

作者&#xff1a;后端小肥肠 上篇&#xff1a;【Activiti7系列】基于Spring Security的Activiti7工作流管理系统简介及实现&#xff08;上篇&#xff09;_spring security activiti7-CSDN博客 目录 1.前言 2. 核心代码 2.1. 流程定义模型管理 2.1.1. 新增流程定义模型数据 …

【qsort函数】

前言 我们要学习qsort函数并利用冒泡函数仿照qsort函数 首先我们要了解一下qsort&#xff08;快速排序&#xff09; 这是函数的的基本参数 void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*)); 简单解释一下 base&#xff1a;指向…

自动化搭建专属 AI 绘图服务

通义万相AIGC技术已经比较成熟&#xff0c;结合阿里云的计算和存储产品可以方便的搭建自己专属的 AI 绘图服务。例如《创意加速器&#xff1a;AI 绘画创作》这个解决方案&#xff0c;利用阿里自研的通义万相AIGC技术在 Web 服务中实现先进的图像生成。 AI 绘画服务搭建步骤 从…

【文档智能 RAG】RAG增强之路:增强PDF解析并结构化技术路线方案及思路

前言 现阶段&#xff0c;尽管大模型在生成式问答上取得了很大的成功&#xff0c;但由于大部分的数据都是私有数据&#xff0c;大模型的训练及微调成本非常高&#xff0c;RAG的方式逐渐成为落地应用的一种重要的选择方式。然而&#xff0c;如何准确的对文档进行划分chunks&…

Golang的协程调度器GMP

目录 GMP 含义 设计策略 全局队列 P的本地队列 GMP模型以及场景过程 场景一 场景2 场景三 场景四 场景五 场景六 GMP 含义 协程调度器&#xff0c;它包含了运行协程的资源&#xff0c;如果线程想运行协程&#xff0c;必须先获取P&#xff0c;P中还包含了可运行的G…

时序数据库是Niche Market吗?

引言 DB-Engines的流行程度排行从其评估标准[4]可以看出完全不能够做为市场规模的评估标准。甚至于在知道市场规模后可以用这个排行作为一个避雷手册。毕竟现存市场小&#xff0c;可预见增长规模小&#xff0c;竞争大&#xff0c;创新不足&#xff0c;那只能卷价格&#xff0c…

01、Linux网络设置

目录 1.1 查看及测试网络 1.1.1 查看网络配置 1、查看网络接口地址 2、查看主机状态 3、查看路由表条目 4、查看网络连接qing 1.1.2 测试网络连接 1.测试网络连接 2.跟踪数据包的路由路径 3.测试DNS域名解析 1.2 设置网络地址参数 1.2.1 使用网络配置命令 1.修改网卡…

C# MES通信从入门到精通(11)——C#如何使用Json字符串

前言 我们在开发上位机软件的过程中&#xff0c;经常需要和Mes系统进行数据交互&#xff0c;并且最常用的数据格式是Json&#xff0c;本文就是详细介绍Json格式的类型&#xff0c;以及我们在与mes系统进行交互时如何组织Json数据。 1、在C#中如何调用Json 在C#中调用Json相关…

【题解】—— LeetCode一周小结23

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结22 3.分糖果 II 题目链接&#xff1a;1103. 分糖果 II 排排坐…

【漏洞复现】用友NC pagesServlet SQL注入漏洞(XVE-2024-13067)

0x01 产品简介 用友NC是由用友公司开发的一套面向大型企业和集团型企业的管理软件产品系列。这一系列产品基于全球最新的互联网技术、云计算技术和移动应用技术&#xff0c;旨在帮助企业创新管理模式、引领商业变革。 0x02 漏洞概述 用友NC /portal/pt/servlet/pagesServlet…

Springboot校园美食推荐系统的开发-计算机毕业设计源码44555

摘要 随着人们生活水平的提高&#xff0c;人们对美食的要求也越来越高&#xff0c;对各类美食信息需求越来越大。因此&#xff0c;结合计算机快速发展、普及&#xff0c;在此基础上制作一个页面简单、美观,功能实用的校园美食推荐系统势在必行&#xff0c;满足用户分享美食的需…