赞
踩
目录
本文重点介绍字符和字符串的库函数得使用和注意事项
深度解析库函数,并实现相关的库函数
函数原型
size_t strlen ( const char * str );
函数介绍
- strlen函数是用于计算字符串长度的
- 字符串以"\0"作为结束标志,此函数就是计算"\0"之前的字符个数
- 返回值为 size_t ,size_t原型为 typedef unsigned int size_t 是无符号整型的重命名,因为strlen函数是计算字符串长度,不可能为负数
- 参数用const char* 的指针接收,const为不可修改增加了函数的安全性
函数模拟实现
下述展示三种strlen函数的模拟实现,三种不同的思路
方法一:计算头尾指针的距离从而得到字符串的长度
- size_t my_strlen(const char* arr)
- {
- assert(arr != NULL);//断言函数,用于判断函数是否为空
- const char* ret = arr;//将字符数组首地址赋值给ret指针变量
- while (*ret)//当ret解引用不为\0时循环继续
- {
- ret++;//指针向后偏移
- }
- return ret - arr;//计算出指针的偏移量从而得到字符串的长度
- }
方法二 :利用一个标记,当数组内容不为\0时标记加一,从而得到字符串长度
- size_t my_strlen1(const char* arr)
- {
- assert(arr != NULL);
- int sum = 0;
- while (*arr)
- {
- arr++;
- sum++;
- }
- return sum;
- }
方法三: 递归实现,当数组内容不为\0时递归调用
- size_t my_strlen2(const char* arr)
- {
- assert(arr != NULL);
- if (*arr)
- return 1 + my_strlen2(arr+1);
- else
- return 0;
- }
char* strcpy(char * destination, const char * source );
函数介绍
- strcpy是实现字符串拷贝的函数
- destination是目标数组,source是用于拷贝的数组,即将source数组中的内容拷贝到destination中
- source字符串必须以 '\0' 结束。
- 会将source字符串中的 '\0' 拷贝到目标空间。
- destination空间必须足够大,以确保能存放source字符串。
- destination空间必须可变。
函数模拟实现
- char* my_strcpy(char* destination, const char* source)
- {
- assert(destination && source);
- char* ret = destination;//用一个字符指针记录des数组的起始地址
- while (*destination = *source)//当source内容为\0时循环结束
- {
- destination++;
- source++;
- }
- return ret;//返回des起始地址
- }
函数原型
char * strcat ( char * destination, const char * source );
函数介绍
- strcat是字符串追加函数
- 将source的内容追加到destination中
- source字符串必须以 '\0' 结束。
- destination空间必须有足够的大,能容纳下源字符串的内容。
- destination空间必须可修改。
函数模拟实现
- char* my_strcat(char* arr1, const char* arr2)
- {
- assert(arr1 && arr2);
- char* ret = arr1;//使用一个字符指针记录目标数组的首地址
- while (*arr1)//当目标函数内容为\0时,开始追加
- {
- arr1++;
- }
- while (*arr1 = *arr2)//开始追加字符串
- {
- arr1++;
- arr2++;
- }
- return ret;
- }
-
函数原型
int strcmp ( const char * str1, const char * str2 );
函数介绍
- strcmp函数时比较两个字符串的大小
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
函数模拟实现
- int my_strcmp(const char* arr1, const char* arr2)
- {
- assert(arr1 && arr2);
- while (*arr1 == *arr2)//通过ascll码值依次比较每个字符的大小
- {
- //当字符数组内容为\0时还没有比较出大小则表示两字符串相等
- if (*arr1 == '\0')
- return 0;//相等则返回0
- arr1++;
- arr2++;
- }
- return *arr1 - *arr2;//不相同等返回差值
- }
函数原型
char * strncat ( char * destination, const char * source, size_t num );
函数介绍
- 只是在原有的strcat的基础上增加了一个size_t num
- 表示只追加num个字符
函数模拟实现
- char* my_strncat(char* arr1, const char* arr2, size_t num)
- {
- assert(arr1 && arr2);
- char* ret = arr1;
- while (*arr1)
- {
- arr1++;
- }
- while (num--)//只追加num个字符
- {
- *arr1 = *arr2;
- arr1++;
- arr2++;
- }
- return ret;
- }
函数原型
char * strncpy ( char * destination, const char * source, size_t num );
函数介绍
- 在原有strncpy上增加了一个size_t num
- 表示只复制num个字符
函数模拟实现
- char* my_strncpy(char* arr1, const char* arr2, size_t num)
- {
- assert(arr1 && arr2);
- char* ret = arr1;
- while (num--)//控制复制的字符数
- {
- *arr1 = *arr2;
- arr1++;
- arr2++;
- }
- return ret;
- }
函数原型
int strncmp ( const char * str1, const char * str2, size_t num );
函数介绍
- 字符串比较函数,只比较num个字符
- 相较于strcmp只多了一个num
函数模拟实现
- int my_strncmp(const char* arr1, const char* arr2 ,size_t num)
- {
- assert(arr1 && arr2);
- while (num--)
- {
- if (*arr1 == *arr2)//字符相等时指针后移
- {
- arr1++;
- arr2++;
- }
- else
- {
- return *arr1 - *arr2;//只要有不相等时就返回两个字符的差
- }
- }
- return 0;//循环结束任然相等返回0
- }
函数原型
char * strstr ( const char *str1, const char * str2);
函数介绍
- strstr函数是在str1字符串中查找str2字符串是否为str1的子串
函数模拟实现
- char* my_strstr(const char* arr1, const char* arr2)
- {
- const char* s1 = arr1;//利用s1指针记录被查询数组的地址
- const char* s2 = arr2;//s2记录查询数组的地址
- const char* p = arr1;//p指针为被查询数组的偏移量
- while (*s1)
- {
- s1 = p;//从arr1第一个字符开始对比,不是字串就偏移一位
- s2 = arr2;
- while (*s1 == *s2)
- {
- s1++;
- s2++;
- }
- if (*s2 == '\0')//如果查询的数组为\0了那就证明arr2是arr1的子串
- {
- return p;
- }
- p++;
- }
- return NULL;
- }
函数原型
void * memcpy ( void * destination, const void * source, size_t num );
函数介绍
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 '\0' 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的
- 可以传任意参数,不局限于字符数组
- 这里的num是字节数,例如传整型数组,一个整型是4字节,10个整型num的值为40
函数模拟实现
- void* my_memcpy(void* arr1, const void* arr2,size_t num)
- {
- void* ret = arr1;
- assert(arr1 && arr2);
- while (num--)//num为字节数,这样就保证了能够一个字节一个字节的交换
- {
- *(char*)arr1 = *(char*)arr2;//将传过来的地址强制类型转换为字符型
- //一个字节一个字节的复制
- arr1 = (char*)arr1 + 1;//强转为char*型这样指针偏移量就为1
- arr2 = (char*)arr2 + 1;
- }
- return ret;
- }
函数原型
void * memmove ( void * destination, const void * source, size_t num );
函数介绍
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理
函数模拟实现
重叠情况一:当source指针在destination指针后面时,直接数字从前向后复制移动即可
重叠情况2:当source指针在destination指针前面时,直接数字从后向前复制移动即可
- void* my_memmove(void* arr1, const void* arr2, size_t num)
- {
- void* ret = arr1;
- assert(arr1 && arr2);
- if (arr1 <= arr2)//当目标函数指针在源函数左边时
- {
- while (num--)//从左向右复制
- {
- *(char*)arr1 = *(char*)arr2;
- arr1 = (char*)arr1 + 1;
- arr2 = (char*)arr2 + 1;
- }
- }
- else//目标函数在源函数右边时
- {
- while (num--)//从右向左依次复制
- {
- *((char*)arr1 + num) = *((char*)arr2 + num);
- }
- }
- return ret;
- }
-
万丈高楼平地起,没有基础就没有后面的高楼,即使这些库函数并没有什么很难的算法,但是也是需要我们去学习的
这里总结了10个常用库函数的使用以及使用的注意事项,同时也给出了这些库函数的模拟实现
这里肯定还是存在问题的,希望看到的诸君不吝赐教!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。