【C语言进阶】字符函数和字符串函数的内部原理
前言
c语言没有字符串类型,字符串通常放在常量字符串或者字符数组里面,本节内容是介绍关于字符串的函数,并且详细剖析了内部的原理。
1.strlen函数
size_t strlen(const char* str);
原理是字符指针遇到'\0'就停止,最终计算'\0'之前的长度。所以这里放一个字符数组那么得出的值就是随机值。
strlen的返回值是size_t,其实就是无符号整型,在使用这个函数的时候需要注意一些小的细节。
易错:由于strlen返回的是无符号整型,所以永远不会输出负数,这里的-3被当做无符号整型的时候,在内存中是一个非常大的数字,这里的结果就会影响逻辑判断。
1.1 模拟实现
#include<stdio.h>
#include<assert.h>
// 1.模拟实现strlen
size_t mystrlen(const char* str)
{assert(str); // 断言,避免是空指针size_t len = 0;while (*str != '\0'){str++;len++;}return len;
}int main()
{char str[] = "hello";printf("%d\n",mystrlen(str));return 0;
}
2.strcpy函数
char* strcmp(const char* destination,const char* source);
字符串拷贝函数,将源头的数据拷贝到目的地数组去,具体的应用场景是,需要把一个字符串传给字符数组的时候。
这个函数有一个缺点,那就是字符串本身含'\0'的时候,拷贝字符串会不完整。这是因为函数内部是按照'\0'作为字符串的终止符,只会拷贝‘\0’及之前的字符。
常见的错误:
下图中p所指向的是一个常量字符串,内容是无法更改的。
2.1 模拟实现
需要注意的是,这里返回的是目标字符数组的起始地址。
#include<stdio.h>
char* mystrcpy(char* dest, const char* str)
{assert(dest);char* ret = dest;assert(str);while (*str != '\0') {*dest = *str;dest++;str++;}*dest = *str;return ret; // 返回目标数组首地址
}int main()
{char str[] = "hello";char dest[20] = { 0 };mystrcpy(dest,str);//printf("%d\n",mystrlen(str)); printf("%s\n",dest);return 0;
}
3. strcat函数
char* strcat(const char* destination,const char* source);
字符串追加,将源字符串追加到目的字符串。
3.1 模拟实现
#include<stdio.h>
#include<assert.h>
char* mystrcat(char* dest,const char* source)
{assert(dest && source);char* ret = dest;while (*dest != '\0') {dest++;}while (*source != '\0') {*dest = *source;dest++;source++;}*dest = *source; // source的\0直接给destreturn ret;
}int main()
{char str[20] = "hello ";mystrcat(str, "world");printf("%s\n",str);return 0;
}
需要注意的第一点是,不能给自己追加自己,这是因为,在覆盖'\0'之后追加最后一个\0的时候,发现之前的\0已经被覆盖掉了,所以这会陷入死循环。
4.strcmp函数
int strcmp(const char* str1,const char* str2);
待续......