长度不受限制的字符串函数
strlen()函数
strlen()函数使用
strlen()返回值为size_t (typedef unsigned int) ,参数为一个char*的指针,即为一个地址。然后strlen函数从这个地址开始一个字节一个字节的向后访问,直到遇见\0才停止,然后返回前面访问的字符数。
#include<stdint.h>
#include<string>
int main()
{
char arr[10] = { 'a','b','c','d','e','f' };
//当给数组设置长度后,并且初始化时没有占满数组,则后面的数组元素会自动补为\0
//但当没有设置数组长度时,数组后面就不会自动补\0;
if (strlen("abc") - strlen("qwerty") > 0)
//strlen()的返回值为无符号整型,所以3-6=-3,但是比较时会将-3按照无符号整数解析
//所以会一直大于0
//故strlen()的返回值不要相减后和0比较大小,要是比较的话就强制类型转换为int
//或者直接将两个strlen()返回值比较大小
{
printf(">\n");
}
else
{
printf("<=\n");
}
return 0;
}
模拟实现strlen()函数
计数器方法
//计数器方法
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str); //断言,判断传进来的str是不是NULL,如果是就中断程序
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char str[] = "abcdef";
int res = my_strlen(str);
printf("%d\n", res);
printf("%d\n", my_strlen(str));
return 0;
}
递归方法
//递归的方法
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str); //断言,判断传进来的str是不是NULL,如果是就中断程序
if (*str == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(str + 1); //不能写成str++,那样会先把str传入函数,然后str才++
}
}
int main()
{
char str[] = "abcdef";
int res = my_strlen(str);
printf("%d\n", res);
printf("%d\n", my_strlen(str));
return 0;
}
指针-指针
//指针-指针
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str); //断言,判断传进来的str是不是NULL,如果是就中断程序
char* p = str;
while (*p != '\0')
{
p++;
}
return p-str;
}
int main()
{
char str[] = "abcdef";
int res = my_strlen(str);
printf("%d\n", res);
printf("%d\n", my_strlen(str));
return 0;
}
strcpy()函数
strcpy()函数的使用
strcpy()函数返回一个char*类型的指针,即返回一个地址,该地址就是目标字符串的首地址。
第一个参数为char*类型的指针, 即目标字符串的首地址。
第二个参数为char*类型的指针,即为源字符串的首地址。
strcpy()拷贝时会将源字符串的\0也拷贝进去。
//strcpy()函数
#include<stdio.h>
#include<string.h>
int main()
{
//char arr1[4] = "x"; //当目标数组的长度小于源字符串长度时,会发生越界访问,
//但是strcpy()函数还是会将源字符串里面的内容都拷贝到目标数组中。
//char* arr1 = "qwersdjf"; //arr1指向的是常量字符串,常量是不可修改的
char arr1[20] = "XXXXXXXXXXXX";
//char arr2[] = "abcdef";
char arr2[10] = { 'a','b','c' }; //不全部初始化,后面的会补上\0
strcpy(arr1, arr2);
printf("%s\n", arr1); //abcdef\0XXXXX
return 0;
}
模拟实现strcpy()函数
#include<stdio.h>
#include<assert.h>
//strcpy函数返回的是目标空间的起始地址
//strcpy函数的返回类型的设置是为了实现链式访问
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;
//while (*src != '\0')
//{
// *dest = *src;
// dest++;
// src++;
//}
//*dest = *src; //最后的\0也拷贝过去
//简便写法
while (*dest++ = *src++);
return start;
}
int main()
{
/*char arr1[20] = "abcdefdskjfk";
char arr2[] = "xyz";*/
char arr1[20] = { 0 };
char* arr2 = "abcdef";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
strcat()函数
strcat()函数使用
strcat()为追加字符串函数。即在一个字符串末尾追加另一个字符串。
strcat()的返回值为一个char*类型的指针,即为目标字符串的首元素地址。
strcat()的第一个参数为目标字符串的首元素地址。
strcat()的第二个参数为源字符串的首元素地址。
strcat()函数会将源字符串追加到目标字符串后面,并且会将目标字符串的\0字符给覆盖,但是也会将源字符串的\0跟着追加过去。
strcat()函数中的源字符串必须以'\0'结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。
字符串不可以使用该函数实现自己给自己追加,如果自己给自己追加会发生越界访问。
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "hello\0XXXXXX";
//arr2追加到arr1后面,会先找到\0,然后从\0开始追加(会将\0直接覆盖),并且会将arr2的\0也追加过去
//所以这就要求源字符串arr2必须以\0结尾.
char arr2[] = " world";
strcat(arr1, arr2);
//printf("%s\n", arr1);
printf("%s\n",strcat(arr1,arr2));
//实验strcat()函数实现字符串自己给自己追加
char arr3[] = "bit";
strcat(arr3, arr3);
printf("%s\n", arr3); //会将arr3中bit\0中的\0给覆盖,然后一直循环追加bitbitbit,直到遇见内存中的\0才停止
return 0;
}
模拟实现strcat()函数
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* start = dest;
while (*dest != '\0')
{
dest++;
}
//while (*src != '\0')
//{
// *dest = *src;
// dest++;
// src++;
//}
//*dest = *src; //将源字符串中最后的\0也追加过去
//简便写法
while (*dest++ = *src++);
return start;
}
int main()
{
char arr1[20] = "hello\0XXXXXXX";
char arr2[] = " world";
my_strcat(arr1, arr2);
//printf("%s\n", arr1);
printf("%s\n", my_strcat(arr1, arr2)); //链式访问
return 0;
}
strcmp()函数
strcmp()函数使用
strcmp()函数的返回值为int,当返回的值大于0,代表第一个字符串大于第二个字符串;当小于0,代表第一个字符串小于第二个字符串;当等于0,代表两个字符串大小相等。strcmp()比较字符串不是比较长度,而是从字符串首个字符开始,逐一比较,如果有一个字符不同,则字符ACSCII码大的字符所在的字符串就大于另一个字符串。当比较到\0时两个字符串还都相同就说明两个字符串的大小相等。 VS中的strcmp()函数规定了第一个字符串大于第二个字符串返回1,第一个字符串小于第二个字符串返回-1,两个字符串相等返回0.但其他编译器返回值可能有所不同。
第一个参数为第一个要比较的字符串的首字符地址。
第二个参数为第二个要比较的字符串的首字符地址。
//strcmp
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = "abc";
int ret = strcmp(arr1, arr2);
//strcmp函数比较的不是字符串的长度,而是比较字符串中对应位置上的字符的大小
//如果相同,就比较下一对,直到不同或者都遇到\0
if (ret > 0)
{
printf(">\n");
}
else if (ret == 0)
{
printf("==\n");
}
else
{
printf("<\n");
}
printf("%d\n", ret);
return 0;
}
模拟实现strcmp()函数
#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;
}
else
{
return -1;
}*/
//或者写成这样
return *str1 - *str2;
}
int main()
{
char arr1[] = "abr";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
if (ret > 0)
{
printf(">\n");
}
else if (ret == 0)
{
printf("==");
}
else
{
printf("<\n");
}
return 0;
}
长度受限制的字符串函数
strncpy()函数
strncpy()函数使用
strncpy()函数的返回值和参数都和strcpy()函数的类型,不过strncpy多了一个参数,该参数为一个size_t类型的无符号整型,该参数可以定义,要从源字符串中拷贝到目标字符串的字符个数count。
如果源字符串的长度小于count,则拷贝完源字符串之后,会在目标后边追加0,直到count个。
//strncpy
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "qwerdfjk";
strncpy(arr1, arr2, 3); //只会拷贝arr2字符串的前三个字符替换arr1的前三个字符
printf("%s\n", arr1); //qwedef
char arr3[] = "abcdef";
char arr4[] = "qwe";
strncpy(arr3, arr4, 5); //如果源字符串的长度不够,则拷贝完源字符串后会在后面补\0
printf("%s\n", arr3);
return 0;
}
模拟实现strncpy()函数
//strncpy()
char* my_strncpy(char* dest, const char* src, size_t count)
{
assert(dest && src);
char* head = dest;
while (count != 0)
{
*dest = *src;
dest++;
if (*src != '\0')
{
src++;
}
--count;
}
return head;
}
int main()
{
char arr1[20] = "abcdXXXXXX";
char arr2[5] = "efgh";
//strncpy(arr1, arr2, 6);
//printf("%s\n", strncpy(arr1, arr2, 6));
my_strncpy(arr1, arr2, 2);
printf("%s\n", arr1);
printf("%s\n", my_strncpy(arr1, arr2, 2));
return 0;
}
strncat()函数
strncat()函数使用
strncat()函数和strcat()函数的返回值和参数类似,只不过strncat()多了一个参数,该参数用来定义从源字符串中向目标字符串中追加的字符个数count。
strncat中的源字符串追加到目标字符串后面count个字符后,还会在后面补一个\0。当源字符串的长度不够count时,会把源字符串都追加到目标字符串后面,然后只在后面补一个\0,没有追加count个字符也没关系。
strncat可以实现自己给自己追加。
//strncat
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abcdeXXXX";
char arr2[] = "qwerdks";
strncat(arr1, arr2, 5);
printf("%s\n", arr1); //abcdeXXXXqwerd
char arr3[20] = "abcde\0XXXXXXXX";
char arr4[] = "qwerrtuta";
//strncat会寻找目标字符串的\0,然后将从\0开始追加(会将\0覆盖掉)
//并且会在追加的源字符串后面补上\0
strncat(arr3, arr4, 5); //abcdeqwerr
printf("%s\n", arr3);
char arr5[20] = "abcde\0XXXXXXXX";
char arr6[] = "qwe";
//当源字符串arr6的长度不够5时,会先将arr6追加到arr5后,然后只会补一个\0
strncat(arr5, arr6, 8);
printf("%s\n", arr5);
return 0;
}
模拟实现strncat()函数
//strncat()
char* my_strncat(char* dest, const char* src, size_t count)
{
assert(dest && src);
char* head = dest;
while (*dest != '\0')
{
dest++;
}
while (count != 0)
{
*dest = *src;
if (*src == '\0')
{
break;
}
dest++;
src++;
count--;
}
*dest = '\0';
}
int main()
{
char arr1[20] = "abcdXXXX";
char arr2[5] = "efgh";
//strncat(arr1, arr2, 8);
//my_strncat(arr1, arr2, 4);
my_strncat(arr1, arr1, 4);
printf("%s\n", arr1);
return 0;
}
strncmp()函数
strncmp()函数使用
strncmp()的返回值和参数与strcmp()函数的类似,只不过strncmp()函数多了一个比较字符数量的参数count,即比较两个字符串的前count个字符。
//strncmp
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdq";
int ret1 = strncmp(arr1, arr2, 4); //只会比arr1和arr2的前四个字符
printf("%d\n", ret1);
char arr3[] = "abcdef";
char arr4[] = "ab";
int ret2 = strncmp(arr3, arr4, 4); //如果有一个字符串的长度不够,也正常比较,如果前面的字符都相等,那么最后就是'\0'和字符比较
printf("%d\n", ret2);
char arr5[] = "abcdef";
char arr6[] = "abc";
if (arr5 < arr6) //比较的是arr1和arr2的地址
{
printf("hh\n");
}
if ("abc" < "abcdef") //比较的是常量字符"abc" 和 "abcdef"的地址
{
printf("hh\n");
}
return 0;
}
模拟实现strncmp()函数
//strncmp()
int my_strncmp(const char* str1, const char* str2, size_t count)
{
assert(str1 && str2);
while ((*str1 == *str2) && (count != 0))
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
count--;
}
/*if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}*/
return *str1 - *str2;
}
int main()
{
char arr1[20] = "abcdXXXXX";
char arr2[5] = "abcd";
//printf("%d\n", strncmp(arr1, arr2, 5));
printf("%d\n", my_strncmp(arr1, arr2, 3));
return 0;
}
strstr()函数
strstr()函数使用
strstr()函数为查找子字符串函数,该函数的返回值为char*类型的指针,即为查找到的子字符串在目标字符串中第一次出现的位置的地址,如果目标字符串中没有该子字符串,则会返回NULL。
第一个参数为目标字符串的首字符地址。
第二个参数为要查找的子字符串的首字符地址。
//strstr
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdeqabcdefafs";
char arr2[] = "cdef";
//strstr()函数会将arr2字符串在arr1字符串中首次出现的位置的地址返回
//如果在arr1中没有找到arr2,就会返回NULL
char* ret = strstr(arr1, arr2);
if (NULL == ret)
{
printf("找不到字符串\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
模拟实现strstr()函数
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
//因为形参str1和str2都用const修饰,所以为了保持一致,下面的s1、s2、cur也需要用const修饰
const char* s1 = str1;
const char* s2 = str2;
const char* cur = str1; //回溯指针,用来使s1回到起始位置。
while (*cur != '\0')
{
s1 = cur; //将s1回溯到下一个字符
s2 = str2; //将s2回溯到字符串首字符
while (*s1 == *s2 && *s1!='\0' && *s2!='\0') //如果s1和s2指向的字符一直,就继续向后寻找,直到遇见*s1和*s2不想等,或者有一个字符串结束.
{
s1++;
s2++;
}
if (*s2 == '\0') //如果结束是因为s2字符串已经结束,则说明查找成功
{
//因为该函数要返回char*的指针,而cur是const修饰的,所以强制类型转换一下,使返回的cur为char*类型的指针
return (char*)cur; //返回arr1中该字符串的首地址
}
cur++; //如果没有*cur字符为首字符没有查到,则使cur向后移一位,以后面的字符为首字符开始查找
}
return NULL; //如果cur指向\0时还没有查到,说明arr1中没有arr2字符串。则返回NULL
}
int main()
{
char arr1[] = "abbsabcafa";
char arr2[] = "bbc";
char* ret = my_strstr(arr1, arr2);
if (ret == NULL)
{
printf("没有找到\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
strtok()函数
strtok()函数使用
strtok()函数为分割字符串函数,该函数的返回值为分割后字符串的首字符地址。
第一个参数指定一个字符串,它包含了0个或者多个由strDelimit字符串中一个或者多个分隔符分割的标记。
第二个参数strDelimit是个字符串,定义了用作分隔符的字符集合。
strtok函数找到strToken字符串中的下一个标记,并将其用\0结尾,返回一个指向这个被截断字符串的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为NULL,函数将找到strToken中第一个标记,strtok函数将保持它在字符串中的位置。
strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回NULL指针。
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "dongruo@qq.com!!";
char buf[30] = { 0 };
char buf2[30] = { 0 };
strcpy(buf, arr); //strtok函数会改变传进去的字符串,所以在使用时一般传入临时拷贝的内容,并且该字符串需要是可修改的。
strcpy(buf2, arr);
const char* sep = "@."; //该字符串为分隔符集合字符串,就是要按照这个字符串里面的字符来分割buf字符串
printf("%s\n", strtok(buf, sep)); //只找第一个标记,第一次使用需要第一个参数需要传入被分割字符串,strtok找到后,
//会将该字符串中第一个出现的分隔符设为\0,并且会保存分隔符后面的地址,并且将这个包含\0的字符串返回。
//当第二次使用strtok函数时,第一个参数可以传NULL,然后就会从上一次保存的地址开始向后查找分隔符,找到后会将分隔符设为\0,
//然后接着保存分隔符后面的地址,并且将处理好的包含\0的字符串返回。
printf("%s\n", strtok(NULL, sep)); //是从保存好的位置开始继续往后找
printf("%s\n", strtok(NULL, sep)); //是从保存好的位置开始继续往后找
//使用循环打印分割好的字符,因为使用时不知道目标字符串里面含有多少个分隔符
char* str = NULL;
//先在初始化时调用第一次strtok,并且第一参数传入目标字符串,
//然后判断strtok的返回值str,如果strtok函数找到了就返回被分割字符串的首地址,如果没找到就返回NULL/
//然后接下来的调用strtok第一个参数就传入NULL,以便向后查找并且分割目标字符串。
for (str = strtok(buf2, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s\n", str);
}
return 0;
}
strerror()函数
strerror()函数使用
strerror()函数的返回值是一个char*的指针,即返回的是错误信息。
该函数的参数为int型,就是传入一个错误码,然后strerror()函数根据这个错误码返回对应的错误信息。
#include<stdio.h>
#include<errno.h>
#include<limits.h>
#include<string.h>
#include<stdio.h>
int main()
{
//每个错误都对应一个错误码。当程序运行时遇到错误后,就会将错误码变量errno的值改为对应的错误码
//然后调用strerror函数并且传入错误码,就会打印对应的错误信息。
//errno为一个全局变量
int* p = (int*)malloc(LLONG_MAX); //向堆区申请内存
if (p == NULL)
{
printf("%s\n", strerror(errno)); //Not enough space
printf("%d\n", errno); //12 ,所以可知Not enough space错误的错误码为12
perror("Malloc"); //perror函数会直接将错误的信息打印出来,并且会将传入的字符串后面加上:然后将错误信息打印在后面。
return 1;
}
printf("nn");
return 0;
}
字符操作函数
字符分类函数
字符分类函数使用
这些函数用来判断字符是否符合条件,如果符合条件就返回真,不符合就返回假。
使用这些函数需要引用头文件,即 #include<ctype.h>
字符转换
可以将里面的字母转换为大写或者小写,如果已经是大写或小写就不会再转换了。
//字符判断函数
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
if (isdigit('2'))
{
printf("是数字\n");
printf("%d\n", isdigit('2')); //如果符合条件就返回真,即返回非0数字
printf("%d\n", isdigit('a')); //如果不符合条件就返回假,即返回0
}
printf("%c\n", toupper('a')); //A
printf("%c\n", toupper('A')); //如果已经是大写,就不做任何操作 A
printf("%c\n", tolower('B')); //b
return 0;
}
内存操作函数
memcpy()函数
memcpy()函数使用
memcpy()函数的返回值为一个void*类型的指针,即为目标数组的地址。
memcpy()函数的第一个参数和第二个参数都设置为void*型,是为了使该函数可以拷贝任意类型的数组。第一个参数为目标数组地址,第二个参数为源数组的地址。
第三个参数为size_t类型的无符号整数,定义了从源地址向后拷贝多少字节的数据到目标地址。
函数memcpy从src位置开始向后复制count个字节的数据到dest的内存位置。
这个函数在遇到'\0'的时候并不会停下来,只有在复制够count个字节后才会停下。
如果src和dest中有任何的重叠,复制的结果都是错的。
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
memcpy(arr2, arr1, 20); //将arr1的前二十个字节的数据拷贝到arr2中
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
模拟实现memcpy()函数
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src,size_t count)
{
assert(dest && src);
void* start = dest;
while (count)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
count--;
}
return start;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
my_memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
my_memcpy(arr1 + 2, arr1, 20); //当拷贝的数据在内存中重叠时,就会发生错误,因为原来的数据被修改的数据覆盖了。
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
memmove()函数
memmove()函数使用
memmove()函数memcpy()函数的差别就是memmove函数处理的源内存和目标内存块是可以重叠的。所以如果源空间和目标空间出现重叠,就得使用memmove函数处理。
//memmove()
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20); //可以实现重叠内存的拷贝
int i = 0;
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
模拟实现memmove()函数
my_memmove()函数解决目标内存与源内存重叠情况的办法,即通过判断来决定是从前向后拷贝还是从后向前拷贝。
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* start = dest; //用来记录要返回的地址
if (dest < src) //当dest<src时,从前向后拷贝
{
while (count)
{
//因为形参定义类型为void*,是为了使任何数据类型的地址都可以使用此函数拷贝,
//而在实现时,都强制类型转换为char*类型,这样才能按字节拷贝数据
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
count--;
}
}
else //剩下的情况从后向前拷贝
{
while (count)
{
//即从目标空间的最后开始拷贝。
//(char*)dest + count刚好指向了目标空间后的第一个地址,所以要-1才指向目标空间最后一字节的地址。
*((char*)dest + count - 1) = *((char*)src + count - 1);
count--;
}
}
return start; //将拷贝好的空间地址返回
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1 + 2, arr1,20); //可以实现重叠内存的拷贝
int sz = sizeof(arr1) / sizeof(arr1[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr1[i]); //1 2 1 2 3 4 5 8 9 10
}
return 0;
}
memcpy()函数和memmove()函数比较
虽然模拟实现的my_memcpy函数不能处理内存空间重叠的情况,但是在编译器的完善中,编译器实现的mymcpy()函数已经也可以处理内存空间重叠的情况了,所以编译器将memcpy()函数的功能完善的和memmove()函数的功能基本一致了。
memcmp()函数
memcmp()函数使用
memcmp()函数的返回值为int型,即和strcmp()函数的返回值代表的意义相同。
memcmp()函数比strcmp()函数多了一个size_t类型的参数,该参数定义了两个字符串要比较的字符的个数count。即比较从buf1和buf2指针开始的count个字节。
//memcmp
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,3,4,0x11223305 };
int ret = memcmp(arr1, arr2, 17);
printf("%d\n", ret); // 0
ret = memcmp(arr1, arr2, 18);
printf("%d\n", ret); // -1
return 0;
}
模拟实现memcmp()函数
//memcmp()
int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
assert(buf1 && buf2);
void* str1 = buf1;
void* str2 = buf2;
while ((*((char*)str1) == *((char*)str2))&&(count!=0))
{
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
--count;
}
if (count == 0)
{
return 0;
}
if (*((char*)str1) > *((char*)str2))
{
return 1;
}
else
{
return -1;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,3,4,0x11223305 };
int ret = memcmp(arr1, arr2, 17);
printf("%d\n", ret); // 0
ret = memcmp(arr1, arr2, 18);
printf("%d\n", ret); // -1
return 0;
}
memset()函数
memset()函数使用
memset()函数的返回值为void*类型的指针,即为处理过的数据的地址。
第一个参数为void*类型的指针,所以任何类型的数据都可以调用memset()函数来实现按字节设置数据。
第二个参数为int型,即为要设置的数据为什么。
第三个参数为size_t类型,即为要改变的字节数。
//memset()
#include<stdio.h>
#include<string.h>
int main()
{
int arr[] = { 0x11111111,0x22222222,3,4,5 };
memset(arr, 6, 20); //memset是以字节为单位来初始化内存单元的
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%p\n", arr[i]); //
}
return 0;
}
模拟实现memset()函数
//memset()
void* my_memset(void* dest, int c, size_t count)
{
assert(dest);
void* start = dest;
while (count)
{
*((char*)dest) = (char)c;
dest = (char*)dest + 1;
--count;
}
return dest;
}
int main()
{
int arr1[] = { 0x11111111,0x22222222,3,4,5 };
//memset(arr1, '\0', 4);
my_memset(arr1, 6, 20);
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i++)
{
printf("%p ", arr1[i]);
}
printf("\n");
return 0;
}