c语言部分库函数,代码实现,以及细节理解
代码来自:
//得9 分
//为了实现链式操作,将目的地址返回,加2 分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '/0' );
return address;
} //得10 分,基本上所有的情况,都考虑到了
//如果有考虑到源目所指区域有重叠的情况,加1 分!
char * strcpy( char *strDest, const char *strSrc )
{
if(strDest == strSrc) { return strDest; }
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while((*strDest++ = *strSrc++)!='/0');
return address;
}
strncpy 是 C语言的函数之一,来自 C语言标准库,定义于 string.h,char *strncpy(char *destin, char *source, int maxlen),把src所指由NULL结束的字符串的前n个字节复制到dest所指的数组中。
char *strncpy(char *strDes, const char *strSrc, unsigned int count)
{
assert(strDes != NULL && strSrc != NULL);
char *address = strDes;
while (count-- && *strSrc != '/0')
*strDes++ = *strSrc++;
*strDes = '/0';
return address;
}
strcpy和memcpy都是标准C库函数,它们有下面特点:
strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容外,还会复制字符串的结束符。
strcpy的函数原型是:char* strcpy(char* dest, const char* src);
memcpy只提供一般的内存复制,即memcpy对于需要复制的内容没有限制,因此用途更广。
memcpy的函数原型是:void *memcpy(void *dest, const char* src, size_t count);
char *strcpy(char *dest, const char *src)
{
if((src == NULL) || (dest == NULL))
{
return NULL;
}
char *strdest = dest; // 保存目标字符串的首地址
while((*dest++ = *str) != '\0');
return strdest;
}
void *memcpy(void *memTo, const char *memFrom, size_t size)
{
if((memTo == NULL) || (memFrom == NULL))
{
return NULL;
} char *tempFrom = (char *)memFrom; //保存memFrom的首地址
char *tempTo = (char *)memTo; //保存memTo的首地址
while(size-- > 0)
{
*tempTo++ = *tempFrom++;
}
return memTo;
}
strcpy 和 memcpy主要有以下三方面的区别:
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符串、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符串的结束符"\0”才结束,所以容易溢出。memcpy则是根据第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其它类型的数据是用memcpy。
memcpy 和 memmove 都是C语言中的库函数,在库函数 string.h中,其原型相似,它们都是从src所指向的内存中复制count个字节到dest所指内存中。并返回dest的值。
当源内存区域 和 目标内存区域无交叉重叠时,两者的结果是一样的,但如果有交叉呢?
memcpy是从src的其实部分开始复制,所以虽然第一种情况下没有问题,但如果遇到第二种情况,则会发生错误,交叉部分的src内容就会被覆盖掉了。
而memmove则由于采用不同的复制机制,所以可以正确处理第二种情况。
void *memmove(void *dst,const void *src,int n)
{
char *dp = (char *)dst;
char *sp = (char *)src;
assert((src!=0)&&(dst!=0)&&(n>0));//not null
//非重叠
//dp < sp
//dp > (sp+n)
if(sp>dp||(sp+n)<dp)
{
while(n--)
*(dp++) = *(sp++);
*dp = '\0';
}
else if(sp<dp)//重叠 (此时条件 sp<dp<(sp+n))如果sp==dp则快速的返回
{//反向拷贝
sp += n;
dp += n;
*dp = '\0';
while(n--)
*(--dp) = *(--sp);
}
return dst;
}
在很多库函数上看到使用了assert()函数,assert函数的作用是计算表达式expression ,如果其值为假(即为0),那么它先向stderr打印一条错误信息,然后调用abort()来终止进程。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Calling abort()\n");
abort();
return 0; /* This is never reached */
}
c语言部分库函数,代码实现,以及细节理解的更多相关文章
- 通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制
通过调用C语言的库函数与在C代码中使用内联汇编两种方式来使用同一个系统调用来分析系统调用的工作机制 前言说明 本篇为网易云课堂Linux内核分析课程的第四周作业,我将通过调用C语言的库函数与在C代码中 ...
- C语言之库函数的模拟与使用
C语言之库函数的模拟与使用 在我们学习C语言的过程中,难免会遇到这样的一种情况: 我们通常实现一个功能的时候,费尽心血的写出来,却有着满满的错,这时却有人来告诉你说:这个功能可以用相应的库函数来实现. ...
- 【伯乐在线】最值得阅读学习的 10 个 C 语言开源项目代码
原文出处: 平凡之路的博客 欢迎分享原创到伯乐头条 伯乐在线注:『阅读优秀代码是提高开发人员修为的一种捷径』http://t.cn/S4RGEz .之前@伯乐头条 曾发过一条微博:『C 语言进阶有 ...
- C语言中库函数strstr的实现
在C语言中库函数strstr()函数表示在一个字符串str1中查找另一个字符串str2,如果查到则返回str2在str1中首次出现的位置,如果找不到则返回null. char* strstr(char ...
- VS2015提示:未安装Style的Visual Studio语言支持,代码编辑Intellisense将不可用。服务器控件的标记Intellisense可能不起作用
一.问题 最近在VS2015打开文件,提示未安装Style的Visual Studio语言支持,代码编辑Intellisense将不可用.服务器控件的标记Intellisense可能不起作用. Int ...
- 小C和小派的缠绵爱情——C语言调用Python代码
我妒忌你的开源,你眼红我的速度,不如我们就在一起吧! --------SJ2050 2019.4.9号更新:实现在未安装python环境的机子上运行调用了python程序的C语言代码! 文章目录 环境 ...
- 问题解决:补充安装c语言的库函数和系统调用man手册
问题解决:补充安装c语言的库函数和系统调用man手册 今日份麻麻~上课时大家的Ubuntu都可以通过man查到关于stat的库函数,但是我的Kali查出来是这样: 询问老师之后得知需要去安装相 ...
- 对于 C语言的扩展和JAVA的重载理解
哎,又被学长看成笨蛋了 ,先前学习java,自己真是什么都要忘了,弄得自己连java最重要的概念--重载,都不知道是啥,还厚着脸皮和学长说 是函数名字一样 ,但是就是函数里面的参数和参数类型不一 ...
- C++调用C语言的库函数
在项目中,使用C语言编写了一个socket后台程序tkcofferd,并且为方便客户端的使用,提供了动态库,其中包含socket接口. 现在的需求是使用qt做一个前端界面,用来展示tkcofferd的 ...
随机推荐
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- JAVA对象及属性的内存堆栈管理(通过小程序简单说明)
JAVA在执行过程中会划分4个内存区域(heap.stack.data segment.code segment)代码区(codesegment):java开始执行会把代码加载到code segmen ...
- DBoW2算法原理介绍
本篇介绍DBoW2算法原理介绍,下篇介绍DBoW2的应用. DBow2算法 DBow2是一种高效的回环检测算法,DBOW2算法的全称为Bags of binary words for fast pla ...
- 【Unity Shaders】ShadowGun系列之一——飞机坠毁的浓烟效果
写在前面 最近一直在思考下面的学习该怎么进行,当然自己有在一边做项目一边学OpenGL,偶尔翻翻论文之类的.但是,写shader是一个需要实战和动手经验的过程,而模仿是前期学习的必经之路.很多人都会问 ...
- C语言一个双向链表的实现
首先编写头文件,头文件里做相关的定义和声明,DList.h内容如下: #ifndef DList_H #define DList_H typedef int Item; typedef struct ...
- UNIX网络编程——UDP 的connect函数(改进版)
上一篇我们提到,除非套接字已连接,否则异步错误是不会返回到UDP套接字的.我们确实可以给UDP套接字调用connect,然而这样做的结果却与TCP连接大相径庭:没有三次握手.内核只是检查是否存在立即可 ...
- 【一天一道LeetCode】#191. Number of 1 Bits
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...
- vs 删除行尾空格
vs 删除行尾空格 vs2010:Enter: Ctrl+H Find what: :b*$ Replace with: [Empty] Look in: Current Document Find ...
- Qt中实现启动画面
纵所周之,当一个程序的启动比较耗时的时候,为了不让用户枯燥的等待或者是误以为程序运行异常了,所以我们都会在启动比较耗时的程序中加上启动界面 ,例如office软件等等. 在Qt中实现启动界面,主要就是 ...
- Unity UGUI基础之Image
UGUI的Image等价于NGUI的Sprite组件,用于显示图片. 一.Image组件: Source Image(图像源):纹理格式为Sprite(2D and UI)的图片资源(导入图片后选择T ...