#include <stdio.h>
//strlen函数
// 字符串以'\0'作为结束标志,strlen函数返回的是在字符串'\0'前面出现的字符个数(不包含'\0')
// 参数指向的字符串必须要以'\0'结束
// 注意函数的返回值为size_t是无符号的(易错)
//求字符长度:1.计时器2.递归3.指针-指针
#include <assert.h>
//int my_strlen(int* arr)
//{
// int count = 0;
// assert(arr != NULL);
// /*while (*arr != '\0')
// {
// count++;
// arr++;
// }
// return count;*/
// //递归写法:
// while (*arr != '\0')
// {
// return 1 + my_strlen(arr + 1);
// }
//}
//int main()
//{
// //int len = my_strlen("abcdef");
// //printf("%d\n", len);
// //3-6=-3//无符号数是很大一个数
// //指针-指针的方法
// if (strlen("abc") - strlen("abcdef") > 0)
// {
// //strlen返回类型是unsigned int
// printf("hehe\n");//hehe
// }
// else
// {
// printf("haha\n");
// }
// return 0;
//}
//strcpy函数
// 1.源字符串必须以'\0'结束 char dset={'a','c'}://err
// 2.会将源字符串中'\0'拷贝到目标空间
// 3.目标空间必须足够大,以确保能存放源字符串 char arr1="d",char arr2= "edg" 这是错误的
// 4.目标空间必须可变
//char* my_strcpy(char* dest, const char* src)
//{
// assert(dest != NULL);
// assert(src != NULL);
// char* ret = dest;
// //while (*src != '\0')
// //{
// // *dest = *src;
// // dest++;
// // src++;
// //}
// //*dest = *src;//将'\0放进dest
// //写法二
// //拷贝src指向的字符串到dest指向的空间,包含'\0'
// while (*dest++ = *src++)
// {
// ;
// }
// //返回目的地空间的起始位置
// return ret;
//}
//int main()
//{
// char arr1 = "abcdefghi";
// char arr2 = "bit";
// my_strcpy(arr1, arr2);
// printf("%s\n", arr1);
// return 0;
//}
//strcat-追加函数
//源字符串必须以'\0'结束
//目标空间必须有足够的大,能容纳下源字符串的内容
//目标空间必须可修改
//char* my_strcat(char* dest, const char* src)
//{
// char ret = dest;
// assert(dest && src);
// //assert(dest);
// //assert(src);
// //1.找到目的找到字符串的'\0'
// while (*dest != '\0')
// {
// dest++;
// }
// //2.追加
// while (*dest++ = *src++)
// {
// ;
// }
// return ret;
//}
//int main()
//{
// char arr1[30] = "hello";
// char arr2[] = "world";
// my_strcat(arr1, arr2);
// printf("%s\n", arr1);
// return 0;
//}
//strcmp函数-判断字符串是否相等
// //vs
//第一个字符串大于第二个字符串,则返回大于0的数字
//第一个字符串等于第二个字符串,则返回0
//第一个字符串小于第二个字符串,则返回小于0的数字
//linux:
//> >0
//== 0
//< <0
//int main()
//{
// char* str1 = "acb";
// char* str2 = "fed";
// //int ret = strcmp(str1, str2);
// //printf("%d\n", ret);
// if (strcmp(str1, str2) > 0)
// {
// printf("str1>str2\n");
// }
// else if (strcmp(str1, str2) == 0)
// {
// printf("str1==str2\n");
// }
// else
// {
// printf("str1<str2\n");
// }
// return 0;
//}
//自己实现strcmp函数
//int my_strcmp(const char* p1, const char* p2)
//{
// assert(p1 && p2);
// while (*p1 == *p2)
// {
// if (*p1 == '\0')
// {
// return 0;//等于
// }
// p1++;
// p2++;
// }
// if (*p1 < *p2)
// return -1;//小于
// else
// return 1;//大于
//}
//int main()
//{
// char* str1 = "abcdef";
// char* str2 = "abqwe";
// int ret = my_strcmp(str1, str2);
// printf("%d\n", ret);
// return 0;
//}
//strncpy函数
//拷贝num个字符从源字符串到目标空间
//如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后面追加0,直到num个
//char* my_strncpy(char* dest, const char* src, int count)
//{
// assert(dest && src);
// char* ret = dest;
// while (count && (*dest++ = *src++))
// {
// count--;
// }
// if (count)//把剩下的填充\0
// {
// while(--count)
// {
// *dest++ = '\0';
// }
// }
// return(ret);
//}
//int main()
//{
// char arr1[10] = "abcnd";
// char arr2[] = "sjh";
// //strncpy(arr1, arr2, 3);//3是拷贝几个元素
// //strncpy的模拟实现
// char* ret = my_strncpy(arr1, arr2, 6);
// printf("%s\n", ret);
// return 0;
//}
//strncat函数--追加
// char* my_strncat(char* dest, char* src,int count)
//{
// assert(dest && src != NULL);
// char* ret = dest;
// //找到\0
// while (*dest++)
// {
// dest--;
// }
// //找到\0,追加
// while (count--)
// {
// if (!(*dest++ = *src++))
// {
// return ret;
// }
// }
//}
//int main()
//{
// char arr1[30] = "hello";
// char arr2[] = "world";
// //strncat(arr1, arr2, 5);//剩下的不会用\0补充,多少个num最后用\0结尾
//
// my_strncat(arr1, arr2, 3);
// printf("%s\n", arr1);
// return 0;
//}
//函数strncmp--比较两个字符串的大小,大于,返回大于0的数,小于,返回小于0的数,等于,返回0
//int main()
//{
// const char* p1 = "abcdef";
// char* p2 = "abcfrg";
// int ret = strncmp(p1, p2, 3);//3是比较多少个元素
// printf("%d\n", ret);
// return 0;
//}
//strstr--查找字符串
//char* my_strstr(const char* p1 ,const char* p2)
//{
// //abbbcdef
// //bbc
// assert(p1 && p2);
// char* s1 = p1;
// char* s2 = p2;
// char* cur = p1;
// if (*p2 == '\0')
// {
// return p1;
// }
// while (*cur)
// {
// s1 = cur;
// s2 = p2;
// while ((*s1 != '\0') && (*s2 != '\0') && (*s1 == *s2))
// {
// s1++;
// s2++;
// }
// if (*s2 == '\0')
// {
// return cur;//找到字串
// }
// if (*s1 == '\0')
// {
// return NULL;
// }
// cur++;
// }
// return NULL;//找不到字串
//}
//int main()
//{
// char* p1 = "abdfghibdf";
// char* p2 = "bdf";
// //char* ret = strstr(p1, p2);
// //自己实现
// char* ret = my_strstr(p1, p2);
// if (ret == NULL)
// {
// printf("子串不存在\n");
// }
// else
// {
// printf("%s\n", ret);//如果出现两处地方,只打印第一次出现
// }
// return 0;
//}
//strtok函数,切割函数
//char*strtok(char*str,const char*sep)
//sep参数是个字符串,定义了用作分隔符发字符集合
//第一个参数指定一个字符串,它包含了0个或者多个由sep字符中一个或者多个分隔符的标记
//strtok函数找到str中下一个标志,并将其用\0结尾,返回一个指向足够标记的指针(注{strtok函数会改变被操作的字符串,所以一般使用strtok函数先临时拷贝一份切割--289-290)
//strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符中的位置
//strtok函数的第一个参数为null,函数将在同一个字符串中被保存的位置开始,查找下一个标记
//如果字符串中不存在更多的标记,则返回null指针
//int main()
//{
// char arr[] = "apw@bitedu.tech";
// char* p = "@.";
// //保存原始数据
// char* buff[2021] = { 0 };
//
// strcpy(buff, arr);
// //切割buff中的字符串
// char* ret = NULL;
// for (ret = strtok(arr, p); ret != '\0'; ret = strtok(NULL, p))
// {
// printf("%s\n", ret);//apw bitedu tech
// }
// return 0;
//}
//strerror--错误信息函数--将错误码翻译成相应的错误信息
//字符分类函数--isupper--将字符转变成大写字母 tolower--将字符转变成小写字母
#include<ctype.h>
//int main()
//{
// char arr[] = "I AM A Student";
// int i = 0;
// while (arr[i])
// {
// if (isupper(arr[i]))//如果是大写字母
// {
// arr[i] = tolower(arr[i]);
// }
// i++;
// }
// printf("%s\n", arr);
// return 0;
//}
//memcpy--拷贝函数
#include <assert.h>
//struct S
//{
// char name[20];
// int age;
//};
//void* my_memcpy(void* dest, const void* src, size_t num)
//{
// void* ret = dest;
// assert(dest != '\0');
// assert(src != '\0');
// while (num--)
// {
// //一个一个字节访问
// *(char*)dest = *(char*)src;
// ++(char*)dest;
// ++(char*)src;
// }
// return ret;
//}
//int main()
//{
// //int arr1[] = { 1,2,3,4,5 };
// //int arr2[5] = { 0 };
// //memcpy(arr2, arr1, sizeof(arr1));
// struct S arr3[] = { {"张三",20},{"李四",30} };
// struct S arr4[3] = { 0 };
// return 0;
//}
//memmove--处理重叠拷贝--my_memcpy拷贝不了的
//c语言标准:
//memcpy:只要处理 不重叠的内存拷贝就可以
//memmove:处理重叠内存的拷贝
//void* my_memmove(void* dest, const void* src, size_t num)
//{
// void* ret = dest;
// assert(dest != NULL);
// assert(src != NULL);
// if (dest < src)
// {
// //前->后
// while (num--)
// {
// *(char*)dest = *(char*)src;
// ++(char*)dest;
// ++(char*)src;
// }
// }
// else
// {
// //后->前
// while (num--)
// {
// *((char*)dest + num) = *((char*)src+num);
// }
// }
// return ret;
//}
//int main()
//{
// int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
// int i = 0;
// //memmove(arr + 2, arr, 20);
// my_memmove(arr + 2, arr, 20);
// for (i = 0; i < 10; i++)
// {
// printf("%d ", arr[i]);
// }
// return 0;
//}
//memcmp函数
//>0 return>0 <0 return <0 =0 return 0
//int main()
//{
// int arr1[] = { 1,2,3,4,5 };
// int arr2[] = { 1,2,5,4,3 };
// //8是字节数,相当于两个整形
// int ret = memcmp(arr1, arr2, 9);
// printf("%d\n", ret);
// return 0;
//}
//memset--内存设置
//int main()
//{
// int arr[10] = { 0 };
// //40是10个整形的字节数
// memset(arr, 1, 40);//arr{1,1,1,1,1,1,1,1,1,1}
// return 0;
//}