最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

C++ 深入挖掘"Hello, world!"

2021-04-21 13:09 作者:剎那-Ksana-  | 我要投稿

前言

(該文技術性比較強,最初發(fā)布在CSDN上,后來做了刪改后發(fā)到這里)

每個人學編程的時候,第一個接觸的大概率都是Hello World,比如說Python:

再比如說,Java:

C++的版本則是:

B站代碼塊無法輸入< >,所以用了數(shù)學符號里面的< >,以下代碼都是這樣

如果不算上 { } 的兩行,這個代碼一共只有3行,但是幾乎沒多少人會去一行行的詳細挖掘其中的內(nèi)容,所以今天我就準備更加深入的探索其中的每一行的細節(jié)。


1. Pre-processor

第一行:

是將iosteam這個庫引入到我們的代碼中,#include是一個所謂的pre-processor directives里面的一個(其他的還有#define, #pragma等等)。這個preprocess也是C、C++與眾不同的一個地方。

如果你在某一行里面定義了preprocessor,那么你這一行里面不能再放其他非preprocessor的代碼,但是preprocessor的語句可以橫跨多行。preprocess末尾也不需要添加分號。

#include 我們知道有兩種格式,一個是#include <library>,另一個是#include “l(fā)ibrary.h"。如果我們的library已經(jīng)在我們的開發(fā)環(huán)境里面的話,我們用< >來導入,否則就用" "。如果你用的是Visual Studio的話,有關的設定可以在下圖的地方看到

Property page

如果你的項目里面同一個library被include多次,那么你很可能在編譯程序的時候會出錯。所以很多情況下,我們用#pragma once解決重復include的問題。或者我們可以通過#ifndef#define這兩個語句。(詳細內(nèi)容可參見:https://en.wikipedia.org/wiki/Include_guard)

每一個C++都有一個main函數(shù):

在執(zhí)行C++程序的時候,程序會自動找到main函數(shù)的所在位置,然后從main開始執(zhí)行。

如果我們的程序里面沒有main函數(shù),絕大多數(shù)情況下,我們的程序不會被編譯。(記得誰講過,C++很熱門的一個話題就是——Will it compile?)

這個main函數(shù),還有另一個我們熟知的版本:

argv (Command line argument) 用來傳輸用戶給的參數(shù),因為argv是一個數(shù)組,所以我們需要argc (argument count) 來定義這個數(shù)組有多長。

此外,還有一個細節(jié)就是,這個main函數(shù),需要返回一個int類型的數(shù)據(jù),有時候我們也可以返回void,但編譯器會返回如下的警告:

Warning C4326 return type of ‘main’ should be ‘int’ instead of ‘void’

但是這里我想說的其實是——注意我們的main函數(shù)下面沒有return。一般而言,如果我們有一個函數(shù)需要返回int或者其他類型的數(shù)據(jù),而我們沒有return語句的話,編譯器會返回如下的錯誤:

Error C4716 ‘Some Function’: must return a value

但是唯獨main是一個特例,如果我們沒有return語句的話,程序會自動幫我們return 0

最后,由于C++非Type safe,所以我們甚至可以返回一個Boolean類型或者char類型的數(shù)據(jù),例如:

這個在Type safe的語言里面是不允許的。


接下來的一句:

我們都知道是輸出Hello world到我們的屏幕上??此坪唵危瞧渲袇s包含著很多復雜的東西。

首先我們從最簡單的開始說起。std是一個所謂的namespace

namespace的存在意義就是為了避免名字上面的沖突。比方說我手里有兩個長得一模一樣的兩個函數(shù),都叫做咖啡,那么這個時候我就用Starbucks和Dunkin’ Donuts將這兩杯咖啡區(qū)分開來。(這里沒有給這兩家店做廣告的意思 lol)

其次,cout來自于iostream這個庫,所以我們必須要導入這個庫,才能使用cout。而cout并不是唯一可以將內(nèi)容輸出到屏幕的方式,我們也可以用printf來替代cout

