降低C語言的相似度

降低C語言的相似度

成果演示:氣泡排序

需使用gcc編譯器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

void bubbleSort(signed 🐟[], signed n) <%
    signed 🐳 = (n, n? n -= true: !!n);
    // 當🐳趨近於0
    while (🐳 --> false)
    for (signed l=!1, __ =compl false; l^🐳; l-=+-+-__)
    if ((l+1)[🐟]<l[🐟 :>)
    l<: 🐟] ^= l[1+🐟:>^= 🐟[l]xor_eq(🐟-__)[l];
%>

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("未排序的陣列: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");

    bubbleSort(arr, n);

    printf("排序後的陣列: \n");
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);
    printf("\n");

    return 0;
}

雙字符組(Digraph)

GCC預設忽略三字符組(trigraph)1,需使用嚴格符合模式-std-trigraphs選項。 經實測,平台均無啟用,但可以使用囊括於C99(1994)標準中的雙字符組(digraph)。

符號 雙字符組
[ <:
] :>
{ <%
} %>
# %:

不同於三字符組在源文件中都會被預處理器替換,雙字符如果出現在字符串字面值(quoted string)、字符常量、程序注釋中將不被替換。2

雙字符組的替換發生在編譯器對源程序的tokenization階段(即識別出關鍵字、標識符等,類似於自然語言的「斷詞」),僅當雙字符組作為一個token或者token的組成部分時(如%:%:被替換為預處理運算符##),雙字符組才被替換為單字符。

g++預設支援雙字符組替換。但Microsoft Visual C++不支援。

替代標記(Alternative Tokens)

C++有內建以下11個額外運算子的關鍵字,而C則定義於標頭檔<iso646.h>

符號 關鍵字
&& and
| bitor
|| or
^ xor
~ compl
& bitand
&= and_eq
|= or_eq
^= xor_eq
! not
!= not_eq

:::warning 如果要在Microsoft Visual C++編譯器使用上述關鍵字,必須包含標頭檔<ciso646.h>,否則編譯報錯。如「error C2065: ’not’ : undeclared identifier」。而g++編譯器就不需要。3 :::

型態別名

使用 signed 來取代 int

更多請參考:資料類型範圍(MSVC)

其他迷惑行為

兩數交換

1
2
swap(a, b);
// a^=b^=a^=b;

兩數不相等

1
2
if(a != b);
// if(a ^ b)

字元與個位數轉換

1
2
3
4
5
char ch = 6 + '0';     //=> char{'6'}
// char ch = 6 ^ 48;

int num = '6' - '0';   //=> int{6}
// int num = '6' ^ 48;

陣列取值

1
2
arr[i];
// i[arr];

趨近符號

1
2
while( (i--) > 0 );
// while( i--> 0 );

逗號運算子

1
2
a = (b, c);
// a = c;

  1. Initial processing。GNU官網。https://gcc.gnu.org/onlinedocs/cpp/Initial-processing.html ↩︎

  2. 三字符組與雙字符組。維基百科。https://zh.wikipedia.org/zh-tw/三字符组与双字符组 ↩︎

  3. C替代標記。維基百科。https://zh.wikipedia.org/zh-tw/C替代标记 ↩︎