strcpy
完成字符串拷贝。
strcpy函数的返回类型是字符指针,参数有两个,都是字符指针。
返回值是目标地址的起始地址。
第一个参数是目标字符串的地址,第二个是以‘\0’结尾的源字符串的地址。参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。
strcpy的功能是拷贝字符串,包括'\0',将源字符串的内容拷贝的目标地址中,拷贝的过程不对越界进行检查,如果目标地址的数组大小比源字符串大小小,会破坏目标地址数组的结构,程序崩溃。需要目标空间足够大,找到'\0'并且拷贝到目标地址,这个函数才会结束。
char arr[5];
strcpy(arr, "abcdef");
// 字符数组5个字节,拷贝字符串需要7个字节,无法正常拷贝,越界崩溃
目标空间必须可修改。
const char* p = "abcd";
strcpy(p, "abc");
如果目标地址和源字符串地址指向的是同一块空间(不是相同地址的意思,比如目标字地址是字符数组"abc"的首地址,源字符串的地址是同一个字符数组其它元素的地址),这是标准未定义的行为。(不要使用strcpy完成同内存拷贝)
#include <stdio.h>
#include <assert.h>
// strcpy模拟实现
char* Strcpy(char* dest, const char* source)
{
// 优化,不加也无所谓
assert(dest != NULL && source != NULL);
char* ret = dest;
while (*dest++ = *source++)
{
;
}
return ret;
}
int main()
{
char arr[20];
printf("%s", Strcpy(arr, "hello world"));
return 0;
}
assert里面条件不成立,编译器会直接报错。
后置++,先使用后++,先对两个指针解引用,将源字符串的字符赋值给目标空间,目标地址和源字符串地址都+1,往后移一位,再判断该字符是不是'\0',如果不是'\0',继续重复,如果是'\0',条件不成立,因为'\0'的ASCII码值是0,结束循环。
源字符串的地址指向的数据'h'拷贝到目标地址上,两个地址++往后走,重复,直到找到'\0'结束。
需要返回值,创建一个字符指针保存目标地址的起始地址。返回值的目的是为了实现链式访问(返回值作为下一个函数的参数);因为源字符串的内容不需要改变,形参写成const char* source,具有常属性,无法被修改,函数里无法通过*source修改字符串内容,在编译期间报语法错误,直接发现问题,防止将目标地址的数据拷贝到源字符串中。
strcat
字符串追加到另一字符串后。
strcat函数的返回类型是字符指针,参数有两个,都是字符指针。
返回值是目标字符串的起始地址。
第一个参数是目标地址的起始地址,第二个参数是源字符串的地址。这两个参数指向的字符串要有'\0'作为结束标志,参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。目标空间必须可修改。
strcat是功能是将源字符串追加到目标字符串后,先在目标字符串中找到'\0',在这个位置开始追加源字符串,拷贝到源字符串的'\0'结束,'\0'也要拷贝。strcat函数追加的过程不对越界进行检查,如果源字符串追加到目标字符串后大于数组大小,破坏目标地址数组的结构,程序崩溃。
strcat也不能完成同内存字符串的追加,这是标准未定义的。
#include <stdio.h>
#include <assert.h>
// strcat模拟实现
char* Strcat(char* dest, char* src)
{
assert(dest && src);
char* ret = dest;
// 找目标空间中的\0
while (*dest)
{
dest++;
}
// 追加
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr[20] = "hello";
printf("%s", Strcat(arr, " world"));
return 0;
}
不需要改变源字符串,形参源字符串的地址加const修饰。
strcmp
比较字符串大小,不能直接使用>、<、==这些操作符,使用strcmp函数比较字符串。
strcmp函数的返回类型是整型,参数有两个,都是字符指针。
返回值是一个整型,如果字符串1大于字符串2,返回一个大于0的整型。如果两个字符串相等,返回0。如果字符串1小于字符串2,返回一个小于0的整型。
两个字符指针,都是指向字符串的首元素的地址,需要是以'\0'结尾的字符串。参数不能传空指针(NULL),对空指针进行解引用,程序崩溃。
strcmp比较两个字符串字符的ASCII码值,按顺序依次比较,到'\0'结束,如果中途遇到不一样直接返回值差值即可。
#include <stdio.h>
#include <assert.h>
// strcmp模拟实现
int Strcmp(const char* s1, const char* s2)
{
assert(s1 && s2);
// 比较两个字符
while (*s1 == *s2)
{
// 如果字符是'\0',结束,两个字符串相同
if (*s1 == '\0')
{
return 0;
}
s1++;
s2++;
}
// 两个字符不相同,返回差值
return *s1 - *s2;
}
int main()
{
int ret = Strcmp("abc", "abbc");
if (ret == 0)
printf("两个字符串相同\n");
else
printf("两个字符串不相同\n");
return 0;
}
比较两个字符串,不需要修改,形参加const修饰。