為C 新增短字串的switch case支援

2021-06-17 21:10:03 字數 2183 閱讀 7790

這篇文章描述了一種在c++中對短字串(長度為4以內)進行switch-case操作的嘗試,如同整型值那樣,以此避免因字串匹配帶來的開銷,稍微提高執行效率。

如大家所知,c++並不支援對字串(單字元還是支援的)做switch case的分支操作,因為switch的表示式只支援整型值或可轉化為整型值的型別。既然switch case不能用了,那可選的方案就只剩下if-else、map、hash(或還有其他,望告知),先分別對這三種方案做個簡要說明。

if-else,如果字串的可能值只有三種或三種以下,那麼這也是個不錯的選擇,**簡單,易讀,至於效率嘛,頂多也就做3次的字串比較;可要是字串的可能值不止3種,比如數10種,那麼這種方案就不太勝任了,最糟的情況下,字串比較可能要貫穿整個if判斷,這種**常見於新手。

map(或者叫dictionary),得益於boost和c++11的function庫,通過key-value的方式,將「字串-functor」進行一一匹對,分支選擇依賴於map查詢的返回項(functor),相對於if-else 而言,平均效率提高了,而且**看起來也好一些,新增新的字串時,只需在map初始化時加入即可,為此付出的代價就只是map儲存的內容開銷了,這也算是空間換時間的一種方式吧。

hash,應該是這三種當中最高效的了,幾乎就相當於整型值的switch-case操作了,先對字串hash,然後每個case分支都是匹配字串的hash值。由於switch-case的特性,case表示式必須是個constant-expression,即不能依賴於執行時計算原字串的hash值,編譯器不答應,所以只能對每個可能字串先計算好hash值,這種**必須寫上原字串作為注釋,這樣的**看起來很怪異,就像是這樣的:

int hash_val = hash_func(str);

switch(hash_val)

那麼,克服hash這個方案所存在的問題,盡量使它達到switch-case的「功效」,是這個實驗的目的。

從上面的**片段可看出,只要有辦法能夠讓字串「abcd」在編譯期自動計算出hash值,那麼這個方案就可行了。那如何將字串自動轉換為整型值呢?巨集定義???與字串相關的巨集定義有「#」這麼乙個符號,或許它能幫上忙,google之,果然,除了「##」、「#」、之外,還有「#@」這麼一種組合,將標記轉換為字元,如

#define makechar(x)  #@x

char a;

a = makechar(b);

bool is_equal = (a == 'b'); // is_equal 值為true

嘗試一下多個字元makechar(abc),編譯、除錯後發現abc被按位元組「或」到整型值,那接下來只需將待匹配的字串也按同樣的方式「轉化」為整型值就行了,直接貼**了:

templatet copy_str_to(t& dest, const char* str)

templatet copy_wstr_to(t& dest, const wchar_t* str)

//templatestruct cat_str_to

template<>

static t go(const wchar_t* psz)

};// templatestruct _case_cvtr_2;

templatestruct _case_cvtr_4;

//--------------------------usage--------------------------//

#define str_switch_2(str) switch(cat_str_to::go(str))

#define str_case_2(a) case _case_cvtr_2<#@a>::value

#define str_switch_4(str) switch(cat_str_to::go(str))

#define str_case_4(a) case _case_cvtr_4<#@a>::value

//--------------------------usage--------------------------//

#define switch	str_switch_4

#define case str_case_4

switch (str)

c 字串新增字元 C 字串

在 c 語言中,字串實際上是使用null字元 0 終止的一維字元陣列。因此,乙個以 null 結尾的字串,包含了組成字串的字元。下面的宣告和初始化建立了乙個 hello 字串。由於在陣列的末尾儲存了空字元,所以字元陣列的大小比單詞 hello 的字元數多乙個。char greeting 6 依據陣列...

js為字串新增樣式

var txt hello world 1.放大 document.write big txt.big 2.縮小 document.write small txt.small 3.加粗 document.write bold txt.bold 4.斜體 document.write italic t...

C 字串為空判斷

字串 字串為空情況有4種,如下 string str1 string str2 string str3 string.empty string str4 null 判斷方法 c 判斷字串的string類的方法有2個,定義如下 摘要 指示指定的字串是 null 還是 system.string.emp...