面试题:实现strcpy,strlen,strcmp,strcat,memcpy 之c-style字符串
哪里可以看到c库函数的源码?
gnu的c运行库glibc,但是源码的实现却是复杂的,需要考虑效率,stlen源码分析。
c-style字符串有个约定,以空字符结尾,即 '\0' 。
char ch[] = { '', '' };
char ch1[] = { "" };
char ch2[] = "";
ch存了2个字符,ch1与ch2一样,存了3个字符,即结尾含有 '\0' 。
char *c = "djawj\0p";
c不会存字符p,\0标识了结尾。
strlen(ch);//stlen沿着ch的内存一直扫描,直到遇到空字符,这就导致了错误
size_t strlen(const char *src)
{
assert(src!=NULL);//if (src == NULL) return ; 发生意外情况不返回,直接结束
const char *temp = src;
while (*temp++);
return (temp - src - );
}
char* strcpy(char* dst, const char* src)
{
assert((dst != NULL) && (src != NULL));//断言,如果条件为false,停止程序运行
char
while ((*dst++ = *src++) != '\0');
return dst;
}
char* strcpy(char* dst, const char* src)
{
assert((dst != NULL) && (src != NULL));
char *tmp = dst;
while ((*dst++ = *src++) != '\0');
return tmp; //返回目的地址,支持链式操作strlen(dst2,strlen(dst1,src))
}
下面代码的问题是返回值不是1,0,-1,有多种值
int strcmp(const char *src, const char *dst)
{
assert((src != NULL) && (dst != NULL));
int result = ; while (*src != '\0'&& *dst != '\0')
{
if (*src == *dst) {
src++; dst++; //相等就比较下一个字符
}
else if (*src > *dst) return result = ;//src>dst
else return result = -; //src<dst
}
return *src - *dst; //三种情况,"abc" "abc" "abcd"
}
修改为为用result存两个字符之差来进行循环检测
int strcmp(const char *src, const char *dst)
{
assert((src != NULL) && (dst != NULL));
int result = ; while (!(result = (*src - *dst)) && (*src != '\0'&& *dst != '\0'))
{ //修改为(!(result = (*src - *dst)) && ( *dst != '\0'))比较简洁
dst++;
src++; }
if (result < ) return -;
else if(result > ) return ;
else return ;
}
参考:http://www.cnblogs.com/xuhj001/archive/2013/11/17/3428088.html
C标准库strcmp实现
int Strcmp2(char *str1, char *str2)
{
assert(str1 != NULL&&str2 != NULL);
for (; *str1 == *str2; str1++, str2++)
if (*str1 == '\0') return ;
return *str1 < *str2 ? - : ;
}
自己写的麻烦的实现:
int Strcmp(char *s1, char *s2)
{
assert(s1 != NULL&& s2 != NULL);
int ret;
while (*s1 != '\0'&&*s2 != '\0')
{
//while (*s1++ == *s2++);
if (*s1 == *s2) { s1++; s2++; }
else {
ret = *s1 - *s2;
cout << ret << endl;
return ret < ? - : ;//不等<会返回1,大于则返回0,而不是-1 }
}
ret = *s1 - *s2;
if (ret < ) return -;
else return ret == ? : ;
}
char *strcat(char *s1,const char *s2) 可以用strcpy(s1+=strlen(s1),s2)实现
char *Strcat(char *s, const char *s2)// Strcat不会另申请空间,而是需要s1有足够的空间可以容纳原s1与s2的字符
{
char *p = s;
while (*s++) //s的递增不影响实参指针的值,为了返回字符串的首地址,用p存下来
{
cout <<<< *s << " ";
}
s--;
while (*s++ = *s2++);//‘\0'的ascii值为0,结果为假,即表达式的值会转换为真或假
return p;
}
由于strcat一次拼接返回的是首指针,频繁拼接需要再次从开始位置扫描,找字符串的尾部,这样效率就低了
面试题:实现strcpy,strlen,strcmp,strcat,memcpy 之c-style字符串的更多相关文章
- 面试题之strcpy/strlen/strcat/strcmp的实现
阿里的电面要我用C/C++实现一个字符串拷贝的函数,虽然以前写过 strcpy 的函数实现,但时间过去很久了,再加上有点紧张,突然就措手不及了.最后写是写出来了,但没考虑异常的情况,面试官好像很不满意 ...
- atoi、itoa,strcpy,strcmp,memcpy等实现
原文:http://www.cnblogs.com/lpshou/archive/2012/06/05/2536799.html 1.memcpy.memmove.memset源码 link:http ...
- 不使用库函数、自己编写的(strlen、strcpy、strcmp、strcat、memcmp、memcpy、memmove)
不使用库函数.自己编写的(strlen.strcpy.strcmp.strcat.memcmp.memcpy.memmove) //求字符串长度的函数 int my_strlen(const char ...
- strcpy/strlen/strcat/strcmp面试总结
<strcpy拷贝越界问题> 一. 程序一 #include<stdio.h> #include<string.h> void main() { char s[]= ...
- 实现字符串函数,strlen(),strcpy(),strcmp(),strcat()
实现字符串函数,strlen(),strcpy(),strcmp(),strcat() #include<stdio.h> #include<stdlib.h> int my_ ...
- 转:C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文
转自:C语言字符串操作函数 - strcpy.strcmp.strcat.反转.回文 C++常用库函数atoi,itoa,strcpy,strcmp的实现 作者:jcsu C语言字符串操作函数 1. ...
- strlen sizeof strcat strcpy区别
strlen(p): 能计算出p指向字符串的长度(以当前p的位置开始),不包含终止字符'\0': p可以声明为char* p或者char p[],这两种形式strlen均能正确计算. sizeof ...
- 笔试算法题(04):实现 string & memcpy & strcpy & strlen
出题:请实现给定String的类定义: 分析:注意检查标准类构造注意事项: 解题: #include <stdio.h> #include <string.h> /** * 检 ...
- strlen、strcpy和strcmp源码
1.不使用库函数实现strcpy #include <assert.h> char *strcpy(char *dst, const char *src) { assert((dst != ...
随机推荐
- 任务调度(02)Spring Schedule
任务调度(02)Spring Schedule [toc] Spring 3.0 提供两种任务调度方式:一是定时任务调度:二是异步任务调度.这两种任务调度方式都是基于 JUC 实现的,是一种非常轻量级 ...
- python学习第三十一天函数的嵌套及函数的作用域
python函数的嵌套是指在函数里面嵌套另外一个函数,可以嵌套更多,函数一旦套用了另外一个函数,他的作用域就已经形成,可以通过global关键词改变变量的作用域,下面详细说明函数的嵌套及函数的作用域 ...
- Go语言_包、变量和函数
包.变量和函数 学习 Go 程序的基本结构. Go 作者组编写,Go-zh 小组翻译. https://go-zh.org 包 每个 Go 程序都是由包构成的. 程序从 main 包开始运行. 本程序 ...
- Task总结
1.Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如: ◆ ThreadPool不支持线程的取消.完成.失败通知等交互性 ...
- JVM(4)之 使用MAT排查堆溢出
开发十年,就只剩下这套架构体系了! >>> 接下来讲解如何设置以及当发生堆溢出的时候怎么排查问题.先看一小段代码: 代码中使用了一个无限循环来为list添加对象,如果采用 ...
- smbcontrol - 向smbd或nmbd进程发送消息
总览smbcontrol [ -i ] smbcontrol [ 目标 ] [ 消息类型 ] [ 参数 ] 描述这个工具是是Samba组件的一部分. smbcontrol是个很小的程序,用它可以向系统 ...
- Swoole 简单学习(2)
Swoole 简单学习(2) swoole之tcp服务器: //创建tcp服务器new swoole_server(string $host,int $port,int $mode=SWOOLE_PR ...
- OpenStack虚拟机网络问题
当发现你的OpenStack虚拟机网络有问题,不妨先试一下这16个步骤 1. Security Group全部打开,这是最基本的,但是很多人容易忘记 其实遇到过无数这种场景了,Debug了半天网络 ...
- LeetCode(力扣)——Search in Rotated Sorted Array 搜索旋转排序数组 python实现
题目描述: python实现 Search in Rotated Sorted Array 搜索旋转排序数组 中文:假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1 ...
- 解决js ajax跨越请求 Access control allow origin 异常
// 解决跨越请求的问题 response.setHeader("Access-Control-Allow-Origin", "*");