|簡體中文

比思論壇

 找回密碼
 按這成為會員
搜索



查看: 401|回復: 0
打印 上一主題 下一主題

C++ 的二进制语法与语义

[複製鏈接]

56

主題

0

好友

490

積分

中學生

Rank: 3Rank: 3

  • TA的每日心情

    6 天前
  • 簽到天數: 204 天

    [LV.7]常住居民III

    推廣值
    0
    貢獻值
    0
    金錢
    156
    威望
    490
    主題
    56
    樓主
    發表於 2014-7-18 20:44:19
    二进制的语法  C/C++ 默认数字使用十进制,八进制使用前缀 0, 十六进制使用前缀 0x 或 0X,二进制常数的提议被否决(引用 C 语言程序原理国际标准 的 6.4.4.1 章节字段 "A proposal to add binary constants was rejected due to lack of precedent and insufficient utility."),一直没有二进制的表示方法, GCC 使用 0b/0B 前缀作为扩展,其实很多编译器都有这个扩展的,只是标准委员会一直没采纳。直到 C++14 才引进,可谓姗姗来迟啊。这种二进制语义 Java 7 也早些时候引入,Python 2.6 以及后来的 3 也引入,Python 为了避免十进制与八进制的混淆,一律用字母前缀,不分大小写,0b 为二进制,0o 为八进制,ox 为十六进制。Python2 升到 Python3 时果断丢弃了原来的八进制语义(也就是在 C/C++/Java 里面有 0 前缀的八进制的语义)。

    表示方法
    1. 下面每行语句表达语义相同,只是选用不同的进制数表示。
    int i = 0b101010;  // binaryint i = 052;  // octalint i = 42;  // decimalint i = 0x2a;  // hexadecimal

    2. 使用 strtol/strtoll/strtoq 函数,可以将一个字符串转换成整数,base 取 2 表示转换成二进制数。
    #include <stdlib.h>
    long int strtol(const char *nptr, char **endptr, int base);
    long long intstrtoll(const char *nptr, char **endptr, int base);


    3.  也可以使用 STL 里的 bitset 完成,不仅可以用数字,也可以用其他字符表示 0/1,这个比方法 2 更强大。这种方法我在做培根密码解密题用到过,将 A/B 字符映射成 0/1 数字。[url=][/url]
    // unsigned long long constructorstd::bitset<8> (42);// string constructorstd::string bits = "110010";std::bitset<8> binary(bits);  // [0,0,1,1,0,0,1,0]// string constructor using custom zero/one digitsstd::string bacon = "ABABB";std::bitset<5> m(bacon, 0, std::string::npos, 'A', 'B'); // [0,1,0,1,1][url=][/url]



    4. 可以使用 boost 库的 BOOST_BINARY, 可以每隔开几个数字一写,在表示很大的数时很方便阅读。
    int value1 = BOOST_BINARY( 100 111000 01 1 110 );unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned longlong long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported



    5. 如果不是一项工程,而是简短的程序,可以利用 C++ 的模板模拟二进制语义。
    [url=][/url]
    template<unsigned long long N>struct binary{    enum { value = (N%10) + binary<N/10>::value*2 };};template<>struct binary{    enum { value = 0 };}[url=][/url]


    int value = static_cast<int>(binary<101010>::value);
    上面的代码中, enum 是为了让变量在编译期获取结果,没有用整型。还有一个问题是如果数的开头有 0,结果可不妙。整个数被当成了八进制而不是十进制数解析,很容易滋生 bug。比较好的解决方法是数字经常以 0 开头(或添加断言强制),将十进制换成八进制。


    [url=][/url]
    // need to enable C++11 flagtemplate<unsigned long long>struct binary{  constexpr static int value = binary<N/8>::value + N%8;}; template<>struct binary<0>{  constexpr static int value = 0;}[url=][/url]




    6.  采用用户自定字面值(User-defined literals),注意这个是 C++11 新加的功能。之前的 C++03 内置一些类似的语义(比方说在浮点数后加字符 "f" 表示声明一个 float 而不是 double),但是用户不能自己定义。
    C++11 开放用户定义新的字面修饰符(literal modifier),利用自定义的修饰符完成由字面值构造对象。所有的自定字面值必须是后置,前置是不允许的。C++11 开放用户定义新的字面修饰符(literal modifier),利用自定义的修饰符完成由字面值构造对象。除了下划线,所有的后置被标准保留。所以,用户定义时需要以下划线开头。
    int operator "" _B(int i);static_assert( 101010_B == 42);






    重要聲明:本論壇是以即時上載留言的方式運作,比思論壇對所有留言的真實性、完整性及立場等,不負任何法律責任。而一切留言之言論只代表留言者個人意見,並非本網站之立場,讀者及用戶不應信賴內容,並應自行判斷內容之真實性。於有關情形下,讀者及用戶應尋求專業意見(如涉及醫療、法律或投資等問題)。 由於本論壇受到「即時上載留言」運作方式所規限,故不能完全監察所有留言,若讀者及用戶發現有留言出現問題,請聯絡我們比思論壇有權刪除任何留言及拒絕任何人士上載留言 (刪除前或不會作事先警告及通知 ),同時亦有不刪除留言的權利,如有任何爭議,管理員擁有最終的詮釋權。用戶切勿撰寫粗言穢語、誹謗、渲染色情暴力或人身攻擊的言論,敬請自律。本網站保留一切法律權利。

    手機版| 廣告聯繫

    GMT+8, 2024-11-1 09:09 , Processed in 0.012625 second(s), 17 queries , Gzip On, Memcache On.

    Powered by Discuz! X2.5

    © 2001-2012 Comsenz Inc.

    回頂部