目录

一、strlen函数

二、C语言模拟实现strlen函数的3种方法

三、str系列函数

strcpy函数

strcat函数

strcat函数模拟实现

strcmp模拟实现

一、strlen函数

#include <stdio.h>
int main()
{const char*str1 = "abcdef";const char*str2 = "bbb";if(strlen(str2)-strlen(str1)>0){printf("str2>str1\n");} else{printf("srt1>str2\n");}return 0;
}

运行结果为str2>str1

原因:strlen返回值是无符号整形,3-6=-3是一个负数,在内存中以补码的形式表示,被当做一个无符号整形,所以补码就是原码,这是一个很大的大于0的数。

二、C语言模拟实现strlen函数的3种方法

1.计数器

//1.计数器
#include <stdio.h>
#include <assert.h>
int my_strlen(char* p)
{assert(*p != NULL);//为了程序的健壮性int count = 0;while (*p != '\0'){count++;p++;}return count;
}int main()
{char arr[] = "abcdef";int num = my_strlen(arr);printf("%d ", num);return 0;
}

2.递归    不能创建临时变量的写法

#include <stdio.h>
int my_strlen(char* p)
{if (*p == '\0'){return 0;}elsereturn 1 + my_strlen(p + 1);
}int main()
{char arr[] = "abcdef";int num = my_strlen(arr);printf("%d ", num);return 0;
}

3.指针-指针

//指针-指针的方式
int my_strlen(char *s)
{char *p = s;//s表示指针变量while(*p != ‘\0’ )p++;return p-s;
}

使用的要求必须是2个指针指向同一块地址空间。

三、str系列函数

strcpy函数

char* strcpy(char * destination, const char * source );

tips:

源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。 学会模拟实现。

int main()
{
    char arr[20] = { 0 };
    arr = "hello"; //err,因为arr是数组名,是地址,表示的是常量,是数字,你怎么能把
    //"hello"赋值给它呢
      printf("%s\n", arr);
}

所以要这么写

int main()
{char arr[20] = { 0 };char* p = "hello";strcpy(arr, p);//string copyprintf("%s\n", arr);
}

还可以这么写

int main()
{char arr[20] = { 0 };char* p = "hello";strcpy(arr, p);//string copyprintf("%s\n", arr);
}

这里注意,arr[20]满足了目标空间足够大,能够放得下,源字符串必须以 '\0' 结束,而且数组目标空间可变,要是这里换成char *q="$$$$$$$$$$$$",则根本strcpy复制不了,因为目标空间不可变。

在举一个例子:

char *p="ASDFG",这里p的内容能改么?

答:不能,p指向的是常量字符串,你想让他改,不可能的,这辈子都不可能的。

strcat函数

char * strcat ( char * destination, const char * source );

源字符串必须以 '\0' 结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

字符串不能自己给自己追加

理由:[a s d f \0]

[a s d f a s d f ....]

见到\0就追加原字符串内容,最后的结果是源字符串\0丢失了。一个字符数组只有一个空间,要在一个空间进行自己的字符串追加,找到’\0’后,将’a’赋给’\0’,此字符串就没有了字符串结束的标志,代码进入死循环。

strcat函数模拟实现

char *my_strcat(char *dest, const char*src)
{char *ret = dest;assert(dest != NULL);assert(src != NULL);while(*dest){dest++;}while((*dest++ = *src++)){;}return ret;
}

char *ret = dest;这句话能去掉吗

不能,去掉后最后结果返不回来,需要有一个指针指向dest

strcmp模拟实现

int my_strcmp(const char* src, const char* dst)
{int ret = 0;assert(src != NULL);assert(dst != NULL);while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)++src, ++dst;if (ret < 0)ret = -1;else if (ret > 0)ret = 1;return(ret);
}

什么时候能够跳出循环?

当dst所指向的内容=\0或者src和dst目标内容dst不等于0(即不相等)时。

1.BF算法,暴力(Brute Force)算法

char* my_strstr(char* str1, char* str2){assert(str1 && str2);int slen = strlen(str1);int sublen = strlen(str2);int i = 0;int j = 0;int count = 0;while(i < slen){while(str1[i] == str2[j] &&  j < sublen){++i;++j;}if(j >= sublen){return str1 + i - j;}++count;i = count;j = 0;}        return NULL;}

2.KMP算法

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>void get_next(int* next, char* sub){int len = strlen(sub);next[0] = -1;next[1] = 0;int i = 2;int k = 0;while(i < len){if(k == -1 || sub[i-1] == sub[k]){next[i] = ++k;++i;}else{k = next[k];}}}char* my_strstr(char *str1, char * str2){assert(str1 && str2);int slen = strlen(str1);int sublen = strlen(str2);int* next = (int*)malloc(sizeof(int)*sublen);assert(next);get_next(next,str2);int i = 0;int j = 0;while(i < slen && j < sublen){if(j == -1 || str1[i] == str2[j]){++i;++j;}else{j = next[j];}}if(i >= sublen){return str1 + i - j;}else{return NULL;}}

C语言strlen等系列函数详细总结相关推荐

  1. c语言怎么产生随机数函数,详细介绍一下C语言里面的随机数产生函数random怎么用...

    匿名用户 1级 2013-11-24 回答 rand()函数可以用来产生随机数e799bee5baa6e79fa5e98193e4b893e5b19e31333332643334,但是这不是真真意义上 ...

  2. C语言详解系列——函数的认识(4)函数的声明与定义,简单练习题

    文章目录 函数的声明与定义 函数的声明 函数的定义 简单的练习题 写一个函数可以判断一个数是不是素数 写一个函数实现二分查找 写一个函数,每调用一次这个函数,就会将 num 的值增加1. 函数的声明与 ...

  3. C语言scanf函数详细解释,[转载]C语言printf和scanf函数详细用法

    Printf和Scan函数的使用方法 一 printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出 信息.在编写程序时经常会用到此函数.printf()函数的调用格式为: prin ...

  4. C语言详解系列——函数的认识(5)函数递归与迭代

    文章目录 函数递归 函数的迭代 函数递归 什么是函数递归?函数自己调用自己的编程技巧我们称为递归,函数递归通常会把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量 ...

  5. openssl之EVP系列之5---EVP_Encrypt系列函数具体解释(二)

    openssl之EVP系列之5---EVP_Encrypt系列函数详细解释(二)     ---依据openssl doc/crypto/EVP_EncryptInit.pod和doc/ssleay. ...

  6. 【C 语言】字符串操作 ( strlen 与 sizeof 函数 | 计算 字符串长度 与 内存块大小 )

    文章目录 一.strlen 与 sizeof 函数 二.计算 字符串长度 与 内存块大小 一.strlen 与 sizeof 函数 strlen() 函数的作用是获取字符串大小 , 其原理是 从 内存 ...

  7. Python语言学习:复杂函数(yield/@property)使用方法、案例应用之详细攻略

    Python语言学习:复杂函数(yield/)使用方法.案例应用之详细攻略 目录 yield 1.生成斐波那契數列 @property 其他函数 yield 带有 yield 的函数在 Python ...

  8. Str库系列函数合集(strlen、strcpy、strcmp、strcat、strchr等)

    关于Str函数,网上五花八门,使初学者很容易迷失方向,笔者在这里做一个常用函数的总结.希望对读者起到些许帮助. 后续会持续更新特殊函数~ 想了解mem系列函数的,请猛戳这里→mem系列函数 代码 // ...

  9. C语言 strlen 函数 - C语言零基础入门教程

    目录 一.strlen 函数简介 二.strlen 函数实战 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.strlen 函数简介 ...

最新文章

  1. linux 进程内存解析
  2. 微软创立全新人工智能实验室,与DeepMind、OpenAI同台竞技
  3. c语言编程 输入螺旋数组,C语言 经典题目螺旋矩阵 实例详解
  4. flume案例-网络数据采集-启动flume
  5. Unity3d通用工具类之生成文件的MD5
  6. AOP(基于注解对AspectJ操作)
  7. IE8 beta2现已正式发布!
  8. 浙江电信网上营业厅的一个BUG(有更新)
  9. python画k线图_Python绘制K线图
  10. AutoFac IoC DI 依赖注入
  11. windows32位安装MongoDB
  12. 【路径规划】基于matlab遗传结合模拟退火算法仓库拣货小车最优路径规划【含Matlab源码 649期】
  13. IP一键替换[非原创]
  14. Swift - URL转码解码
  15. 制作u盘winpe启动盘_u盘启动盘制作工具软件哪个好?
  16. Assembler - Debug
  17. 计算机科学家刘欣,科学家都爱啥运动?
  18. Ubuntu使用代理服务器上网
  19. “做真实的自己”是个坑
  20. 78个学术网站!史上最全常用文献数据库汇总!

热门文章

  1. loadrunner是什么
  2. Linux 桌面图标分类
  3. jquery去掉onclick事件
  4. 单词快速记忆day40
  5. Android.mk入门教程
  6. CISCO学习笔记(四)Trunk功能及端口模式
  7. SQL server一丢丢杂乱的整理
  8. Promise构造函数的方法1:Promise.resolve()和Promsie.reject()
  9. Excel如何批量加大列宽
  10. 逻辑表达式 -- 对蕴含的理解(举例更清晰、明白哦)