0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++能不能讓編譯器自動推導(dǎo)變量類型嗎

Wildesbeast ? 來源:今日頭條 ? 作者:IT劉小虎 ? 2024-10-24 17:22 ? 次閱讀

隨著計算機性能的持續(xù)提升,編程語言似乎迎來了一次大爆發(fā),各種編程語言不斷出現(xiàn),樂意折騰的人總能找到一門適合自己胃口的編程語言。

總能找到一門適合自己胃口的編程語言

程序員的口味大體可以分為兩種:一是追求極致程序效率,一是追求極致開發(fā)效率。拋開稍顯晦澀的匯編語言不談,前者以C語言程序員為代表,C語言語法簡單,可控性強,更貼近機器,適合開發(fā)超高效率的程序。后者則以各種偏腳本化的語言程序員為代表,這類編程語言更貼近人類,因此開發(fā)效率很高。

Python程序中變量的類型

下面是一段 Python 代碼,可以看出,Python 程序員在定義變量時,甚至無需關(guān)心變量的類型,只需寫出核心邏輯即可:

#!/usr/bin/python # -*- coding: UTF-8 -*- counter = 100 # 賦值整型變量 miles = 1000.0 # 浮點型 name = "John" # 字符串

不過,程序中變量的數(shù)據(jù)類型本質(zhì)上是用于告訴計算機其占用內(nèi)存的大小,以及該如何解釋這段數(shù)據(jù)的。所以,即使是 Python 程序,在運行時也需要確定變量的類型,否則計算機就不知道如何存儲和解釋程序中的變量。當然了,由于上面這段代碼沒有顯式的指定變量類型,所以確定數(shù)據(jù)類型的工作只能交給編譯器(或者說解釋器)了。

Python使用變量非常簡單

C++程序中變量的類型

不要小看 Python 的這個特性,這可以省去相當多的“鍵盤敲擊次數(shù)”。作為實例,可以參考下面這段C++程序片段:

... std::list cars_list; ... std::list::iterator it; for (it=cars_list.begin(); it!=cars_list.end(); it++) { ... }

這個“定義”過程需要敲擊相當多的字符

為了遍歷 list 中的元素,上述C++代碼定義了迭代器it,可以看出,這個“定義”過程需要敲擊相當多的字符:“std::list::iterator ”。若是C++也允許像Python那樣,無需顯式的指定變量類型,而是把變量類型的確認工作交給編譯器,代碼就簡潔許多了:

... std::list cars_list; ... for (it=cars_list.begin(); it!=cars_list.end(); it++) { ... }

代碼簡潔許多

這樣的C++代碼并不影響閱讀,熟悉 list 的程序員一眼就能看出it是一個迭代器。

可能有讀者覺得將“確認變量類型”的工作交給編譯器會降低編譯效率,但是其實仔細想一下,應(yīng)該并非如此,請看下面這段C++代碼:

int a = 0; int *p = &a; a = p;

編譯器在處理第三行代碼時,大都會報錯,給出類似于下面這樣的信息

error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]

這說明C++編譯器在處理變量賦值時,也需要確定右值的類型,因此從理論上來看,自動推導(dǎo)類型并不會帶來多少額外的工作。

C++中的auto關(guān)鍵字

事實上,C++11標準的確增加了“變量類型自動推導(dǎo)”的功能,只不過不像 Python,C++的這一功能需要借助auto關(guān)鍵字。

其實早在C++98標準中,就已經(jīng)存在auto關(guān)鍵字了,只不過那時的auto關(guān)鍵字僅用于聲明變量擁有自動的生命周期,可是不使用 auto 關(guān)鍵字定義的變量仍然具有自動的生命周期,所以那時的 auto 關(guān)鍵字屬于多余的特性。

C++11標準丟棄了auto關(guān)鍵字之前的特性,取而代之的,將此關(guān)鍵字用于定義“可自動推導(dǎo)類型”的變量。下面是一段C++代碼示例,請看:

int a = 8; auto b = a; // 自動推導(dǎo) b 的類型為 int cout << typeid(b).name() << endl;

自動推導(dǎo)類型的C++代碼示例

編譯這段C++代碼時應(yīng)注意指定C++11標準:

# g++ t.cpp -std=c++11 # ./a.out i

可見,程序輸出了i,表示變量 b 為 int 類型,這說明auto關(guān)鍵字的確根據(jù) b 的右值(int型的a)確定了 b 的類型為 int。

現(xiàn)在有了auto關(guān)鍵字,前面那個遍歷 list 的C++代碼片段就可以改寫了,請看:

for (std::list::iterator it=cars_list.begin(); it!=cars_list.end(); it++){ ... } // 現(xiàn)在可以改寫為 for (auto it=cars_list.begin(); it!=cars_list.end(); it++){ ... }

顯然簡潔了許多

顯然簡潔了許多,C++程序員也可以少敲很多次鍵盤,手指健康得到了一定程度的保護。

C++的 auto 關(guān)鍵字用于模板

