strlen、strcmp、strcat、strlen、memmove

#include <cassert>
#include <iostream>
using namespace std;

/*
strlen 返回字符串不包含结束符\0的长度
*/
int mystrlen(const char *str)
{//非递归strlen
    assert(str);//必须不为空
    int len = 0;
    while (*str++)
        len++;
    return len;
}
int mystrlen1(const char *str)
{//递归 stelen
    if (*str == ‘\0‘) return 0;
    return mystrlen1(str + 1) + 1;
}
/*
strcmp,如果str1大,返回正数,小返回负数,相等返回0
ascii码共128种(0-127),所以可以转为unsigned char(范围-128到127)
且无符号两数相等情况下相减必为0,而有符号相减为0,两数的每一位不一定相等
*/
int mystrcmp(const char* str1,const char* str2)
{
    assert(str1 && str2);//允许一个为空
    int ret = 0;
    while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str1)//注意*str1放后面,前面肯定计算完毕
    {//结束符ascii码是0。相等进入while,不相等则ret存储差值,如果str1短,已经是负值,长则为正值
        str1++;
        str2++;
    }
    if (ret > 0) return 1;
    else if(ret < 0) return 0;
    else return 0;
}

/*
strcat 返回新dst。将字符串src包括结束符都复制到dst后,注意覆盖dst的\0
不考虑dst不够存放src的情况(会报错,但没法处理,因为dst为指针,不知其空间大小
*/
char *mystrcat(char *dst,const char *src)
{
    assert(dst && src);//允许一个为空
    char *tmp = dst;
    while (*tmp) tmp++;//指到dst的结束符处(比strcpy多了这一步
    while (*src)
        *tmp++ = *src++;
    *tmp = *src;//复制结束符
    return dst;
}

/*
strcpy 返回新dst,将字符串src包括结束符全部复制到dst开始处
不考虑dst不够存放src,容易溢出
*/
char *mystrcpy(char *dst, const char *src)
{
    assert(dst && src);
    char *tmp = dst;
    while (*src)
        *tmp++ = *src++;
    *tmp = *src;
    return dst;
}
/*
memmove size指定复制长度,如果源在前且与目标有重叠,则逆向复制
而memcpy都是正向复制
*/
void *mymemmove(void *dst, void *src, size_t size)
{
    if (dst == nullptr || src == nullptr) return nullptr;
    void *res = dst;
    char *pdst = (char *)dst;
    char *psrc = (char *)src;
    if (pdst >= psrc && pdst <= psrc + size)
    {
        for (int i = size - 1; i >= 0; i--)
            *(pdst + i) = *(psrc + i);//源在前,逆向复制
    }
    else
    {
        for (int i = 0; i < size; i++)
            *(pdst + i) = *(psrc + i);//源在后/不重叠,正向复制
    }
    return dst;
}

int main()
{
    char str[] = {‘1‘,‘2‘,‘3‘};
    const char *a = "12";

    //cout << mystrlen(a) << endl;
    //cout << mystrcmp("2222", "22") << endl;
    char dst[5] = "12";
    cout << mystrcat(dst, "34") << endl;
    cout << mystrcpy(dst, "34") << endl;
}

原文地址:https://www.cnblogs.com/beixiaobei/p/10914225.html

时间: 2024-08-05 22:58:08

strlen、strcmp、strcat、strlen、memmove的相关文章

常见函数strlen、strcmp、strstr原型实现

数组元素的结束符为'\0',串的结束符为NULL 一.strlen #include <iostream> using namespace std; long h_strlen(constchar*str){ assert(str!=NULL); const char *s = str; while (*s++); return (s - str - 1); } int main(int argc, const char * argv[]) { char s1[] = "hello&

转:C语言字符串操作函数 - strcpy、strcmp、strcat、反转、回文