printf屬于C里面的一個函數(shù),而cout屬于C++里面的函數(shù),具體的性能差異可以忽略不計,printf還可以輸出格式化的內(nèi)容,如:

但cout卻沒有這個功能。此外,printf還有其他親戚,如fprintf。除了printf以外,C++內(nèi)還有puts,puts和printf比較接近。

以上三個方式的性能差異,都可以忽略不計,具體使用哪一個主要還是看每個程序員的習慣。

接下來,是<<這個符號,這個符號是將比特向左移動(bitwise left shift),a<<b就是將a的比特朝左移動b的距離。當然在這里,是運算符重載來賦予<<其他的意義——即將后面的那一串字符串print到我們的控制臺里面。

此處運算符重載的格式為:

此處只列舉float,其他參數(shù)還包括int, double, bool等十多種。這里留意這句語句的返回類型。

再接下來,一個非常復雜的問題是,cout到底是一個什么東西?

很明顯,不像printf和puts,cout它不是一個函數(shù)(如果是函數(shù)那怎么能運算符重載呢?),它是一個std::ostream類型的object(ostream是一個class),并且這個實體名字叫做cout。

那么既然cout是一個實體的object,那么為什么我們不需要在代碼里面創(chuàng)建實體,比如說:

這里值得一提的是,你的確可以創(chuàng)建一個std::ostream類型的實體,然后通過那個實體來執(zhí)行ostream下某些功能:

但因為cout這個實體,我們的庫已經(jīng)幫我們創(chuàng)建好了,通過extern使得我們的cout成為一個全局可見的變量:

這樣的話就剩得我們再去創(chuàng)建一個實體了。

接下來是ostream,它的原名叫做basic_ostream:

這里的using是給我們的某一個數(shù)據(jù)類型起一個別名,typedef能完成相同的任務:

這個basic_ostream的定義如下:

這里的_Elem里面放char type,比如說char, wchar之類的,而_Traits里面基本上是放std::char_traits<_Elem>(即,如果是char,那么就放std::char_traits<char>)。

而至于這個class本身,我目前還沒有完全搞懂其中的機制??傊?,它的作用就是操作所謂的流(stream),流由連續(xù)的byte組成,這個流可以是formatted(比如說int, boolean, 字符串類型的數(shù)據(jù)),也可以是unformatted(純粹的binary數(shù)據(jù)),我們的"Hello, world"字符串就是一個流。

最后,如果我們要讓cout輸出一個自定義的內(nèi)容的話,我們可以用以下的方式:

正如我們之前運算符重載那樣,這里我們只是再額外重載一個,這里我們必須返回一個地址(reference),并且我們的參數(shù)里面必須傳輸一個ostream的地址,因為我們的cout是一個object。


后記

本來這個內(nèi)容是打算在愚人節(jié)做成視頻發(fā)出來博大家一樂的,后來發(fā)現(xiàn)這個真的是笑不出來


參考資料:

CPP Reference: https://en.cppreference.com/w/

Microsoft Docs C++ Language Reference: https://docs.microsoft.com/en-us/cpp/cpp/cpp-language-reference?view=msvc-160

THE END.

C++ 深入挖掘"Hello, world!"的評論 (共 條)

分享到微博請遵守國家法律
炎陵县| 吉安市| 马公市| 玉门市| 辽阳市| 吉木萨尔县| 西和县| 松潘县| 西青区| 华池县| 叙永县| 漳平市| 阜平县| 惠水县| 禹州市| SHOW| 饶平县| 沧州市| 玉溪市| 肇源县| 日喀则市| 莱州市| 桓仁| 会昌县| 竹山县| 鄂伦春自治旗| 神农架林区| 山阴县| 长沙市| 慈利县| 疏附县| 江源县| 舞阳县| 库尔勒市| 石城县| 伊吾县| 陵川县| 宁夏| 高台县| 门头沟区| 松溪县|