上面只是C++中 auto 關(guān)鍵字的其中一種用法,事實上,auto 關(guān)鍵字不僅僅能夠讓程序員少敲代碼,也能帶來一些功能上的便利。例如,在定義模板函數(shù)時,用于聲明依賴模板參數(shù)的變量類型,下面是一段C++代碼示例:

template void add(_Tx x, _Ty y) { auto v = x+y; std::cout << v; }

請注意變量 v 的定義,如果這里不使用 auto 關(guān)鍵字就棘手多了,因為我們根本無法事先確定變量 x 和 y 的類型,不到編譯的時候,誰能知道 x+y 的結(jié)果究竟是什么類型呢?

誰能知道 x+y 的結(jié)果究竟是什么類型呢?

讀者應(yīng)該注意到上面的 add() 函數(shù)其實并不好用,因為它沒有將結(jié)果返回給調(diào)用者。于是可以做如下修改,請看相關(guān)C++代碼:

template auto add(_Tx x, _Ty y) { return x+y; }

可見,auto 關(guān)鍵字也可用于自動推導(dǎo)模板函數(shù)的返回值類型,否則 add() 函數(shù)的返回值類型也是相當難確定的。不過,在編譯這段C++代碼時,發(fā)現(xiàn)如下警告信息:

warning: ‘a(chǎn)dd’ function uses ‘a(chǎn)uto’ type specifier without trailing return type [enabled by default] auto add(_Tx x, _Ty y)

要避免出現(xiàn)這樣的警告信息,可以使用C++11標準引入的新關(guān)鍵字decltype,相關(guān)的C++代碼如下,請看:

template auto add(_Tx x, _Ty y)->decltype(x+y) { return x+y; }

auto用于定義模板函數(shù)

auto 在這里的作用也稱為返回值占位,它只是為函數(shù)返回值占了一個位置,真正的返回值是后面的decltype(x+y)?,F(xiàn)在編譯這段C++代碼,可以得到如下輸出,請看:

# g++ t.cpp -std=c++11 # ./a.out 9.14 7 145

注意事項

auto 關(guān)鍵字的“自動推導(dǎo)類型”功能是由編譯器提供的,而編譯器也不是占卜得到變量類型的,它需要知道一些信息,因此 auto 在定義變量時必須初始化:

int i = 3; auto j = i;

只有這樣,編譯器才能根據(jù)右值的類型推導(dǎo)出 auto 變量的類型。也正是因為如此,auto 變量作為函數(shù)的參數(shù)是非法的:

// 非法 void foo(auto a){ ... }

若是使用 auto 關(guān)鍵字在同一行定義多個變量,這些變量必須是同一類型,否則編譯器就會報錯,例如下面這兩行C++代碼:

auto a1 = 1, a2 = 2;//正確 auto b1 = 10, b2 = 'a';//錯誤,沒有推導(dǎo)為同一類型

如果 auto 變量初始化時的右值為引用,則去除引用。請看下面這段C++代碼:

int a = 1; int &b = a; auto c = b; // 此時 c 的類型為 int c = 100; // a 依然為 1

如果希望自動推導(dǎo)為引用類型,則需要配合&運算符:

auto &d = b; d = 100; // 此時 a 為 100

類似的,如果初始化表達式帶有 const 或者 volatile 修飾符,僅有 auto 定義的變量去除 const 和 volatile 修飾符。

最后要說明的是,C++中的 auto 關(guān)鍵字并不是真正的類型,它僅用于告訴編譯器“應(yīng)該自動推導(dǎo)變量的類型”,所以像 sizeof() 以及 typeid() 這樣操作數(shù)據(jù)類型的操作符是不能用于 auto 的,下面這兩行C++代碼是非法的:

size = sizeof(auto); // 非法 cout << typeid(auto).name() << endl; // 非法

小結(jié)

本節(jié)主要討論了C++11標準中的 auto 關(guān)鍵字,可見,它不僅能夠讓程序員少敲鍵盤,提升了C++程序開發(fā)效率,還額外提供了一些功能上的便利。文章在最后還討論了使用 auto 關(guān)鍵字的注意事項,希望對讀者有所幫助。

點個關(guān)注吧

歡迎在評論區(qū)一起討論,質(zhì)疑。文章都是手打原創(chuàng),每天最淺顯的介紹C語言、linux嵌入式開發(fā),喜歡我的文章就關(guān)注一波吧,可以看到最新更新和之前的文章哦。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2090

    瀏覽量

    73408
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1608

    瀏覽量

    48979
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    609

    瀏覽量

    28289
