成都网站建设设计

将想法与焦点和您一起共享

C语言学习笔记——字符串函数和内存函数-创新互联

前言

对于字符串的操作可以说是C语言基础学习的一大难点。C语言标准库中有许多用于处理字符串的库函数。今天我来分享一些常用的字符串函数的使用方法和原理。

专注于为中小企业提供成都做网站、网站制作、成都外贸网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业比如免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000多家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
一、字符串函数 1.strlen
size_t strlen (const char * str);

strlen函数用于计算字符串长度,传入字符串起始地址(char*类型)即可计算从起始地址处开始,至'\0'(字符串结束的标志)处的字符个数(不包括'\0'),并以size_t(即unsigned int)类型返回。例如以下代码的打印值即为12。

char arr[] = "Hello world!";
printf("%d\n",strlen(arr));

strlen函数的原理非常简单,可借助循环对字符串进行遍历,并通过循环变量来记录循环发生的次数,直到遇见'\0'为止。最后返回循环变量的值即可。

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

strcpy函数可将参数中source所指向的字符串复制至destination所指向的字符串处,并返回destination所指向的地址。例如以下代码,将str2指向的字符串复制至str1所指向的字符串处,覆盖原字符串,最后输出"you "。注意,字符串str2中的'\0'字符也被复制至str1中对应位置,故str1字符串的内容变为"you\0o\0",输出为"you"。

char str1[] = "hello ";
char str2[] = "you";
printf("%s\n",strcpy(str1,str2));

strcpy函数的原理是将source中的字符一个一个赋值给destination中的元素,直到source指针遇到'\0'。利用循环赋值即可实现。

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

strcat函数可将source所指向的字符串内容追加至destination指向的字符串后,并返回destination所指向的地址。例如以下代码,将"world"追加至"hello"后,输出"helloworld"。

char str1[] = "hello";
char str2[] = "world";
printf("%s\n",strcat(str1,str2));

strcat函数的原理可以理解为将source所指向的字符串复制到destination所指向的字符串后,即复制到destination所指向的字符串的'\0'处。首先通过destination和destination所指向的字符串长度确定destination所指向的字符串的'\0'的地址,再仿照strcpy函数将source所指向的字符串复制过来即可。

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

strcmp函数用于比较两个字符串的大小,从给定的两个起始地址开始对两字符串的各个字符进行逐一对比,若字符相同,则对比下一对字符,若str1中字符的ASCII码值大,则返回一个正数;若str中字符的ASCII码值小,则返回一个负数;若两字符串完全相同,则返回0。例如以下两段代码,分别返回0和一个正数。

char str1[] = "abc";
char str2[] = "abc";
printf("%d\n",strcmp(str1,str2));
char str1[] = "abcq";
char str2[] = "abcdefg";
printf("%d\n",strcmp(str1,str2));

strcmp函数的原理就是通过循环来比较两个字符串的各个字符是否相同,我们可以先分两种情况讨论。当两字符串相同时,它们的各个字符相同,直到'\0',因此我们通过循环来判断,当有字符不同时即跳出循环,而当两字符均为'\0'时说明两字符串完全相同,直接返回0即可;当两字符串不同时,则比较不同的两个字符大小,并视情况返回正数或负数。

5.strn系列

这里strn系列指strncpy、strncat、strncmp,这些函数的原理与上述三个函数基本相同,区别在于strn系列的对字符串的操作长度受限。我们知道,strcpy、strcat和strcmp判断结束的标志都是'\0',而strn系列的操作长度受参数控制,这里以strncpy和strcpy对比为例。

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

从函数声明上看,两函数的差异只有参数,strncpy要多一个size_t类型参数,这就是长度限制。例如以下代码

char str1[] =  "hello world";
char str2[] = "abcdef";
printf("%s\n",strcpy(str1,str2));
printf("%s\n",strncpy(str1,str2,3));

打印结果分别为"abcdef"和"abclo world"。由于传入的参数num为3,故strncpy函数只会复制前3个字符,而strcpy函数会将str2字符串整个复制到str1处。

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

strstr函数用于查找字符串str1中是否含有字符串str2,若含有,则返回str1中与str2相同字符串的起始地址;若不含,则返回空指针。例如以下代码,分别返回'c'的地址和空指针。

