程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 的二進制語法與語義,二進制語法語義

C++ 的二進制語法與語義,二進制語法語義

編輯:C++入門知識

C++ 的二進制語法與語義,二進制語法語義


二進制的語法

  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;  // binary
int i = 052;  // octal
int i = 42;  // decimal
int i = 0x2a;  // hexadecimal

 

2. 使用 strtol/strtoll/strtoq 函數,可以將一個字符串轉換成整數,base 取 2 表示轉換成二進制數。 #include <stdlib.h> long int strtol(const char *nptr, char **endptr, int base); long long int strtoll(const char *nptr, char **endptr, int base);

 

3.  也可以使用 STL 裡的 bitset 完成,不僅可以用數字,也可以用其他字符表示 0/1,這個比方法 2 更強大。這種方法我在做培根密碼解密題用到過,將 A/B 字符映射成 0/1 數字。
// unsigned long long constructor
std::bitset<8> (42);
// string constructor
std::string bits = "110010";
std::bitset<8> binary(bits);  // [0,0,1,1,0,0,1,0]
// string constructor using custom zero/one digits
std::string bacon = "ABABB";
std::bitset<5> m(bacon, 0, std::string::npos, 'A', 'B'); // [0,1,0,1,1]
  4. 可以使用 boost 庫的 BOOST_BINARY, 可以每隔開幾個數字一寫,在表示很大的數時很方便閱讀。
int value1 = BOOST_BINARY( 100 111000 01 1 110 );
unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported

 

5. 如果不是一項工程,而是簡短的程序,可以利用 C++ 的模板模擬二進制語義。
template<unsigned long long N>
struct binary
{
    enum { value = (N%10) + binary<N/10>::value*2 };
};

template<>
struct binary
{
    enum { value = 0 };
}
  int value = static_cast<int>(binary<101010>::value); 上面的代碼中, enum 是為了讓變量在編譯期獲取結果,沒有用整型。還有一個問題是如果數的開頭有 0,結果可不妙。整個數被當成了八進制而不是十進制數解析,很容易滋生 bug。比較好的解決方法是數字經常以 0 開頭(或添加斷言強制),將十進制換成八進制。    
// need to enable C++11 flag
template<unsigned long long>
struct binary
{
  constexpr static int value = binary<N/8>::value + N%8;
};
 
template<>
struct binary<0>
{
  constexpr static int value = 0;
}

 

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);

 

   

對於如下說明,語法與語義都正確的賦值是____

答案是C。
A、語法上正確(可能引起編譯警告)。若非靜態變量或全局變量,否則s沒有被初始化,是隨機值,*s的值無法確定,即沒有確定的語義;若是靜態變量或全局變量,s被初始化為0,對地址0的解引用操作沒有確定的語義。
B、錯誤。理由同上,對隨機地址的操作不具有確定的語義(s[0]等價於*s)。另外對隨機地址單元的寫操作(賦值)引起的後果不可預料。
C、正確,將a[1]的地址賦值給指針s。
D、語法錯誤,c(int)和a(const int*)的類型不匹配,會引起編譯錯誤。
----
[原創回答團]
參考資料:原創
 

問計算機程序中的詞法,語法,語義到底指什?

詞法,例,什麼樣的詞可以做變量名字:
變量名必須是以字母開始的字母數字串,允許符號"_",
C語言,大小寫區分,名字長度最長多少多少,不允許用保留字做變量名.
有的語言大小寫不區分.名字長度有的有限制,看你是什麼語言.

保留字:系統函數名,系統常量名,語句用字.例如:
sqrt(),sin(),pow(),NULL,EOF,if,while,for

語法:
程序的結構:
頭文件
全局量聲明
函數原型聲明
主程序塊
子程序塊
子程序塊

語法:
語句:
循環語句: for (i=0;i<10;i++) { ....};
while (..) { ...}
開關語句: switch (..) {
case 1: ...;break;
case 2: ...;break;
default: ...;break;
}
條件語句: if (..) { ...;} else { ...;};
等語句的規矩.

語義:
描述你的計算過程意思正確.例如:
雪是白的. -- 語法正確,語義正確.
雪是紅的. -- 語法正確,語義錯誤.

計算1加到100等與幾:
語法正確,語義正確.
sum=0;
for (i=1;i<=100;i++) sum=sum+i;
printf("%d\n",sum);

語法正確,語義錯誤:
sum=0;
for (i=0;i<100;i++) sum=sum+i;
printf("%d\n",sum);
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved