嵌入式大杂烩周记 | 第 15 期

大家好,我是杂烩君。

嵌入式大杂烩周记主要是一些实用项目学习分享,每篇一个主题。

内容主要来源于我们之前收集的资料:

https://gitee.com/zhengnianli/EmbedSummary

本期主角:sds

SDS 是 C 的字符串库,旨在通过添加堆分配的字符串来增强有限的 libc 字符串处理功能。

SDS 字符串库特点:

(1)计算效率更高。获取字符串长度所需的复杂度从O(N)降低到了O(1),所以即使获取一个非常长的字符串长度,也不会对系统性能造成任何影响,因为该命令的时间复杂度仅为O(1)。

(2)二进制安全。SDS 字符串函数是二进制安全的,因此无论内容如何,长度都是字符串的真实长度,如果字符串中间包含空字符,也没有问题。而C字符串函数遇到空字符结束。

(3)SDS 字符串函数杜绝缓冲区溢出。

(4)SDS 字符串函数减少修改字符串时带来的内存重分配次数。

(5)SDS 字符串函数兼容部分C字符串函数。

sds源码链接:

https://github.com/antirez/sds

sds的使用

1、sds结构

struct sds {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

用到了柔性数组,往期文章中也有用到柔性数组:

sds字符串记录自身的len信息,获取字符串的长度的时间复杂度仅为O(1)。C字符串不记录自身的len信息,所以为了获取字符串的长度只能遍历整个字符串,并对遍历的字符进行计数,直到遇到字符串结束符为止,时间复杂度仅为O(N)。

2、sds常用接口

sds sdsnewlen(const void *init, size_t initlen);
sds sdsnew(const char *init);
sds sdsempty(void);
sds sdsdup(const sds s);
void sdsfree(sds s);
sds sdsgrowzero(sds s, size_t len);
sds sdscatlen(sds s, const void *t, size_t len);
sds sdscat(sds s, const char *t);
sds sdscatsds(sds s, const sds t);
sds sdscpylen(sds s, const char *t, size_t len);
sds sdscpy(sds s, const char *t);
(1)创建sds字符串
int main(int argc, char **argv)
{
    sds mystring = sdsnew("Hello World!");
    printf("%s\n", mystring);
    sdsfree(mystring);

    return 0;
}
6535ebaa6b8a00ba74d45afc1102574c.png
  • sdsnew()SDS 字符串是通过函数或稍后我们将看到的其他类似函数创建和分配堆的。

  • SDS 字符串可以printf()像任何其他 C 字符串一样传递。

  • SDS 字符串需要用 释放sdsfree(),因为它们是堆分配的。

(2)复制sds字符串
#include <stdio.h>
#include "sds.h"
#include "sdsalloc.h"

int main(int argc, char **argv)
{
    sds src_str1 = sdsnew("Hello World!");
    printf("src_str1 = %s\n", src_str1);
    
    sds dst_str1 = sdsempty();
    dst_str1 = sdscpy(dst_str1, src_str1);
    printf("dst_str1 = %s\n", dst_str1);

    sdsfree(src_str1);
    sdsfree(dst_str1);

    return 0;
}
abdb629fd13b03946f28b3852b9d1475.png
  • sdsempty()函数创建一个空的零长度字符串。

  • sdscpy()字符串拷贝函数,它不需要长度,但需要一个以空字符结尾的字符串。

(3)获取sds字符串长度
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"

int main(int argc, char **argv)
{
    sds str = sdsnewlen("A\0\0B",4);
    printf("sdslen(str) = %d\n", (int) sdslen(str));

    printf("strlen(str) = %d\n", (int) strlen(str));

    sdsfree(str);
    return 0;
}
cb18adfa6b3d30eb9070b651eef17de3.png
  • SDS 字符串函数是二进制安全的,因此无论内容如何,长度都是字符串的真实长度,如果字符串中间包含空字符,也没有问题。

  • strlen函数则遇到空字符则计算结束。

(4)连接sds字符串
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"

int main(int argc, char **argv)
{
    sds str = sdsempty();
    str = sdscat(str, "Hello ");
    str = sdscat(str, "World!");
    printf("%s\n", str);

    sdsfree(str);
    
    return 0;
}
aa089f051bcc870e156572d6cc1da70f.png

以上就是本次的分享。

如果觉得文章有帮助,麻烦帮忙点赞、收藏、转发,谢谢!

咱们下期见~

注意

由于微信公众号近期改变了推送规则,为了防止找不到,可以星标置顶,这样每次推送的文章才会出现在您的订阅列表里。

猜你喜欢:

分享一种灵活性很高的协议格式(附代码例子)

访问非法内存为什么不会出错?

嵌入式大杂烩周记 | 第 14 期

分享几个实用的代码片段(第二弹)

分享一种你可能不知道的bug定位方法

分享一种修改配置文件的方法

《嵌入式大杂烩周记第 13 期:lz4》

《嵌入式并行多线程处理器,了解一下!》

《分享一种修改配置文件的方法》

《分享几个实用的代码片段(附代码例子)》

《废旧板子再利用:搭建无线调试环境!》

《嵌入式段错误的3种调试方法汇总!》

《简说TCP通信非阻塞接收(附代码例子)》

《TCP通信常用接口的使用封装》

《写国际化的嵌入式代码,时间问题如何处理?》

《Linux命令行万能解压命令》

《嵌入式软件中,总线错误的坑?替大家先踩一步》

《分享嵌入式软件调试方法及几个有用的工具!》

《分享两点提高编程能力的建议!》

在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式大杂烩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值