面试题之strcpy/strlen/strcat/strcmp的实现
阿里的电面要我用C/C++实现一个字符串拷贝的函数,虽然以前写过 strcpy 的函数实现,但时间过去很久了,再加上有点紧张,突然就措手不及了。最后写是写出来了,但没考虑异常的情况,面试官好像很不满意。(T_T),写篇文章记录一下,以免日后重蹈覆辙。
一、字符串拷贝strcpy
函数strcpy的原型是char*,des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串。
strcpy(char* des , const char* src)
#include <assert.h>
#include <stdio.h> char* strcpy(char* des, const char* src)
{
assert((des!=NULL) && (src!=NULL));
char *address = des;
while((*des++ = *src++) != '\0')
;
return address;
}
要知道 strcpy 会拷贝'\0',还有要注意:
源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型。
要判断源指针和目的指针为空的情况,思维要严谨,这里使用
assert(见文末)。要用一个临时变量保存目的串的首地址,最后返回这个首地址。
函数返回 char* 的目的是为了支持链式表达式,即strcpy可以作为其他函数的实参。
二、字符串长度strlen
函数strlen的原型是size_t,其中 size_t 就是 unsigned int。
strlen(const char *s)
#include <assert.h>
#include <stdio.h> int strlen(const char* str)
{
assert(str != NULL);
int len = 0;
while((*str++) != '\0')
++len;
return len;
}
strlen 与 sizeof 的区别:
sizeof是运算符,strlen是库函数。
sizeof可以用类型、变量做参数,而strlen只能用 char* 变量做参数,且必须以
\0结尾。sizeof是在编译的时候计算类型或变量所占内存的大小,而strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度。
数组做sizeof的参数不退化,传递给strlen就退化为指针了。
三、字符串连接strcat
函数strcat的原型是char*,des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串。
strcat(char* des, char* src)
#include <assert.h>
#include <stdio.h> char* strcat(char* des, const char* src) // const表明为输入参数
{
assert((des!=NULL) && (src!=NULL));
char* address = des;
while(*des != '\0') // 移动到字符串末尾
++des;
while(*des++ = *src++)
;
return address;
}
四、字符串比较strcmp
函数strcmp的原型是int。
strcmp(const char *s1,const char *s2)
- 若s1==s2,返回零;
- 若s1>s2,返回正数;
- 若s1<s2,返回负数。
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇\0为止。
#include <assert.h>
#include <stdio.h> int strcmp(const char *s1,const char *s2)
{
assert((s1!=NULL) && (s2!=NULL));
while(*s1 == *s2)
{
if(*s1 == '\0')
return 0; ++s1;
++s2;
}
return *s1 - *s2;
}
附:assert()断言
assert是宏,而不是函数。它的原型定义在头文件 assert.h 中:
void assert( int expression );
宏 assert 经常用于在函数开始处检验传入参数的合法性,可以将其看作是异常处理的一种高级形式。assert 的作用是先计算表达式expression,然后判断:
如果表达式值为假,那么它先向stderr打印错误信息,然后通过调用 abort 来终止程序运行。
如果表达式值为真,继续运行后面的程序。
注意:assert只在 DEBUG 下生效,在调试结束后,可以通过在#include语句之前插入
<assert.h>#define NDEBUG来禁用assert调用。
个人站点:http://songlee24.github.com
面试题之strcpy/strlen/strcat/strcmp的实现的更多相关文章
- strcpy/strlen/strcat/strcmp面试总结
<strcpy拷贝越界问题> 一. 程序一 #include<stdio.h> #include<string.h> void main() { char s[]= ...
- strcpy,strlen, strcat, strcmp函数,strlen函数和sizeof的区别
//计算字符串实际长度 //strlen()函数:当遇到'\0'时,计算结束,'\0'不计入长度之内,如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0 ...
- 自定义方法实现strcpy,strlen, strcat, strcmp函数,了解及实现原理
位置计算字符串长度 //strlen()函数,当遇到'\0'时,计算结束,'\0'不计入长度之内 //字符串的拷贝 //strcpy(字符串1,字符串2); //把字符串2 ...
- strcpy/strlen/strcat/strcmp的实现
一.字符串拷贝strcpy 函数strcpy的原型是char* strcpy(char* des , const char* src),des 和 src 所指内存区域不可以重叠且 des 必须有足够 ...
- strlen strcat strcpy strcmp 自己实现
strlen strcat strcpy strcmp 自己实现 strlen include <stdio.h> #include <string.h> #include & ...
- 写出完整版的strcpy函数及其他如:strcat,strcmp,strstr的函数实现
(---牛客网中刷题---)写出完整版的strcpy函数 如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案: 2分 1 2 3 4 void strcpy( char *st ...
- strcpy(),strcat()的用法
strcpy(): 定义一个字符串char a[20],和一个字符串c[]="i am a teacher!"; 把c复制到a中就可以这样用:strcpy(a,c); 这个函数包含 ...
- 库函数strcpy/strlen的工作方式
库函数strcpy/strlen的工作方式 分类: C/C++ 2011-07-03 23:49 1032人阅读 评论 ...
- c/c++面试题(3)strcat/strcmp/strlen/strcpy的实现
1.编写一个函数实现strlen以及strcpy函数. strcpy函数. 后面的字符串拷贝到一个字符数组中,要求拷贝好的字符串在字符数组的首 地址,并且只拷贝到'\0'的位置.原型是 char* m ...
随机推荐
- Swift 中的值类型与引用类型
顶级修饰 次级修饰 赋值类型 存储类型 值类型 值类型 深拷贝 栈 值类型 引用类型 浅拷贝 堆 引用类型 值类型 浅拷贝 堆 引用类型 引用类型 浅拷贝 堆 复合引用类型会改变内部值类型的存储行 ...
- MFC_简易文件管理器
练习_简易文件管理器 Edit1编辑框绑定变量,初始化内容 m_EditCtrl = L"D:\"; 添加List控件,属性设置report,OnInitDialog()函数里添加 ...
- lua 之 三木运算符
在c语言中我三目运算符这么写: a?b:c 例如: max = a>b?a:b; 在lua中我们这么写 max = a>b and a or b 运行如下:
- CAD控件使用教程 自定义实体的实现
自定义实体的实现 1 . 自定义实体... 3 1.1 说明... 3 1.2 类的类型信息... 3 1.3 worldDraw.. 4 1.4 ...
- maven release插件将一版本发布到仓库中时Return code is: 401, ReasonPhrase:Unauthorized
需要在maven的setting.xml中配置servers.server节点,其值为nexus的对应的repository的id以及用户名及密码 <servers> <server ...
- hibernate 5.x版本中中schemaexport的使用
public static void main(String[] args) { /*//创建hibernate配置对象 Configuration cfg = new Configuration() ...
- shell learning note
shell learning note MAIN="/usr/local/" # 变量大写 STATUS="$MAIN/status" # 美元符加字符串是 ...
- jq进度条
<!doctype html><html><head><meta charset="utf-8"><title>JQue ...
- spring的IOC的简单理解
之前看了一下源码,看的挺吃力,只能是慢慢看了. 简单说一下springIOC的我的理解,IOC也叫控制反转,可以有效的减低各个组件之间的耦合度 想象一下,如果不用IOC,那么系统里面会有大量的new ...
- js 小练习
js 学习之路代码记录 js 加载时间线 1.创建Document对象,开始解析web页面.解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中.这个阶段document.r ...