文章目录
记得没事就用assert断言来检查传入的是否是空指针,因为大部分传空指针的时候都是使用者未检查指针的有效性,头文件是<assert.h>,可以在assert的括号里面直接写指针,如果是空指针会被翻译成 0,可以直接被assert识别出来,也可以一次检查两个指针,用&&就可以
strlen函数
用途: 求字符串长度
格式:size_t strlen( const char* str)
模拟实现一个strlen函数
有三种方法:计数器,递归,指针-指针
注意事项:
参数指向的字符串必须是有‘\0’结尾的,不然strlen函数不能正常返回结果,返回的是随机值,如果在字符串中间有‘\0’,只会统计‘\0’之前的字符个数
(与这个函数的结束判断方式有关)
int main()
{
char arr1[] = "hello";//自带结束标志
char arr2[] = {
'a','b','c' };//没有结束标志,会越界访问找结束标志,随机值
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}
返回值是无符号整型,因此不能直接用 相减的方式 比较两个字符串的长度
例题:
int main()
{
char arr1[] = "abc";
char arr2[] = "abcdef";
if ((strlen(arr1) - strlen(arr2)) > 0)
{
printf(">");
}
else
{
printf("<=");
}
return 0;
}
明明arr1比arr2短,结果值是大于,就是因为strlen这个函数的返回值是无符号类型,在if判断时进行了强制类型转换,
将无符号的结果(此处应该是-3)转换成了一个特别大的正整数,因此是大于零
strcpy
用途:字符串拷贝,将一个字符串拷贝到另一个字符串地址里去
格式:char * strcpy(char* destination, const char* source)
注意事项
-
源字符串必须以 ‘\0’ 结束。因为,在函数运行时,必须有结束的地方,不然就停不下来了,会导致溢出,会将源字符串中的 ‘\0’ 拷贝到目标空间。在拷贝时,会把结束符号一起拷过去,同时函数停止工作
-
目标空间必须足够大,以确保能存放源字符串。//如果目标空间不够大,代码会挂掉
-
目标空间必须可变。参数的前一个指针指向的那个空间不能是被const修饰的,也会挂掉
模拟实现strcpy
char* my_strcpy(char* dest,const char* sour)
{
assert(dest && sour);
char* start = dest;
while (*dest++=*sour++)
{
}
return start;
}
int main()
{
char arr1[20] = "###############";
const char* p = "hello zhao";
printf("%s", my_strcpy(arr1, p));
return 0;
}
strcat
用途:字符串追加函数,在一个字符串后面再连接一个字符串,一般不支持自己追加自己,会覆盖字符串结束标志‘\0’
格式:char* strcat(char* destination, const char* source)
注意事项
- 源字符串必须以 ‘\0’ 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
- 字符串自己给自己追加,如何用strncat函数,限制个数,如果没有‘\0’就用if判断补‘\0’
模拟实现
char* my_strcat(char* dest, const char* sour)
{
assert(dest && sour);
char* start = dest;
//先找被追加字符串的结尾地址
while (*dest)
{
dest++;
}
//追加
*dest = *sour;
while (*dest)
{
dest++;
sour++;
*dest = *sour;
}
return start;
}
int main()
{
char arr1[20]