爲何Swift和Python要拋棄++\--?

簡單好用的++、--

說到自增(++)\自減(--)運算符,小夥伴們應該都不會陌生,在不少編程語言的代碼中,都常常出現它們的身影。html

  • 好比經常使用的for語句
for (int i = 0; i < n; i++) {
    // TODO
}
  • 好比經典的一行代碼實現字符串拷貝
// 將src的內容拷貝至dest
void strcpy(char *dest, char *src) {
    while (*dest++ = *src++);
}

int main() {
    char s1[10], *s2 = "xmg_mj";
    strcpy(s1, s2);
    printf("%s", s1); // xmg_mj
    return 0;
}

使用得當的話,自增(++)\自減(--)運算符的確可讓代碼簡潔又優雅。python

可是

2大熱門編程語言SwiftPython並不支持自增(++)、自減(--)運算符,這是爲何呢?c++

這裏先給出幾個參考連接,有興趣的小夥伴能夠自行去閱讀一下:git

這裏只列出幾個顯而易見的理由swift

  • 有了強大又簡潔的for-infor語句中能夠徹底不須要++、--
// C++
for (int i = 0; i < 5; i++) {
    cout << i << endl;
}

// Swift
for i in 0..<5 {
    println(i)
}

// Python
for i in range(5):
    print(i)
  • 儘管while (*d++ = *s++);看起來彷佛簡單而優雅,但對於初學者來講絕非簡單,會增長學習成本。而SwiftPython更傾向於但願任何人都能快速上手這門編程語言。app

  • 當混合使用前綴和後綴的++、--時編程語言

    • 會下降代碼的可讀性,好比while (n++ > --k),經驗豐富的程序員也必須停下來思考一下代碼的具體含義是什麼
    • 運行結果可能會有不肯定性

運行結果的不肯定性

下面列出2段代碼,變量b的結果是什麼呢?(值得一提的是:實際開發中咱們並不會這麼寫,這裏把它列出來僅僅是爲了討論一些技術細節)

int a, b;

// 第1段代碼
a = 1;
b = a++ + ++a + a++ + ++a;

// 第2段代碼
a = 1;
b = a++ + a++ + a++ + a++;

實際上,上面的C語言代碼在MSVC、MinGW編譯器下得出的結果是不徹底一致的

  • MSVC:微軟出品
  • MinGW:GNU出品(能夠理解爲Windows版本的GCC)

第1段代碼

結果一致,符合絕大部分人的預期,因此就不展開討論了

a = 1;
b = a++ + ++a + a++ + ++a;
// MSVC:b = 1 + 3 + 3 + 5 = 12
// MinGW:b = 1 + 3 + 3 + 5 = 12

第2段代碼

結果不一致

  • MSVC的結果是1 + 1 + 1 + 1 = 4
  • MinGW的結果是1 + 2 + 3 + 4 = 10
a = 1;
b = a++ + a++ + a++ + a++;
// MSVC:b = 1 + 1 + 1 + 1 = 4
// MinGW:b = 1 + 2 + 3 + 4 = 10

你可能好奇:你怎麼知道MinGW的計算過程是1 + 2 + 3 + 4呢?根據最終結果10反推回去猜出來的麼?NO!若是是這樣作的話,那就有點侮辱了程序員這個職業了。

像這種不太容易從表面去理解的代碼,你若想知道它的真正本質,那就要搬出強有力且精準的武器了,它就是彙編語言(Assembly Language)

簡單說明一下使用彙編語言的理由:

  • 衆所周知,C語言代碼最終都會被編譯爲機器語言代碼(也叫作機器指令,只由0和1組成)
  • 那經過研究最終的機器指令來探索C語言代碼的本質?因爲機器指令極其晦澀難懂,所以,對通常人來講,這並非一種高效的辦法
  • 最佳的辦法是:研究一下介於C語言機器語言之間的彙編語言代碼
    • C語言彙編語言機器語言
    • 彙編語言代碼比機器指令可讀性高不少
    • 每一條機器指令都有與之對應的彙編語言代碼
    • 所以,你研究彙編語言代碼,基本就等同於研究機器指令,可讀性+精準性兼具

看看MSVC環境下的彙編代碼

  • 紅框代碼:將4個a相加的結果賦值給b,因爲a的初始值是1,因此b = 1 + 1 + 1 + 1 = 4
  • 綠框代碼:讓a執行4次自增1的操做,至關於執行4次a += 1

看看MinGW環境下的彙編代碼

  • 爲了保證能基本看懂這段彙編代碼,建議你能夠理解爲[rbp-0x4]表明變量a,[rbp-0x8]表明變量b
  • 綠框代碼:讓a執行自增1的操做,至關於執行a += 1
  • 紅框代碼:將a每次自增1以前的值累加起來,最後賦值給b
  • 能夠看到,綠框、紅框代碼是交替執行的,因此最終b = 1 + 2 + 3 + 4 = 10

最後2段代碼

最後再放2段代碼出來,在MSVC和MinGW下的結果也是不一致的

a = 1;
b = ++a + ++a + ++a + ++a;
// MSVC:b = 5 + 5 + 5 + 5 = 20
// MinGW: b = 3 + 3 + 4 + 5 = 15

a = 1;
b = ++a + ++a + a++ + a++;
// MSVC:b = 2 + 3 + 3 + 4 = 12
// MinGW:b = 3 + 3 + 3 + 4 = 13

根據前面的一些講解,相信你如今能夠推斷出MSVC的結果了。

但MinGW的結果可能仍是會讓人感受到奇怪:它實際上是先讓最前面的2個++a執行a自增1的操做,後面的2個++a\a++就照常處理,因此最終b = 3 + 3 + ...

好了,就此打住,建議不要去糾結這些細節了,由於原本就不推薦這種寫法。你只須要知道:多個前綴、後綴的自增自減一塊兒使用時,結果具備不肯定性。

總的來講,++、--是把雙刃劍,再者,它並不是是編碼過程當中必不可缺的,因此被SwiftPython拋棄也是正常的事。

關於彙編

常常看到有人說:彙編語言都是上古時期的編程語言了,沒啥用,甚至還有人說C\C++這麼古老的語言,沒有任何學習價值。我我的並不贊同這些觀點。掌握好彙編,能夠更好地瞭解代碼的本質,掃除一些基本的知識誤區​。​

由於時間和篇幅的關係,這篇文章並無詳細解釋每一句彙編代碼的做用。若是你對彙編感興趣,能夠參考如下圖片

以前有在B站上傳一些彙編教程,有須要的小夥伴能夠向公衆號發送彙編兩字,獲取教程地址

最後的思考題

最後留一道思考題,能夠將思考的結果直接留言評論

不是說Python不支持自增(++)\自減(--)運算符麼,爲何下面的Python代碼能運行成功呢?

a = 10
b = ++a

c = a++ + ++a

若是你特別但願我寫點什麼方面的內容,也能夠留言建議,謝謝

歡迎關注

相關文章
相關標籤/搜索