加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 本期主角:sds
    • sds的使用
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

嵌入式大雜燴周記:sds 字符串庫

2022/08/26
664
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

大家好,我是雜燴君。

嵌入式大雜燴周記主要是一些實用項目學(xué)習(xí)分享,每篇一個主題。

內(nèi)容主要來源于我們之前收集的資料:

https://gitee.com/zhengnianli/EmbedSummary

本期主角:sds

SDS 是 C 的字符串庫,旨在通過添加堆分配的字符串來增強有限的 libc 字符串處理功能。

SDS 字符串庫特點:

(1)計算效率更高。獲取字符串長度所需的復(fù)雜度從O(N)降低到了O(1),所以即使獲取一個非常長的字符串長度,也不會對系統(tǒng)性能造成任何影響,因為該命令的時間復(fù)雜度僅為O(1)。

(2)二進制安全。SDS 字符串函數(shù)是二進制安全的,因此無論內(nèi)容如何,長度都是字符串的真實長度,如果字符串中間包含空字符,也沒有問題。而C字符串函數(shù)遇到空字符結(jié)束。

(3)SDS 字符串函數(shù)杜絕緩沖區(qū)溢出。

(4)SDS 字符串函數(shù)減少修改字符串時帶來的內(nèi)存重分配次數(shù)。

(5)SDS 字符串函數(shù)兼容部分C字符串函數(shù)。

sds源碼鏈接:

https://github.com/antirez/sds

sds的使用

1、sds結(jié)構(gòu)

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[];
};

用到了柔性數(shù)組,往期文章中也有用到柔性數(shù)組:

  • 分享一種靈活性很高的協(xié)議格式(附代碼例子)

sds字符串記錄自身的len信息,獲取字符串的長度的時間復(fù)雜度僅為O(1)。C字符串不記錄自身的len信息,所以為了獲取字符串的長度只能遍歷整個字符串,并對遍歷的字符進行計數(shù),直到遇到字符串結(jié)束符為止,時間復(fù)雜度僅為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)創(chuàng)建sds字符串
int main(int argc, char **argv)
{
    sds mystring = sdsnew("Hello World!");
    printf("%sn", mystring);
    sdsfree(mystring);

    return 0;
}

 

 

  • sdsnew()SDS 字符串是通過函數(shù)或稍后我們將看到的其他類似函數(shù)創(chuàng)建和分配堆的。SDS 字符串可以printf()像任何其他 C 字符串一樣傳遞。SDS 字符串需要用 釋放sdsfree(),因為它們是堆分配的。
 
(2)復(fù)制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 = %sn", src_str1);
    
    sds dst_str1 = sdsempty();
    dst_str1 = sdscpy(dst_str1, src_str1);
    printf("dst_str1 = %sn", dst_str1);

    sdsfree(src_str1);
    sdsfree(dst_str1);

    return 0;
}

 

sdsempty()函數(shù)創(chuàng)建一個空的零長度字符串。

sdscpy()字符串拷貝函數(shù),它不需要長度,但需要一個以空字符結(jié)尾的字符串。

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

int main(int argc, char **argv)
{
    sds str = sdsnewlen("A