C语言字符串
野猪佩奇` 人气:0求字符串长度
strlen
函数功能
字符串长度,求一个字符串中字符的个数(不包含’\0’)。
函数参数:
size_t strlen( const char *string ); # size_t 是函数的返回类型 # char* string 是函数参数
函数使用:
#include <stdio.h> #include <string.h> //strlen对应头文件 int main() { char arr[] = "abcdef"; int len = strlen(arr); printf("%d\n", len); return 0; }
模拟实现(初阶):
#include <stdio.h> #include <assert.h> //assert对应头文件 size_t my_strlen(const char* str) { assert(str != NULL); //检查str是否为空指针 int count = 0; while (*str != '\0') { str++; count++; } return count; } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }
模拟实现(进阶):
#include <stdio.h> #include <assert.h> //assert对应头文件 size_t my_strlen(const char* str) //const用于保护源字符串不被修改 { assert(str != NULL); char* head = str; //记录字符串开头的地址 while (*str++); //找到字符串结束的地址 return str - head - 1; //指针-指针得到元素个数,-1减去\0 } int main() { char arr[] = "abcdef"; int len = my_strlen(arr); printf("%d\n", len); return 0; }
注意事项:
- 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含’\0’)。
- 函数参数指向的字符串必须要以 ‘\0’ 结束,否则得到的就是随机值(strlen会一直往后找,直到遇到’\0’才结束)。(常考)
- 注意函数的返回值为size_t,是无符号的。(易错:可能出现算术转换)
长度不受限制的字符串函数
strcpy
函数功能:
字符串拷贝,把一个字符串里面的内容拷贝到另一个字符串中去(包括’\0’)。
函数参数;
char* strcpy(char * destination, const char * source ); # char* 是函数的返回值,返回的是目标空间的起始地址 # source 是要拷贝的字符串 # destination 是目标空间
函数使用:
#include <stdio.h> #include <string.h> //strcpy对应头文件 int main() { char arr1[] = "abcdef"; char arr2[10] = ""; strcpy(arr2, arr1); printf("%s\n", arr2); return 0; }
模拟实现(初阶):
#include <stdio.h> #include <assert.h> //assert对应头文件 char* my_strcpy(char* dest, const char* src) //const用于保护源字符串 { assert(dest && src); //保证传递过来的不是空串 char* ret = dest; //记录目标空间的起始地址 while (*src != '\0') { *dest = *src; dest++; src++; } *dest = *src; //将末尾的'\0'赋给dest return ret; } int main() { char arr1[] = "abcdef"; char arr2[10] = ""; my_strcpy(arr2, arr1); printf("%s\n", arr2); return 0; }
模拟实现(进阶):
#include <stdio.h> #include <assert.h> //assert对应头文件 char* my_strcpy(char* dest, const char* src) //const用于保护源字符串 { assert(dest && src); //保证传递过来的不是空串 char* ret = dest; //记录目标空间的起始地址 while (*dest++ = *src++); //连同末尾的'\0'一起赋给了dest return ret; } int main() { char arr1[] = "abcdef"; char arr2[10] = ""; my_strcpy(arr2, arr1); printf("%s\n", arr2); return 0; }
注意事项:
- 源字符串必须以 ‘\0’ 结束。
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
strcat
函数功能:
字符串追加,在一个字符串的末尾追加另外一个字符串(包括’\0’)。
函数参数:
char * strcat ( char * destination, const char * source ); # char* 是函数的返回值,返回的是目标空间的起始地址 # source 是要追加的字符串 # destination 是目标空间
函数使用:
#include <stdio.h> #include <string.h> //strcat对应头文件 int main() { char arr1[] = "world!"; char arr2[20] = "hello "; strcat(arr2, arr1); printf("%s\n", arr2); return 0; }
模拟实现(初阶):
#include <stdio.h> #include <assert.h> //字符串追加可以分为两部分:1、找到目标字符串的末尾 2、字符串拷贝 char* my_strcat(char* dest, const char* src) //const用于保护源字符串 { assert(dest && src); //保证传递过来的不是空串 char* ret = dest; //记录目标空间的起始地址 while (*dest != '\0') //找到目标空间的末尾 { dest++; } while (*src != '\0') { *dest = *src; dest++; src++; } *dest = *src; //将末尾的'\0'赋给dest return ret; } int main() { char arr1[] = "world!"; char arr2[20] = "hello "; my_strcat(arr2, arr1); printf("%s\n", arr2); return 0; }
模拟实现(进阶):
#include <stdio.h> #include <assert.h> //字符串追加可以分为两部分:1、找到目标字符串的末尾 2、字符串拷贝 char* my_strcat(char* dest, const char* src) //const用于保护源字符串 { assert(dest && src); //保证传递过来的不是空串 char* ret = dest; //记录目标空间的起始地址 while (*dest++ != '\0'); //找到目标空间的末尾 dest--; //抵消最后一次自增的副作用 while (*dest++ = *src++); //字符串拷贝 return ret; } int main() { char arr1[] = "world!"; char arr2[20] = "hello "; my_strcat(arr2, arr1); printf("%s\n", arr2); return 0; }
注意事项:
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- strcat 函数不能自己给自己追加。(追加会覆盖掉末尾的’\0’,导致死循环)
strcmp
函数功能:
字符串比较,以字节为单位比较两个字符串的大小
函数参数:
int strcmp ( const char * str1, const char * str2 ); # int 函数返回值 # char* str1 char* str2 用于比较的两个字符串
函数返回值:
>0 : str1 大于 str2; =0 : str1 等于 str2; <0 : str1 小于 str2
函数使用:
#include <stdio.h> #include <string.h> //strcmp对应头文件 int main() { char str1[] = "abcdef"; char str2[] = "abq"; int ret = strcmp(str1, str2); printf("%d\n", ret); return 0; }
模拟实现:
#include <stdio.h> #include <assert.h> //assert对应头文件 int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2 && *str1 != '\0' && *str2 != '\0') //找到字符串中不相等字符的位置 { str1++; str2++; } if (*str1 != '\0' && *str2 != '\0') //如果此位置不是字符串末尾,则不相等,返回差值 return *str1 - *str2; return 0; //若前面没返回,说明相等,返回0 } int main() { char str1[] = "abcdef"; char str2[] = "abq"; int ret = my_strcmp(str1, str2); printf("%d\n", ret); return 0; }
注意事项:
- 对每一对字符进行比较,直到遇到不相等的字符或者遇到’\0’。
- 比较的是每一对字符的ASCII值。
长度受限制的字符串函数
由于strcpy、strcat、strcmp等字符串函数存在安全隐患(目标空间小于源空间等问题),C语言还提供了另外几种相对安全的字符串函数,即strncpy、strncat、strncmp,这些字符串函数相比于原字符串函数多了一个参数,用于指定操作的字节数。(注意:strncpy、strncat、strncmp函数只是相对安全,并不是绝对安全,多一个参数只是起到一个提醒作用)
strncpy
函数功能:
字符串拷贝,把一个字符串中num个字节的内容拷贝到另一个字符串中去。
函数参数:
char * strncpy ( char * destination, const char * source, size_t num ); # char* 是函数的返回值,返回的是目标空间的起始地址 # source 是要拷贝的字符串 # destination 是目标空间 # num 是要拷贝的字节数
函数使用:
#include <stdio.h> #include <string.h> //strncpy对应的头文件 int main() { char arr1[] = "abcdef"; char arr2[10] = ""; strncpy(arr2, arr1, sizeof(arr1) / sizeof(arr1[0]) * 1); //sizeof(arr)/sizeof(arr[0]) 求得数组元素个数,*1 乘以每个元素的大小,得到整个数组的字节数 printf("%s\n", arr2); return 0; }
模拟实现:
//模拟实现strncpy #include <stdio.h> #include <assert.h> char* my_strncpy(char* dest, const char* src, size_t num) { assert(dest && src); char* ret = dest; //记录目标空间的起始地址 while (num--) { *dest = *src; if (*dest == '\0') //如果*dest为0,说明将src的结束字符赋给了dest,这种情况下源字符串的长度小于num { while (num--) { //如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。(与库函数的实现方式保持一致) *dest++ = 0; } break; } dest++; src++; } *dest = '\0'; //在dest的末尾补上结束字符 return ret; } int main() { char arr1[] = "abc"; char arr2[10]; my_strncpy(arr2, arr1, 4); printf("%s\n", arr2); return 0; }
注意事项:
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
strncat
函数功能:
字符串追加,将一个字符串中num个字节的内容追加到另一个字符串的末尾,并在最后面加上’\0’。
函数参数:
char * strncat ( char * destination, const char * source, size_t num ); # char* 是函数的返回值,返回的是目标空间的起始地址 # source 是要追加的字符串 # destination 是目标空间 # num 是要追加的字节数
函数使用:
#include <stdio.h> #include <string.h> //strncat对应的头文件 int main() { char arr1[] = "world!"; char arr2[20] = "hello "; strncat(arr2, arr1, sizeof(arr1) / sizeof(arr1[0]) * 1); //sizeof(arr)/sizeof(arr[0]) 求得数组元素个数,*1 乘以每个元素的大小,得到整个数组的字节数 printf("%s\n", arr2); return 0; }
模拟实现:
#include <stdio.h> #include <assert.h> char* my_strncat(char* dest, const char* src, size_t num) { assert(dest && src); char* ret = dest; //记录目标空间的起始地址 //找到dest末尾 while (*dest != '\0') { dest++; } //strncpy while (num--) { *dest = *src; if (*dest == '\0') //如果*dest为0,说明将src的结束字符赋给了dest,这种情况下源字符串的长度小于num { //如果源字字符串的长度小于num,则只复制到终止空字符的内容。(与库函数的实现方式保持一致) return ret; //直接返回 } dest++; src++; } *dest = '\0'; //如果循环正常结束,则在dest的末尾补上结束字符 return ret; } int main() { char arr1[20] = "abcdef"; char arr2[] = "ABCDEF"; my_strncat(arr1, arr2, 5); printf("%s\n", arr1); return 0; }
注意事项:
- 将源字符串中num个字节的内容追加到目标字符串的末尾,并在最后添加’\0’。
- 如果源中字符串的长度小于num,则只复制到终止空字符的内容
strncmp
函数功能:
字符串比较,比较两个字符串中前num个字节的大小。
函数参数:
int strncmp ( const char * str1, const char * str2, size_t num ); # int 函数返回值 # char* str1 char* str2 用于比较的两个字符串 # num 要比较的字节数
函数返回值:
>0 : str1 大于 str2; =0 : str1 等于 str2; <0 : str1 小于 str2
函数使用:
#include <stdio.h> #include <string.h> //strncmp对应的头文件 int main() { char arr1[] = "abcdef"; char arr2[] = "abcq"; int len = strncmp(arr2, arr1, 3); printf("%d\n", len); return 0; }
注意事项:
- 对前num对字节中的每一对字符进行比较,直到遇到不相等的字符。
- 比较的是每一对字符的ASCII值。
字符串查找函数
strstr
函数功能:
查找子串,查找一个字符串中是否包含子串。
函数参数:
char * strstr ( const char *str1, const char * str2); # char* 函数返回值,返回字符串中子串的起始地址,若找不到,则返回NULL; # char* str1 要搜索的字符串; # char* str2 子串
函数使用:
#include <stdio.h> #include <string.h> //strstr对应头文件 int main() { char arr1[] = "abbbcdef"; char arr2[] = "bcd"; char* ret = strstr(arr1, arr2); printf("%s\n", ret); return 0; }
模拟实现(重要):
#include <stdio.h> #include <assert.h> char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); //如果中途匹配失败需要回到str2的起始地址,所以用其他变量标识str2,保证str2的首地址不会丢失 const char* p1 = str1; const char* p2 = str2; const char* mark = str1; //用来标记每次第一个字符成功匹配的位置 while (*mark != '\0') { p1 = mark; //从mark处开始往后匹配 p2 = str2; //每次匹配后p2回到str2开头 while (*p1 == *p2 && *p1 != '\0' && *p2 != '\0') //一直往后匹配,直到遇到不相等的字符 { p1++; p2++; } if (*p2 == '\0') //如果不相等处p2为'\0'(子串全部匹配成功),则返回Mark处地址 return (char*)mark; mark++; //否则,说明这一次匹配失败,从mark后面一个字节处开始重新匹配 } return NULL; //字符串找完都没有子串就返回空指针 } int main() { char arr1[] = "abbbcdef"; char arr2[] = "bcdq"; char* ret = my_strstr(arr1, arr2); printf("%s\n", ret); return 0;
注意事项:
- 被查找的字符串和子串都不能是空串,且都以’\0’结尾。
- 如果查找成功,返回字符串中子串所在位置的首地址,如果查找失败,则返回NULL。
注:我们上面模拟实现的查找子串的函数效率比较低,如果要追求高效率,则需要使用KMP算法,有关KMP算法的相关知识,我会在后面的文章中进行介绍。
strtok
函数功能:
字符串分割,把一个字符串按照分割标志分割为几个字符串。
函数参数:
char * strtok ( char * str, const char * sep ); # char* 函数返回值,strtok函数会找到str中的下一个标记,并将其用'\0'结尾,返回一个指向这个标记的指针; # char* str 指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记; # char* sep 一个字符串,定义了用作分隔符的字符集合;
函数使用:
#include <stdio.h> #include <string.h> int main() { char* sep = "@."; char email[] = "1684277750@qq.com"; char tmp[20] = ""; //由于strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都会临时拷贝一份,操作拷贝的数据 strcpy(tmp, email); printf("%s\n", strtok(tmp, sep)); //第一次第一个参数传递被切割字符串的首地址 printf("%s\n", strtok(NULL, sep)); //第二次及以后第一个参数传递空指针(strtok会记住上一次切割的位置) printf("%s\n", strtok(NULL, sep)); return 0; }
这里我们知道目标字符串会被分隔符切割为三个字符串,所以这里我们调用了三次strtok函数,但是当我们不知道目标字符串的内容时,这种方法显然就不能用了;那么我们该如何正确的使用strtok函数呢?
我们知道,strtok函数第一次调用时需要传递目标字符串的地址,其余调用都只需要传递NULL即可,那么我们可以利用这个特点结合for循环的特性来正确调用strtok函数。
#include <stdio.h> #include <string.h> int main() { char* sep = "@."; char email[] = "1684277750@qq.com"; char tmp[20] = ""; //由于strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都会临时拷贝一份,操作拷贝的数据 strcpy(tmp, email); char* ret = NULL; //用来保存strtok函数的返回值 for (ret = strtok(tmp, sep); //初始化部分:第一次传递tmp的地址 ret != NULL; //判断部分:只要strtok的返回值ret不为空,说明继续分割 ret = strtok(NULL, sep)) //调整部分:第二次及以上传递NULL { printf("%s\n", ret); //ret不为空,说明字符串没被分割完,则打印 } return 0; }
注意事项:
- sep参数是个字符串,定义了用作分隔符的字符集合;
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记;
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: 由于strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都会临时拷贝一份,操作拷贝的数据 )
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置;
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记;
- 如果字符串中不存在更多的标记,则返回 NULL 指针;
strerror
函数功能:
C语言有一系列的库函数,当这些库函数调用失败时,会返回相应的错误码,而strerror函数的作用就是获取错误码对应的错误信息的首地址,让使用者知道程序发生错误的原因。
函数参数:
char * strerror ( int errnum ); # char* 函数返回值,返回错误码对应的错误信息的字符串的地址; # int errnum 错误码
函数使用:
#include <stdio.h> #include <string.h> //strerror的头文件 int main() { printf("%s\n", strerror(0)); printf("%s\n", strerror(1)); printf("%s\n", strerror(2)); printf("%s\n", strerror(3)); printf("%s\n", strerror(4)); printf("%s\n", strerror(5)); return 0; }
这里有一个问题,C语言中那么多的错误信息,那么我们需要记住每一个错误信息对应的错误码吗?其实,C语言中设置了一个全局的用于存放错误码的变量errno,只要调用C语言库函数发生错误,那么errno就会记录相应的错误码,所以strerror函数和errno一般都是配合使用的。
#include <stdio.h> #include <string.h> //strerror对应头文件 #include <errno.h> //errno对应头文件 int main() { FILE* pf = fopen("test.txt", "r"); if (pf == NULL) { printf("%s\n", strerror(errno)); return 1; } else { printf("文件打开成功!\n"); } return 0; }
字符函数
字符分类函数
函数 | 如果他的参数符合下列条件就返回真 |
---|---|
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 | 任何可打印字符,包括图形字符和空白字符 |
字符转换函数
函数 | 返回值 |
---|---|
tolower | 返回对应小写字母的ASCII值 |
toupper | 返回对应大写字母的ASCII值 |
内存操作函数
前面我们学习的strcpy、strcat、strcmp、strncpy、strncat、strncmp等函数都是字符串函数,只能对字符串进行相关操作,如果要对其他数据类型,如整形、字符、结构体等进行类似操作的话,就需要学习内存操作函数,常见的内存操作函数有memcpy、memmove、memcmp、memset。
memcpy
函数功能:
内存拷贝,将一块内存中num个字节的内容拷贝到另一块内存中,常用来处理不重叠内存数据的拷贝。
函数参数:
void * memcpy ( void * destination, const void * source, size_t num ); # void* 函数返回值,返回dest内存空间的地址; # void* destination 目标内存空间地址; # void* source 源空间地址; # size_t num 要拷贝的字节数;
函数使用:
#include <stdio.h> #include <string.h> //memcpy对应头文件 int main() { int arr1[] = { 1,2,3,4,5,6 }; int arr2[10] = { 0 }; memcpy(arr2, arr1, 6 * sizeof(int)); for (int i = 0; i < 6; i++) { printf("%d ", arr2[i]); } return 0; }
模拟实现:
#include <stdio.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; //强转为char*类型后赋值 //这里不要写成(char*)dest++,在某些编译器下会报错,因为强制类型转是一种临时效果 dest = (char*)dest + 1; src = (char*)src + 1; } return ret; } int main() { int arr1[] = { 1,2,3,4,5,6 }; int arr2[10] = { 0 }; my_memcpy(arr2, arr1, 6 * sizeof(int)); for (int i = 0; i < 6; i++) { printf("%d ", arr2[i]); } return 0; }
注意事项(重要):
在C语言标准中,memcpy只负责处理内存不重叠的数据,内存重叠的数据的拷贝是memmove函数负责实现的,即下面这种情况在C语言标准中memcpy函数是不能实现的:
memcpy(arr1 + 2, arr1, 4 * sizeof(int));
从上面我们memcpy的模拟实现中也可以看出,memcpy是从前向后拷贝的,这就导致在拷贝重叠内存数据时会发生数据覆盖(即arr1[2]中的数据在前面赋值中被改为1,导致将arr[2]中的数据赋给arr[4]时不是4,而是1),但是在VS下的memcpy函数是具备拷贝重叠数据的能力的,也就是说,VS下的memcpy函数同时实现了memmove函数的功能,但是其他编译器下的memcpy函数是否也具备memmove函数功能是未知的,所以我们在处理重叠内存数据拷贝的时候尽量还是使用memmove函数,以免发生错误。
memmove
函数功能:
内存移动,将一块内存数据中的内容移动覆盖至另一块内存数据,常用来处理重叠内存数据的拷贝。
函数参数:
# memmove 函数的参数和 memcpy 函数完全相同 void * memmove ( void* destination, const void * source, size_t num );
函数使用:
#include <stdio.h> #include <string.h> //memmove对应头文件 int main() { int arr1[] = { 1,2,3,4,5,6 ,7,8 }; int arr2[10] = { 0 }; memmove(arr1 + 2, arr1, 4 * sizeof(int)); for (int i = 0; i < 8; i++) { printf("%d ", arr1[i]); } return 0; }
模拟实现(重要):
思路分析:
在memcpy中我们提到在拷贝重叠内存的数据时会发生内存覆盖的情况,其实这种覆盖分为两种情况:
(1):dest的地址大于src的地址
如图,如果这时我们从前往后移动的话,那么4就会覆盖掉6,从而导致将6赋给8变成4赋给8,所以我们应该从后往前移。
(2):dest的地址小于src的地址
如果这时我们从后往前移动的话,那么7就会覆盖掉5,导致将5赋给2的时候变成7赋给2,所以这里我们应该从前往后移动。
代码实现:
#include <stdio.h> #include <assert.h> void* my_memmove(void* dest, void* src, size_t num) { assert(dest && src); void* ret = dest; //保存目标空间的地址 if (dest < src) { //前 -> 后 等价于memcpy 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; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9 }; my_memmove(arr + 1, arr + 3, 4 * sizeof(int)); for (int i = 0; i < 9; i++) { printf("%d ", arr[i]); } return 0; }
memcmp
函数功能:
内存比较,比较两块内存中前num个字节的大小。
函数参数:
int memcmp ( const void * ptr1, const void * ptr2, size_t num ); # int 函数返回值; # void* ptr1 void* ptr2 要比较的两块内存; # size_t num 要比较的字节数;
函数返回值:
>0 : ptr1 大于 ptr2; =0 : ptr1 等于 ptr2; <0 : ptr1 小于 ptr2;··
函数使用:
#include <stdio.h> #include <string.h> //memcmp对应头文件 int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 1,2,3 }; int ret = memcmp(arr1, arr2, 3 * sizeof(int)); printf("%d\n", ret); return 0; }
模拟实现:
#include <stdio.h> #include <assert.h> int my_memcmp(const void* ptr1, const void* ptr2, size_t num) { assert(ptr2 && ptr2); size_t count = 0; //用来标记相等的字节数 while (*(char*)ptr1 == *(char*)ptr2 && count < num) //一直循环,直到找到不相等的字节数据 { count++; //进入一次循环表示有一对字节相等,count++ ptr1 = (char*)ptr1 + 1; ptr2 = (char*)ptr2 + 1; } if (count < num) //如果count小于num,说明两块内存的前num个字节中有不相等的数据 return *(char*)ptr1 - *(char*)ptr2; //直接返回数据的差值 else return 0; //count等于num,说明相等 } int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 1,2,3 }; int ret = my_memcmp(arr1, arr2, 3 * sizeof(int)); printf("%d\n", ret); return 0; }
memset
函数功能:
内存设置,把一块内存中num个字节的内容设置为指定的数据。
函数参数:
void *memset( void *dest, int c, size_t count ); # void* 函数返回值,返回目标空间的地址; # int c 函数参数,指定你想要初始化的数据; # size_t count 函数参数,指定初始化的字节数
函数使用:
#include <stdio.h> #include <string.h> //memset对应头文件 int main() { char str[] = "hello world"; memset(str, 'x', 5); printf("%s\n", str); return 0; }
模拟实现:
#include <stdio.h> #include <assert.h> void* my_memset(void* dest, int c, size_t num) { assert(dest != NULL); void* ret = dest; //记录目标空间的地址 while (num--) //循环将num个字节的内容初始化为指定值 { *(char*)dest = c; dest = (char*)dest + 1; } return ret; } int main() { char str[] = "hello world"; my_memset(str, 'x', 5); printf("%s\n", str); return 0; }
加载全部内容