C 語言字符串(譯)

  C 語言的 switch 語句很是強大。然而,它不能用字符串做爲判斷條件,只能用常整數。這是能夠理解的,由於 C 的字符串僅僅是數組,它們並非並非一個總體。javascript

  在某些狀況下,將 string 做爲 switch 語句判斷條件是很是有用的。在 lwan 中我用一個小竅門避免在熱門路徑調用 strcmp 家族函數。這是利用字符串僅僅是字節數組這個概念,咱們將這些字節數組轉化成一個指向 32 位整數的指針,並解引用這個指針。利用這個竅門,咱們就能夠在 switch 語句中使用短小的字符串(例如:文件擴展名,包括 . 它們大多數只有四個字符)來做爲判斷條件。css

  C 也支持多字節整型常量。然而因爲大小端的影響, 當你在這些編譯這些常量時啓用 -Wall -Wextra 選項,GCC 會發出警告。個人解決方法是:用宏和枚舉類型配合去建立一個編譯器指望的常整型。下面的代碼直接從 lwan 拷貝的,爲了說明  STRING_SWITCH 語句的用法:html

 1 #define STRING_SWITCH_L(s) switch (*((int32_t *)(s)) | 0x20202020)
 2 #define MULTICHAR_CONSTANT(a,b,c,d) ((int32_t)((a) | (b) << 8 | (c)<< 16 | (d) << 24))
 3 
 4 enum {
 5     EXT_JPG = MULTICHAR_CONSTANT_L('.','j','p','g'),
 6     EXT_PNG = MULTICHAR_CONSTANT_L('.','p','n','g'),
 7     EXT_HTM = MULTICHAR_CONSTANT_L('.','h','t','m'),
 8     EXT_CSS = MULTICHAR_CONSTANT_L('.','c','s','s'),
 9     EXT_TXT = MULTICHAR_CONSTANT_L('.','t','x','t'),
10     EXT_JS  = MULTICHAR_CONSTANT_L('.','j','s',0),
11 } lwan_mime_ext_t;
12 
13 const char* lwan_determine_mime_type_for_file_name(char *file_name)
14 {
15     char *last_dot = strrchr(file_name, '.');
16     if (UNLIKELY(!last_dot))
17         goto fallback;
18 
19     STRING_SWITCH_L(last_dot) {
20     case EXT_CSS: return "text/css";
21     case EXT_HTM: return "text/html";
22     case EXT_JPG: return "image/jpeg";
23     case EXT_JS:  return "application/javascript";
24     case EXT_PNG: return "image/png";
25     case EXT_TXT: return "text/plain";
26     }
27 
28 fallback:
29     return "application/octet-stream";
30 }

  咱們注意到,STRING_SWITCH_L 是將字符串與一個 32 位整數按位或,這樣作能夠一次性檢測 4 個字符的狀況。java

  這樣的 switch 語句在 lwan 中用來匹配 HTTP 頭和 HTTP 請求方法。也用來作簡單的文件擴展名到 MIME-Type 的轉換,就像上面代碼所展現的那樣。數組

  譯自 http://tia.mat.br/blog/html/2012/08/09/string_switch_in_c.html ,若有錯誤,清留言!app

相關文章
相關標籤/搜索