1、字符串
由双引号引起来的一串字符称为字符串。字符串的结束标志是一个\0的转义字符。在计算字符串长度的时候\0是结束标志,不算作字符串内容。
C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。
字符串常量适用于那些对它不做修改的字符串函数。
int main()
{
char str1[] = "hello world";
char str2[] = { 'h','e','l','l','o',' ','w','o','r','l','d' };
char* str3 = "hello world"; //将常量字符串hello world的首字符地址存放到
//指针变量str3中
return 0;
}
2、库函数介绍
使用库函数,需要包含#include对应的头文件。
2.1、strlen
形式:size_t strlen( const char *string );
作用:计算字符串的长度,直到遇到\0为止,返回值为无符号整型,参数为char *类型。
#include <stdio.h>
#include <string.h>
#include <assert.h>
//1、计数器方法
//size_t my_strlen(const char* str)
//{
// assert(str);
// unsigned int count = 0;
// while (*str != '\0')
// {
// count++;
// str++;
// }
// return count;
//}
//2、递归方法
//size_t my_strlen(const char* str)
//{
// if (*str != '\0')
// return 1 + my_strlen(str + 1);
// else
// return 0;
//}
//3、指针-指针
size_t my_strlen(const char* str)
{
const char* start = str;
const char* end = str;
while (*end != '\0')
{
end++;
}
return end - start;
}
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen(arr));
printf("%d\n", my_strlen(arr));
return 0;
}
2.2、strcpy
形式:char *strcpy( char *strDestination, const char *strSource );
作用:将源字符串(source)拷贝到目标空间(destination)。
注意点:(1)返回值是char*,目标空间首元素地址。
(2)源字符串必须有\0作为结束标志。
(3)需要将源字符串中的\0也拷贝到目标空间。
(4)目标空间必须可变。
(5)目标空间必须足够大,以确保能存放源字符串。
//1、没有实现将\0也copy到destination中,也没有返回值
//void my_strcpy(char* destination, const char* source)
//{
// assert(destination);
// assert(source);
//
// while (*source != '\0')
// {
// *destination = *source;
// destination++;
// source++;
// }
//}
//2、源字符串\0前的内容和\0分步copy
//char* my_strcpy(char* dest, const char* sour)
//{
// char* ret = dest;
// assert(dest && sour);
// while (*sour)
// {
// *dest++ = *sour++; //copy源字符串\0前的内容
// }
// *dest = *sour; //copy\0
// return ret;
//}
//3、优化
char* my_strcpy(char* dest, const char* sour)
{
char* ret = dest;
assert(dest && sour);
while (*dest++ = *sour++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
printf("%s\n", arr1);
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
2.3、strcat
形式: char *strcat( char *strDestination, const char *strSource );
作用:字符串追加,在目标空间后追加源字符串。
注意点:同strcpy。
注:字符串给自己追加会导致在第一次追加时覆盖\0,导致后续追加没有\0,陷入死循环。
char* my_strcat(char* dest, const char* sour)
{
assert(dest && sour);
char* ret = dest;
//1、找到目标空间的末尾,即\0的位置
//while (*dest++) //不能使用*dest++,因为dest会略过一个\0,指向第二个\0
while (*dest)
{
dest++;
}
//2、拷贝字符串
while (*dest++ = *sour++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "hello ";
my_strcat(arr1, "world");
printf("%s\n", arr1);
//字符串给自己追加会导致在第一次追加时覆盖\0,导致后续追加没有\0,陷入死循环
my_strcat(arr1, arr1);
printf("%s\n", arr1);
return 0;
}
2.4、strcmp
形式:int strcmp( const char *string1, const char *string2 );
作用:比较字符串。相等,返回0;string1>string2,返回>0的数;string1<string2,返回<0的数。
注:两个字符串比较,比较的是两个字符串的字符的ASCII码值,不是比较字符串的长度。
//int main()
//{
// char arr1[] = "hello";
// char arr2[] = "hello";
// //比较字符串是否相等
// //arr1和arr2都是数组名,都是数组首元素地址
// //比较时,是用地址在比较,两个地址不相等
// //这里是在比较两个地址,不是在比较两个字符串是否相等
// if (arr1 == arr2)
// printf("==\n");
// else
// printf("!=\n");
// return 0;
//}
//int my_strcmp(const char* dest, const char* sour)
//{
// assert(dest && sour);
// while (*dest == *sour)
// {
// if (*dest == '\0') //判断dest和sour是否相等
// return 0;
// dest++;
// sour++;
// }
// if (*dest > *sour) //判断dest是否大于sour
// {
// return 1;
// }
// else //判断dest是否小于sour
// {
// return -1;
// }
//}
int my_strcmp(const char* dest, const char* sour)
{
assert(dest && sour);
while (*dest == *sour) //==,判断,不是赋值,因此结果为真就会进入循环
{
if (*dest == '\0')
return 0;
dest++;
sour++;
}
return (*dest - *sour);
}
int main()
{
char arr1[] = "abc";
char arr2[] = "abcdef";
int ret = my_strcmp(arr1, arr2);
if (ret>0)
printf(">\n");
else if (ret < 0)
printf("<\n");
else
printf("==\n");
return 0;
}