收藏 人收藏

    評論

    相關(guān)推薦

    C語言中結(jié)構(gòu)體能不能相加

    C語言中,結(jié)構(gòu)體能不能相加?
    的頭像 發(fā)表于 12-19 17:04 ?1145次閱讀
    <b class='flag-5'>C</b>語言中結(jié)構(gòu)體<b class='flag-5'>能不能</b>相加

    能不能把導(dǎo)入的工程的編譯器也修改為argmgcc呢?

    KEil MDK工程導(dǎo)入RTT-STUDIO后,工程上右鍵,點擊“構(gòu)建設(shè)置”菜單,設(shè)置頁面出不來,一點反應(yīng)沒有.另外,我的理解是,導(dǎo)入的工程感覺還是用的KEIL MDK做編譯器,而原生的RTT-STUDIO工程是用的armgcc。能不能把導(dǎo)入的工程的
    發(fā)表于 02-21 10:08

    C++編譯器數(shù)值性能比較

    現(xiàn)在市面上,主流的C/C++編譯器包括M$的CL、gcc、Intel的icl、PGI的pgcc及Codegear的bcc(原來屬于Borland公司)。Windows上使用最多的自然是cl,而在更廣闊的平臺上,gcc則是
    發(fā)表于 09-10 11:54 ?8次下載

    電池能不能修復(fù)?

    電池能不能修復(fù)? 電池修復(fù)作為一個新生事物,許多人對它不了解,也有許多人對它一知半解。那么電池到底能不能修復(fù)呢?
    發(fā)表于 11-23 10:40 ?1079次閱讀

    Linux下C/C++編譯器gcc使用指南

    1.gcc包含的c/c++編譯器 gcc,cc與c++,g++ gcc和cc是一樣的,c++和g++是一樣的。一般
    發(fā)表于 11-02 10:59 ?0次下載

    英特爾C++和Fortran編譯器的逐漸優(yōu)化過程介紹

    這是一個介紹視頻,解釋了英特爾?C++和Fortran編譯器提供的逐步優(yōu)化。
    的頭像 發(fā)表于 11-05 06:21 ?3076次閱讀

    MATLAB 64位C語言和C++編譯器應(yīng)用程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是MATLAB 64位C語言和C++編譯器應(yīng)用程序免費下載。
    發(fā)表于 05-21 08:00 ?4次下載
    MATLAB 64位<b class='flag-5'>C</b>語言和<b class='flag-5'>C++</b><b class='flag-5'>編譯器</b>應(yīng)用程序免費下載

    EE-88:使用21xx編譯器初始化C語言中的變量

    EE-88:使用21xx編譯器初始化C語言中的變量
    發(fā)表于 05-19 21:08 ?1次下載
    EE-88:使用21xx<b class='flag-5'>編譯器</b>初始化<b class='flag-5'>C</b>語言中的<b class='flag-5'>變量</b>

    阿里云基礎(chǔ)軟件C/C++編譯器的工作現(xiàn)狀及挑戰(zhàn)

    本文主要詳細介紹了阿里云C、C++編譯器(GCC、LLVM)工作現(xiàn)狀、主流編譯器(GCC、LLVM)開源社區(qū)參與現(xiàn)狀以及多架構(gòu)(RISC-V)對數(shù)據(jù)中心的挑戰(zhàn)。
    的頭像 發(fā)表于 06-23 15:26 ?2879次閱讀
    阿里云基礎(chǔ)軟件<b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>編譯器</b>的工作現(xiàn)狀及挑戰(zhàn)

    SuperH C/C++ 編譯器包 V.9.04 用戶手冊

    SuperH C/C++ 編譯器包 V.9.04 用戶手冊
    發(fā)表于 01-12 18:45 ?1次下載
    SuperH <b class='flag-5'>C</b>/<b class='flag-5'>C++</b> <b class='flag-5'>編譯器</b>包 V.9.04 用戶手冊

    指針能不能作為循環(huán)變量

    指針能不能作為循環(huán)變量?
    的頭像 發(fā)表于 02-16 18:11 ?969次閱讀

    C/C++編譯器的缺省字節(jié)對齊方式

    C/C++編譯器的缺省字節(jié)對齊方式為自然對界。即在缺省情況下,編譯器為每一個變量或是數(shù)據(jù)單元按其自然對界條件分配空間。
    的頭像 發(fā)表于 04-15 11:24 ?913次閱讀

    SuperH C/C++ 編譯器包 V.9.01 用戶手冊

    SuperH C/C++ 編譯器包 V.9.01 用戶手冊
    發(fā)表于 04-21 19:55 ?0次下載
    SuperH <b class='flag-5'>C</b>/<b class='flag-5'>C++</b> <b class='flag-5'>編譯器</b>包 V.9.01 用戶手冊

    SuperH C/C++ 編譯器包 V.9.04 用戶手冊

    SuperH C/C++ 編譯器包 V.9.04 用戶手冊
    發(fā)表于 07-03 18:38 ?4次下載
    SuperH <b class='flag-5'>C</b>/<b class='flag-5'>C++</b> <b class='flag-5'>編譯器</b>包 V.9.04 用戶手冊

    RX系列V3.06.00的C/C++編譯器包數(shù)據(jù)手冊

    電子發(fā)燒友網(wǎng)站提供《RX系列V3.06.00的C/C++編譯器包數(shù)據(jù)手冊.pdf》資料免費下載
    發(fā)表于 01-26 15:57 ?1次下載
    RX系列V3.06.00的<b class='flag-5'>C</b>/<b class='flag-5'>C++</b><b class='flag-5'>編譯器</b>包數(shù)據(jù)手冊