哪个网站做餐饮推广最好,建筑工程网招采,wordpress 描述插件,php网站开发占比文章目录 1. strlen函数1.1使用1.2模拟实现 2.strcmp函数2.1使用2.2模拟实现 3.strncmp函数3.1使用3.2模拟实现 4.strcpy函数4.1 使用4.2模拟实现 5.strcncpy5.1使用5.2模拟实现 6.strcat函数6.1使用6.2模拟实现 7.strncat函数7.1使用7.2模拟实现 8.strstr函数8.1使用8.2模拟实… 文章目录 1. strlen函数1.1使用1.2模拟实现 2.strcmp函数2.1使用2.2模拟实现 3.strncmp函数3.1使用3.2模拟实现 4.strcpy函数4.1 使用4.2模拟实现 5.strcncpy5.1使用5.2模拟实现 6.strcat函数6.1使用6.2模拟实现 7.strncat函数7.1使用7.2模拟实现 8.strstr函数8.1使用8.2模拟实现 9.strtok函数10.strerror函数11.memcpy11.1使用11.2模拟实现 12.memmove函数12.1使用12.2模拟实现 13.memset函数13.1使用13.2模拟实现 14.memcmp函数14.1使用14.2模拟实现 简介本篇文章是对C语言中常用的字符串函数和内存函数的学习以及模拟实现 文档内容来自https://legacy.cplusplus.com/ 1. strlen函数
1.1使用 字符串以 ‘\0’ 作为结束标志strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数不包含 \0 )。参数指向的字符串必须要以 ‘\0’ 结束。注意函数的返回值为size_t是无符号的 易错 使用需要包含对应的头文件string.h 下面这个代码的执行结果是什么呢
int main()
{const char* str1 abcdef;const char* str2 bbb;if (strlen(str2) - strlen(str1) 0){printf(str2str1\n);}else{printf(srt1str2\n);}return 0;
}strlen(str1) 6strlen(str2) 3。3-6小于0所以输出strstr2对吗 恭喜你掉坑里了 两个无符号数运算的结果还是无符号数-3看成无符号数就是330所以输出str2str1。
1.2模拟实现
定义新变量的方法
size_t my_strlen(char* str)
{size_t count 0;while (*str){count;str;}return count;
}指针-指针
size_t my_strlen(char* str)
{char* cur str;while (*str){str;}return str-cur;
}不定义新变量递归法
size_t my_strlen(char* str)
{if (*str \0){return 0;}else{return 1 my_strlen(str 1);}
}2.strcmp函数
2.1使用 两个字符串进行比较的时候就不能再像整数那样使用 来比较了它实际比较的是两个字符串对应字符的ASCLL码值
第⼀个字符串大于第⼆个字符串则返回大于0的数字第⼀个字符串等于第⼆个字符串则返回0第⼀个字符串小于第⼆个字符串则返回小于0的数字 2.2模拟实现
int my_strcmp(const char* str1, const char* str2)
{assert(str1 ! NULL);assert(str2 ! NULL);while (*str1 *str2){if (*str1 \0){return 0;}str1;str2;}return str1 - str2;/*if (*str1 *str2){return 1;}elsereturn -1;*/
}3.strncmp函数
3.1使用 strncmp函数与strcmp函数的使用十分相似strncmp函数只是限定了比较几个字符的大小 例如比较前五个字符的大小 当要比较的长度大于两个串本身的长度时比较到其中一个串的末尾即可
3.2模拟实现
int my_strncmp(const char* str1, const char* str2, int num)
{assert(str1 ! NULL);assert(str2 ! NULL);//无字符串可比直接返回0if (!num){return 0;}//1.两字符串相等//2.在规定的范围内//3.字符串未到末尾while ((*str1 *str2) --num *str1 ! \0){str1;str2;}return *str1 - *str2;
}4.strcpy函数
4.1 使用 源字符串必须以 ‘\0’ 结束会将源字符串中的 ‘\0’ 拷贝到目标空间。目标空间必须足够大以确保能存放源字符串。目标空间必须可修改。函数返回目标空间的起始地址 4.2模拟实现
写法1
char* my_strcpy(char* dest, const char* src)
{assert(dest ! NULL);assert(src ! NULL);char* ret dest;while (*src){*dest *src;dest;src;}*dest *src;return ret;
}写法2
char* my_strcpy(char* dest, const char* src)
{assert(dest ! NULL);assert(src ! NULL);char* ret dest;while (*dest *src){;}return ret;
}5.strcncpy
5.1使用 将源字符串的前 num 个字符复制到目标字符串。如果在复制 num 个字符之前找到源 C 字符串的末尾由 null 字符表示则 destination 将用零填充直到总共写入 num 个字符。不足num个用0填充 5.2模拟实现
char* my_strncpy(char* dest, const char* src, int num)
{assert(dest ! NULL);assert(src ! NULL);char* ret dest;while ((*dest *src) --num){;}while (--num){*dest 0;dest;}return ret;
}6.strcat函数
6.1使用 源字符串必须以 ‘\0’ 结束目标字符串中也得有 \0 否则没办法知道追加从哪⾥开始。目标空间必须足够大以确保能存放源字符串。目标空间必须可修改。函数返回目标空间的起始地址字符串自己给自己追加如何需要使用memmove 6.2模拟实现
char* my_strcat(char* dest, const char* src)
{assert(dest ! NULL);assert(src ! NULL);char* ret dest;//找dest的\0while (*dest){dest;}//开始追加while (*dest *src){;}return ret;
}7.strncat函数
7.1使用 将源的前 num 个字符附加到目标外加一个终止 null 字符如果 source 中 C 字符串的长度小于 num则仅复制 ‘\0’ 之前的内容
7.2模拟实现
char* my_strncat(char* dest, const char* src, int num)
{assert(dest ! NULL);assert(src ! NULL);char* ret dest;//找dest的\0while (*dest){dest;}//开始追加while (num-- (*dest *src)){;}*dest 0;return ret;
}8.strstr函数
8.1使用 str1中找str2字符串返回str2第一次出现位置的地址字符串的比较匹配不包含 \0 字符以 \0 作为结束标志 8.2模拟实现
char* my_strstr(const char* str1, const char* str2)
{assert(str1 ! NULL);assert(str2 ! NULL);char* ptr1 NULL;char* ptr2 NULL;if (!(*str2)){return (char*)str1;}while (*str1){ptr1 (char*)str1;ptr2 (char*)str2;while ((*ptr1 *ptr2) *ptr1 *ptr2){ptr1;ptr2;}if (*ptr2 0){return (char*)str1;}str1;}return NULL;
}9.strtok函数 delimiters参数指向⼀个字符串定义了用作分隔符的字符集合第⼀个参数指定⼀个字符串它包含了0个或者多个由delimiters字符串中⼀个或者多个分隔符分割的标记。strtok函数找到str中的下⼀个标记并将其⽤ \0 结尾返回⼀个指向这个标记的指针。注strtok函数会改变被操作的字符串所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。strtok函数的第⼀个参数不为 NULL 函数将找到str中第⼀个标记strtok函数将保存它在字符串中的位置。strtok函数的第⼀个参数为 NULL 函数将在同⼀个字符串中被保存的位置开始查找下⼀个标记。如果字符串中不存在更多的标记则返回 NULL 指针。
是不是有点难理解 用大白话说就是 strtok函数是以一个delimiter函数中的字符为分隔依据的函数第一次调用该函数需要将要分隔的字符串的地址传给他它会根据分隔依据找第一次在字符串中出现该分隔符的位置将其用\0替代并且返回一个指向这个分隔符的指针。下一次调用就只需要传给它空指针和分隔依据它会从上一个分隔符位置再次开始找直到找到分隔符。最终找到字符串结尾即可。 10.strerror函数
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码⼀般是放在 errno.h 这个头⽂件中说明的C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码只不过程序启动的时候errno是0 表⽰没有错误当我们在使⽤标准库中的函数的时候发⽣了某种错误就会讲对应的错误码存放在errno中⽽⼀个错误码的数字是整数很难理解是什么意思所以每⼀个错误码都是 有对应的错误信息的。 strerror函数就可以将错误对应的错误信息字符串的地址返回。
打印0-10错误码对应的信息 例如我们使用fopen函数打开本地某一个文件夹它就会自动打印处使用该函数产生的错误。 再我们以上所讲的所有字符串函数你要相对字符串进行操作是不是必须知道它的类型呀可不是什么时候我们都能准确的知道的比如一个结构体类型的数据。当我们不知道的时候那么该如何操作呢下面我们将进行讲解
11.memcpy
11.1使用 将 num 字节的值从源指向的位置直接复制到目标指向的内存块源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本该函数不检查源中的任何终止 null 字符 - 它始终准确复制 num 个字节 11.2模拟实现
void* my_memcpy(void* dest, const void* src, int num)
{void* ret dest;while (num--){*(char*)dest *(char*)src;dest (char*)dest 1;src (char*)src 1;}return ret;
}12.memmove函数
12.1使用 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。如果源空间和⽬标空间出现重叠就得使⽤memmove函数处理 12.2模拟实现
void* my_memmove(void* dest, const void* src, int num)
{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;
}13.memset函数
13.1使用 memset是⽤来设置内存的将内存中的值以字节为单位设置成想要的内容。将ptr指向的内存的第一个字节设置为指定的值 13.2模拟实现
void* my_memset(void* ptr, int x, int num)
{void* ret ptr;while (num--){*((char*)ptr num) x;}return ret;
}14.memcmp函数
14.1使用 比较从ptr1和ptr2指针指向的位置开始向后的num个字节如果它们都匹配则返回零或者返回一个不同于零的值如果它们不匹配则表示哪个值更大。请注意与 strcmp 不同该函数在找到 null 字符后不会停止比较, 14.2模拟实现
/*
当buf1buf2时返回值0
当buf1buf2时返回值0
当buf1buf2时返回值0
*/
int my_memcmp(const void* buffer1, const void* buffer2, int num)
{ 当比较位数不为0时且每位数据相等时移动指针while (--num *(char*)buffer1 *(char*)buffer2){buffer1 (char*)buffer1 1;buffer2 (char*)buffer2 1;}return (*(char*)buffer1) - (*(char*)buffer2);
}目前本人学习和使用到的字符串、内存函数就这些如有错误请批评指正