char str1[] = "abcde";
char str2[] = "cd";
char str3[] = "bd";
printf("%p\n",strstr(str1,str2));
printf("%p\n",strstr(str1,str3));

strstr函数的原理较为复杂,首先我们要记录str2的起始地址,以防止在遍历时丢失地址。然后对字符串str1进行遍历,直到找到与str2首字符相同的字符,接下来即可仿照strcmp的原理进行比较。但是需要注意,同样为了防止丢失地址,需要记录str1此时的地址。对比完成后,若相同则返回str1此时的地址,若不同则从str1此时的地址开始继续向后遍历。若str1遍历至'\0'仍未找到相同的字符串,则返回空指针。

7.strtok
char * strtok ( char * str, const char * delimiters );

strtok函数的作用是将字符串str以指定的分界符分割,将str中与分界符相同的字符全部改为'\0',首次返回字符串str的首地址。它的特点是若再次调用时传入空指针,函数将返回上一次调用时产生的'\0'后一位的地址,例如以下代码,打印值分别为"1234567"、"163"和"com"。

char str[] = "1234567@163.com";
char deli[] = "@.";
printf("%s\n",strtok(str,deli));
printf("%s\n",strtok(NULL,deli));
printf("%s\n",strtok(NULL,deli));

strtok函数的原理是将字符串str中的每个字符与delimiters中的所有字符比较,若有相同则将其改为'\0',并返回str的起始地址。需要注意的是,我们需要创建一个静态变量来保存'\0'后的地址,以确保下次传入空指针时能找到该地址。

二、内存函数

由于字符串函数仅针对字符型变量,无法操作其他类型的变量,故C语言标准库提供了内存函数以操作不同类型的变量。

1.memset
void * memset ( void * ptr, int value, size_t num );

memset函数可将一段内存空间设定为指定值,其中指针ptr为空间的起始地址,变量value为修改值,变量num为空间大小(单位:字节),返回起始地址。由于返回值为void*类型的指针,使用时需进行强制类型转换。该函数原理较简单,通过循环赋值即可由于参数为void*类型的指针,可强制类型转换为char*类型的指针进行操作。

2.memcmp
int memcmp (const void * ptr1, const void * ptr2, size_t num);

memcmp函数的功能和原理均类似于strcmp函数,将参数的void*指针转为char*类型进行操作即可,这里就不过多解释了。

3.memcpy与memmove
void * memcpy (void * destination, const void * source, size_t num);
void * memmove (void * destination, const void * source, size_t num);

这两个函数的作用极其相似,但略有不同。它们都是用来将source所指向的数据拷贝至destination所指向的地址,类似于strcpy的拷贝字符串。例如以下代码,使用这两个函数打印值相同,均为"3 4 3 4 5"(整型占用4字节,故8字节操作两个整型)。

int i = 0;
int arr1[] = {1,2,3,4,5};
int arr2[] = {3,4,5,6,7};
memcpy(arr1,arr2,8);  //或memmove(arr1,arr2,8); 
for(i = 0;i< 5;i++)
{
    printf("%d ",arr[i]);
}

但是,当拷贝内容与目的地内容重叠时,就会出现问题,如下

int arr[] = {1,2,3,4,5};
memcpy(arr1+1,arr1,8);
for(i = 0;i< 5;i++)
{
    printf("%d ",arr[i]);
}

这段代码的打印结果为"1 1 1 4 5",这是由于memcpy函数在拷贝时首先将'1'覆盖至'2',此时数组变为"1 1 3 4 5",然后memcpy将第二个'1'拷贝至'3',导致数组变为"1 1 1 4 5"。若使用memmove来操作,则结果为"1 1 2 4 5"。

造成这种差异的原因是memcpy函数永远是按从低地址到高地址的顺序拷贝数据,而memmove则不同,若destination的地址高于source(即destination>source),则按按从高地址到低地址的顺序拷贝数据;若destination的地址低于source(即destination>source),则按按从低地址到高地址的顺序拷贝数据。


结束语

以上就是我对一些常用的字符串函数和内存函数的理解了,部分函数的模拟实现源代码我上传到了我的gitee仓库(链接:https://gitee.com/q1479527934/warehouse-of-c.git),有需要的小伙伴可以看看哦。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:C语言学习笔记——字符串函数和内存函数-创新互联
浏览地址:http://chengdu.cdxwcx.cn/article/dijied.html