zoukankan      html  css  js  c++  java
  • C 语言字符串(译)

      C 语言的 switch 语句非常强大。然而,它不能用字符串作为判断条件,只能用常整数。这是可以理解的,因为 C 的字符串仅仅是数组,它们并不是并不是一个整体。

      在某些情况下,将 string 作为 switch 语句判断条件是非常有用的。在 lwan 中我用一个小窍门避免在热门路径调用 strcmp 家族函数。这是利用字符串仅仅是字节数组这个概念,我们将这些字节数组转化成一个指向 32 位整数的指针,并解引用这个指针。利用这个窍门,我们就可以在 switch 语句中使用短小的字符串(例如:文件扩展名,包括 . 它们大多数只有四个字符)来作为判断条件。

      C 也支持多字节整型常量。然而由于大小端的影响, 当你在这些编译这些常量时启用 -Wall -Wextra 选项,GCC 会发出警告。我的解决方法是:用宏和枚举类型配合去创建一个编译器期望的常整型。下面的代码直接从 lwan 拷贝的,为了说明  STRING_SWITCH 语句的用法:

     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 个字符的情况。

      这样的 switch 语句在 lwan 中用来匹配 HTTP 头和 HTTP 请求方法。也用来做简单的文件扩展名到 MIME-Type 的转换,就像上面代码所展示的那样。

      译自 http://tia.mat.br/blog/html/2012/08/09/string_switch_in_c.html ,如有错误,清留言!

  • 相关阅读:
    Java动态代理(三)——模拟AOP实现
    Java动态代理(二)CGLIB动态代理应用
    Java动态代理(一)动态类Proxy的使用
    CGLIB实现动态代理
    初识Java微信公众号开发
    spring+ibatis事务管理配置
    什么是事务的传播特性
    Spring事务配置的五种方式
    Java语言基础(五) Java原始数据类型的分类以及数据范围
    Java语言基础(四) String和StringBuffer的区别
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/4255342.html
Copyright © 2011-2022 走看看