大家好,我是雜燴君。
嵌入式大雜燴周記主要是一些實用項目學(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