转自:C语言字符串操作函数 - strcpy.strcmp.strcat.反转.回文 作者:jcsu C语言字符串操作函数 1. 字符串反转 - strRev2. 字符串复制 - strcpy3. 字符串转化为整数 - atoi4. 字符串求长 - strlen5. 字符串连接 - strcat6. 字符串比较 - strcmp7. 计算字符串中的元音字符个数8. 判断一个字符串是否是回文1. 写一个函数实现字符串反转 版本1 - while版 void strRev(char *s){    

程序猿之---C语言细节17(求time_t的最大值、strlen求的是长度、malloc分配字符内存细节、switch的中default细节)

主要内容:求time_t的最大值.strlen求的是长度.malloc分配字符内存细节.switch的中default细节 #include <stdio.h> #include <time.h> int main() {     /*****************************************************************         time_t最大值测试     ************************************

6、C_宏定义与预处理、函数与函数库

C语言预处理理论 由源码到可执行程序的过程 源码.c->(编译)->elf可执行程序 源码.c->(编译)->目标文件.o->(链接)->elf可执行程序 源码.c->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序 源码.c->(预处理)->预处理过的.i源文件->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序

下载-深入浅出Netty源码剖析、Netty实战高性能分布式RPC、NIO+Netty5各种RPC架构实战演练三部曲视频教程

下载-深入浅出Netty源码剖析.Netty实战高性能分布式RPC.NIO+Netty5各种RPC架构实战演练三部曲视频教程 第一部分:入浅出Netty源码剖析 第二部分:Netty实战高性能分布式RPC 第三部分:NIO+Netty5各种RPC架构实战演练

bos 第4 (区域excel批量导入、区域通用分页查询、分区的添加、分区多条件分页查询、分区导出excel)

BOS项目笔记 第4天 今天内容安排: 1.区域批量导入功能 jQuery OCUpload(一键上传插件).apache POI.pinyin4j 2.实现区域的分页查询 3.对分页代码重构 4.添加分区(combobox下拉框) 5.分区的组合条件分页查询 6.分区数据导出功能 1. 区域数据批量导入功能 1.1 一键上传插件使用 ajax不能做文件上传. 第一步:在jsp页面中引入插件的js文件 <script type="text/javascript" src=&quo

Python学习笔记 之 递归、二维数组顺时针旋转90&#176;、正则表达式

递归.二维数组顺时针旋转90°.正则表达式 1.   递归算法是一种直接或间接调用自身算法的过程. 特点: 递归就是在过程或函数里调用自身 明确的递归结束条件,即递归出口 简洁,但是不提倡 递归次数多容易造成栈溢出 要求: 每次调用递归规模上有所减小 前一次为后一次做准备 规模较小时必须直接给出解答而不再进行递归调用 例子:递归实现二分法 1 def searchMyData(mydate,a1): 2 mid = int(len(mydate)/2) 3 if mid >= 1: 4 if m

Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别

http://www.cnblogs.com/xrq730/p/4839245.html 前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出和内存泄露的区别 1.内存溢出 内存溢出指的是程序在申请内存的时候,没有足够大的空间可以分配了. 2.内存泄露 内存泄露指的是程序在申请内存之后,没有办法释放掉已经申请到内存,它始终占用着内存,即被分配的对象可

JavaScript - 简介、在HTMl中使用JavaScript、基本概念

1. JavaScript简介 JavaScript历史回顾 JavaScript是什么 JavaScript与ECMAScript的关系 JavaScript的不同版本 一言概之,略. 2. 在HTML中使用JavaScript 要把JavaScript放到网页中,就得涉及Web的核心语言 -- HTML.当初开发JavaScript的时候,要解决的一个重要问题就是让JavaScript与HTML页面共存,并且不影响页面在浏览器中的呈现效果.最终决定为Web增加统一的脚本支持. 2.1 <sc

Probabilistic Graphical Models:一、Introduction and Overview(1、Overview and Motivation)

一.PGM用来做什么 1.  医学诊断:从各种病症分析病人得了什么病,该用什么手段治疗 2.  图像分割:从一张百万像素级的图片中分析每个像素点对应的是什么东西 两个共同点:(1)有非常多不同的输入变量:(2)对于算法而言,结果都是不确定的 二.PGM各代表什么 1.  Models 2.  Probabilistic (1)概率:设计model即是为了分析一些不确定的东西(uncertainty) (2)Uncertainty的来源: (3)概率在模型表达上的优势 3.  Graphical