大家好,我是雜燴君。
嵌入式大雜燴周記主要是一些實(shí)用項(xiàng)目學(xué)習(xí)分享,每篇一個(gè)主題。
內(nèi)容主要來(lái)源于我們之前收集的資料:
https://gitee.com/zhengnianli/EmbedSummary
本期主角:sds
SDS 是 C 的字符串庫(kù),旨在通過(guò)添加堆分配的字符串來(lái)增強(qiáng)有限的 libc 字符串處理功能。
SDS 字符串庫(kù)特點(diǎn):
(1)計(jì)算效率更高。獲取字符串長(zhǎng)度所需的復(fù)雜度從O(N)降低到了O(1),所以即使獲取一個(gè)非常長(zhǎng)的字符串長(zhǎng)度,也不會(huì)對(duì)系統(tǒng)性能造成任何影響,因?yàn)樵撁畹臅r(shí)間復(fù)雜度僅為O(1)。
(2)二進(jìn)制安全。SDS 字符串函數(shù)是二進(jìn)制安全的,因此無(wú)論內(nèi)容如何,長(zhǎng)度都是字符串的真實(shí)長(zhǎng)度,如果字符串中間包含空字符,也沒(méi)有問(wèn)題。而C字符串函數(shù)遇到空字符結(jié)束。
(3)SDS 字符串函數(shù)杜絕緩沖區(qū)溢出。
(4)SDS 字符串函數(shù)減少修改字符串時(shí)帶來(lái)的內(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信息,獲取字符串的長(zhǎng)度的時(shí)間復(fù)雜度僅為O(1)。C字符串不記錄自身的len信息,所以為了獲取字符串的長(zhǎng)度只能遍歷整個(gè)字符串,并對(duì)遍歷的字符進(jìn)行計(jì)數(shù),直到遇到字符串結(jié)束符為止,時(shí)間復(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 字符串是通過(guò)函數(shù)或稍后我們將看到的其他類似函數(shù)創(chuàng)建和分配堆的。SDS 字符串可以printf()像任何其他 C 字符串一樣傳遞。SDS 字符串需要用 釋放sdsfree(),因?yàn)樗鼈兪嵌逊峙涞摹?/li>
(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)建一個(gè)空的零長(zhǎng)度字符串。
sdscpy()字符串拷貝函數(shù),它不需要長(zhǎng)度,但需要一個(gè)以空字符結(jié)尾的字符串。
(3)獲取sds字符串長(zhǎng)度
#include <stdio.h>
#include <string.h>
#include "sds.h"
#include "sdsalloc.h"
int main(int argc, char **argv)
{
sds str = sdsnewlen("A