求字符串的长度
一个带’\0’的字符数组才叫字符串
strlen函数
size_t strlen(const char str);*
strlen函数返回的是不包含**’\0’**的字符个数;
参数指向的字符串必须以’\0’结束;
函数的返回值为size_t,是无符号的(unsigned int)
函数的模拟实现:
方法1:计数器方式
size_t my_strlen(const char* str){
int count = 0;
while (*str != '\0'){
str++;
count++;
}
return count;
}
方法2:不创建临时变量的计数器
size_t my_strlen(const char* str){
if (*str == '\0'){
return 0;
}else{
return 1 + my_strlen(str + 1);
}
}
方法3:指针-指针
size_t my_strlen(const char* str){
char* start = str;
while (*str != '\0'){
str++;
}
return str - start;
}
结果:6
长度不受限制的字符串函数
strcpy函数
字符串拷贝
char strcpy(char dest,const char* src);**
注意:目标空间必须足够大,确保能存放源字符串
strcpy函数实现
char* strcpy(char* dest, const char* src){
char* ret = dest;
while (*src){
*dest = *src;
dest++;
src++;
}
return ret;
}
int main(){
char* str1 = "hello";
char str2[20]= { 0 };
strcpy(str2, str1);
printf("%s", str2);
system("pause");
return 0;
}
结果:
strcat函数
字符串拼接
char strcat(char dest,const char* src);**
注意:目标空间必须足够大
函数的实现
char* my_strcat(char* dest, const char* src){
assert(dest);
assert(src);
char* ret = dest;
while (*dest){
dest++;
}
while(*src)
{
*dest++ = *src++;
}
return ret;
}
int main(){
char str1[20] = "hello ";
char str2[] = "world";
my_strcat(str1, str2);
printf("%s", str1);
system("pause");
return 0;
}
结果:
strcmp
字符串比较
比较规则:字典序
int my_strcmp(const char* str1, const char* str2){
assert(s1);
assert(s2);
while (*str1 == *str2){
if (*str1 == '\0'){
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2){
return 1;
}
else{
return -1;
}
}
int main(){
char* str1 = "abcdef";
char* str2 = "aswerf";
int ret = my_strcmp(str1, str2);
if (ret < 0){
printf("小于\n");
}
else if (ret == 0){
printf("等于\n");
}
else if(ret>0)
{
printf("大于\n");
}
system("pause");
return 0;
}
结果:小于
字符串查找
strstr
查找字符串中的子字符串
char* my_strstr(const char* str1, const char* str2){
const char* s1 = str1;
const char* s2 = str2;
const char* cp = str1;
if (*str2 == '\0'){
return (char*)str1;
}
while (*cp){
s1 = cp;
s2 = str2;
while (*s1 == *s2){
s1++;
s2++;
}if (*s2 == '\0'){
return (char*)cp;
}
cp++;
}
return NULL;
}
int main(){
char str1[] = "abcdefabc";
char str2[] = "cdef";
char* ret =my_strstr(str1, str2);
printf("%s\n", ret);
system("pause");
return 0;
}
结果:
内存操作函数
memcpy
源数据与目标数据不能有任何重叠部分,否则复制的结果是未定义的
void* my_memcpy(void* dest, void* src, size_t count){
void* ret = dest;
assert(dest);
assert(src);
while (count--){
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main(){
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, sizeof(arr1));
for (int i = 0; i < 10; i++){
printf("%d ", arr2[i]);
}
system("pause");
return 0;
}
结果:
memmove
void memmove(void dest, void* src, size_t count)**
,用法和memcpy一样,但能够处理内存块重叠的问题
为了方面函数实现:
如果dest<src;将从前向后拷贝
如果dest>src,将从后向前拷贝
void* my_memmove(void* dest, const void* src, size_t count){
assert(dest);
assert(src);
if (dest < src){
while (count--){
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else{
while (count--){
*((char*)dest + count) = *((char*)src + count);
}
}
}
int main(){
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
my_memmove(arr1 + 2, arr1, 20);
for (int i = 0; i < 10; i++){
printf("%d ", arr1[i]);
}
system("pause");
return 0;
}
结果: