当前位置: 首页 > news >正文

【C语言进阶】字符函数和字符串函数的内部原理

前言

        c语言没有字符串类型,字符串通常放在常量字符串或者字符数组里面,本节内容是介绍关于字符串的函数,并且详细剖析了内部的原理。

 1.strlen函数

size_t strlen(const char* str);

        原理是字符指针遇到'\0'就停止,最终计算'\0'之前的长度。所以这里放一个字符数组那么得出的值就是随机值。

        strlen的返回值是size_t,其实就是无符号整型,在使用这个函数的时候需要注意一些小的细节。

易错:由于strlen返回的是无符号整型,所以永远不会输出负数,这里的-3被当做无符号整型的时候,在内存中是一个非常大的数字,这里的结果就会影响逻辑判断。

1.1 模拟实现

#include<stdio.h>
#include<assert.h>
// 1.模拟实现strlen
size_t mystrlen(const char* str) 
{assert(str); // 断言,避免是空指针size_t len = 0;while (*str != '\0'){str++;len++;}return len;
}int main()
{char str[] = "hello";printf("%d\n",mystrlen(str));return 0;
}

 2.strcpy函数

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

        字符串拷贝函数,将源头的数据拷贝到目的地数组去,具体的应用场景是,需要把一个字符串传给字符数组的时候。

         这个函数有一个缺点,那就是字符串本身含'\0'的时候,拷贝字符串会不完整。这是因为函数内部是按照'\0'作为字符串的终止符,只会拷贝‘\0’及之前的字符。

常见的错误:

下图中p所指向的是一个常量字符串,内容是无法更改的。

2.1 模拟实现

        需要注意的是,这里返回的是目标字符数组的起始地址。

#include<stdio.h>
char* mystrcpy(char* dest, const char* str)
{assert(dest);char* ret = dest;assert(str);while (*str != '\0') {*dest = *str;dest++;str++;}*dest = *str;return ret; // 返回目标数组首地址
}int main()
{char str[] = "hello";char dest[20] = { 0 };mystrcpy(dest,str);//printf("%d\n",mystrlen(str)); printf("%s\n",dest);return 0;
}

 3. strcat函数

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

字符串追加,将源字符串追加到目的字符串。

3.1 模拟实现

#include<stdio.h>
#include<assert.h>
char* mystrcat(char* dest,const char* source) 
{assert(dest && source);char* ret = dest;while (*dest != '\0') {dest++;}while (*source != '\0') {*dest = *source;dest++;source++;}*dest = *source; // source的\0直接给destreturn ret;
}int main()
{char str[20] = "hello ";mystrcat(str, "world");printf("%s\n",str);return 0;
}

需要注意的第一点是,不能给自己追加自己,这是因为,在覆盖'\0'之后追加最后一个\0的时候,发现之前的\0已经被覆盖掉了,所以这会陷入死循环。

4.strcmp函数

int strcmp(const char* str1,const char* str2);

待续......

http://www.lryc.cn/news/589611.html

相关文章:

  • 一区 Top (HPJ) | WGAS+WGCNA分析文章套路
  • 详解低速容错CAN(附与高速CAN对比表)
  • 区块链:以太坊侧链Polygon
  • 简单工厂设计模式
  • I/O 多路复用详解笔记
  • JS中async/await功能介绍和使用演示
  • [Dify]--进阶3-- 如何通过插件扩展 Dify 的功能能力
  • 基于华为欧拉系统安装FileGator文件管理器
  • screen -r 2050449 # 重新连接到 run_models 会话
  • saltstack安装部署
  • docker搭建freeswitch实现点对点视频,多人视频
  • vscode里面怎么配置ssh步骤
  • 【PTA数据结构 | C语言版】层序遍历二叉树
  • js分支语句和循环语句
  • 小架构step系列15:白盒集成测试
  • NE综合实验3:链路聚合、VLAN与Trunk、STP、DHCP、OSPF及PPP整合部署
  • 经典排序算法之插入排序
  • 二分查找栈堆
  • 笔试——Day8
  • 力扣经典算法篇-25-反转链表 II(头插法)
  • AI 增强大前端数据加密与隐私保护:技术实现与合规遵
  • 牛客:HJ22 汽水瓶[华为机考][数字处理]
  • C# 网口demo
  • Neo4j Python 驱动库完整教程(带输入输出示例)
  • deepseekAI对接大模型的网页PHP源码带管理后台(可实现上传分析文件)
  • Python初学者笔记第十三期 -- (常用内置函数)
  • RestTemplate 实现后端 HTTP 调用详解
  • python 基于 httpx 的流式请求
  • kube-proxy 中 IPVS 与 iptables
  • Vue 2 和 Vue 3 中,组件的封装、二次开发和优化