0. 序言
<iostream.h>與<iostream>這兩個庫就是C++ 标準化前/後的兩個庫,現在都在并行使用。用 .h 包含的是C++ 标準化之前的庫 ,不帶 .h 的是C++ 标準化(C++ 98)之後的頭檔案,對于普通使用者來說這兩者沒有什麼差別,差別是在内部函數的具體實作上。
#include <iostream.h> //非标準輸入輸出流,這是标準化以前的頭檔案(當時還沒有命名空間的概念)
#include <iostream> //标準輸入輸出流,這個就是C++98标準化以後的标準頭檔案
1. C++發展概述
C++ 是一門以C為基礎發展而來的一門面向對象的進階程式設計語言,從1983年由Bjarne Stroustrup教授在貝爾實驗室創立開始至今,已有30多個年頭。C++ 從最初的C with class,經曆了從C++ 98、C++ 03、C++ 11、C++ 14再到C++ 17多次标準化改造,功能得到了極大的豐富,已經演變為一門集面向過程、面向對象、函數式、泛型和元程式設計等多種程式設計範式的複雜程式設計語言,入門具有一定的難度。
C++ 經曆了長時間的發展演變。1954年,John Backus發明了世界上第一種計算機進階語言Fortran,為之後出現的進階程式設計語言奠定了基礎。1970年,AT&T的Bell實驗室的 Ken Thompson,以BCPL語言為基礎,設計出簡單且接近硬體的B語言(取BCPL的首字母),并且他用B語言寫了第一個Unix作業系統。到了1972年,Bell實驗室的Dennis Ritchie和Ken Thompson共同發明了C語言,并使用C重寫Unix。1979年,Bjame Stroustrup到了Bell實驗室,開始從事将C改良為帶類的C(C with Classes)的工作,1983年該語言被正式命名為C++,主要意圖是表明C++ 是C的增強版,1985年釋出了第一個C++ 版本。
第一個版本的C++,因其面向對象的思想使得程式設計變得簡單,并且又保持了C語言的運作效率,在推出的一段時間内,得到了快速的發展,占據了程式設計語言界的半壁江山。從1985年到1998年,C++從最初的C with Classes新增了很多其他的特性,比如異常處理、模闆、标準模闆庫(STL)、運作時異常處理(RTTI)與名字空間(Namespace)等。
1998年,C++ 标準委員會統籌C++ 的所有特性,釋出了第一個C++ 的國際标準:C++ 98。
從1998年到2003年,C++ 标準從C++ 98疊代到C++ 03,期間C++ 擴增了很多額外的特性,比如以Boost MPL(Boost Metaprogramming Library)與Loki等為代表的模闆元程式設計庫的出現,讓開發者更加便捷的使用C++在編譯期的執行能力,即通過代碼編譯獲得計算結果,學術性的稱為模闆元程式設計。
到了2003年,C++ 标準委員會總結最新技術并釋出了C++ 03标準。
從2003年到2011年,也就是從C++ 03到C++ 11,期間C++ 引入了對象移動、右值引用、lamba表達式(函數式程式設計)、編譯時類型識别(auto)、别名模闆以及很多新型關鍵詞(如nullptr、decltype、constexpr)等現代程式設計語言常具備的能力,讓C++ 與時俱進,開發效率得到了很大的提升。這些新的特性随着C++ 11标準的釋出而被正式确立下來。
近年來,C++ 标準的變更周期縮短,由C++ 11到C++ 14以及最近的C++ 17都隻用了3年的時間。C++ 14引入了二進制文字常量、将類型推導從Lambda函數擴充到所有函數、變量模闆以及數字分位符等。C++ 14 是對C++ 11的重要補充和優化,是C++ 發展曆程中的一個小型版本,雖然新增的内容較少,但是仍然為使用者“帶來了極大的友善”,為實作使C++ “對新手更為友好”這一目标作出努力。到了2017年,C++ 迎來了C++ 17标準。此次對C++ 的改進和擴增,讓C++ 變得更加容易接受和便于使用了。C++ 17引入了許多新的特性,比如類模闆參數推導、UTF-8文字常量、fold表達式、新類型以及新的庫函數等。
2. namespace(TODO)
C++ 标準程式庫涵蓋範圍相當大,提供了大量功能,正因為這樣,标準庫中class名稱和函數名與第三方提供的class和函數名沖突的可能性變大。為避免該沖突的發生,在标準化時特别引入了“名字空間的定義”,即namespace。将所有标準程式庫中的東西都放在了namespace std中。
但是這麼做同時有引來了一個新的問題。很多C++ 程式代碼依賴那些已經存在很多年的C++ “準”标準程式庫(C++遲遲未标準化才導緻這些情況的發生),例如iosteam.h,complex.h等等。
3. 用法差別
為了解決這個新出現的問題,标準化委員會決定設計一些新的頭檔案名,給那些穿上std外衣的元件所使用。把C++ 頭檔案的.h去掉,于是就有前面出現的iostream,同樣C的頭檔案也做了相同的處理,同時在前面加上了一個字母c,以表示是C的頭檔案(感覺上有種種族歧視的感覺)。
非标準 | 标準 | |
---|---|---|
C輸入輸出标準庫 | #include<stdio.h> | #include<cstdio> |
同時标準化委員會聲明就有的C++頭檔案将不再列于被支援的名單之中了,而舊有的C頭檔案為了滿足“對C的相容性”這個古老契約,仍然将繼續存活下去。
當代碼中用<iostream.h>時,這時頭檔案是C語言格式的,尚未出現namespace,輸出可直接引用。
cout<<x;
//<iostream.h>繼承C語言的标準庫檔案,未引入名字空間定義,是以可直接使用。
當代碼中引入<iostream>時,為标準輸入輸出流,包含在std命名空間内,輸出需要引用std命名空間。
std::cout<<x;
如果還是按原來的方法就會有錯。
使用<iostream>時,引入std::有以下方法:
- 使用using編譯指令引用整個命名空間。
using namespace std; //all names available
cout << x ;
這個using編譯指令使std這個命名空間中的所有名稱都可用,這是一種懶惰的做法,在大型項目中有潛在問題。是以更好的做法是按需引用.
- 隻列出所需的名稱。
using std :: cout; //make cout available
cout << x ;
3.基本引用
std::cout << x;
下面以完整程式,使用cout和endl舉例說明。
3.1 iostream.h 的使用
iostream.h中函數都是全局的,使用的方法同C相同。
//example.cpp
#include <iostream.h>
int main(void)
{
cout<<"Hello World"<<endl;
return 0;
}
上面的例子examplec.pp使用下面普通的方法編譯,甚至提示找不到iostream.h這個頭檔案
# g++ example.cpp
error: iostream.h: No such file or directory
error: ‘cout’ was not declared in this scope
error: ‘endl’ was not declared in this scope
沒有頭檔案怎麼辦呢?這需要安裝相容包,在我的64位系統安裝了下面2個包(還有其他包)
# yum install compat-gcc*
Install compat-gcc-34.x86_64
Install compat-gcc-34-c++.x86_64
記住上面包的名字中的數字34,在不同系統中可能是不同的,繼續編譯,注意這次使用的不是g而是g34.
# g++34example.cpp
In file included from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/backward/iostream.h:31, from main.cpp:8: /usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
這次編譯有一個很長的warning,意思就是建議使用标準頭檔案不使用非标準頭檔案。
非要使用非标準頭檔案的時候可以通過添加編譯選項-Wno-deprecated 來取消這個warning
# g++34 -g example.cpp -Wno-deprecated
OK,到此就編譯成功了。
3.2 iostream 的使用
主要有3種方法,沒有最優,隻有最合适
方法1,适用于使用函數個數少,函數使用次數少 的情況
//example1.cpp
#include <iostream>
int main(void)
{
std::cout<<"Hello World"<<std::endl; //方法1
return 0;
}
方法2,适用于使用函數個數少,函數使用次數較多 的情況
//example2.cpp
#include <iostream>
using std::cout; //方法2
using std::endl; //方法2
int main(void)
{
cout<<"Hello World"<<endl;
return 0;
}
方法3,适用于使用函數個數和函數次數較多 的情況
//example3.cpp
#include <iostream>
using namespace std; //方法3
int main(void)
{
cout<<"Hello World"<<endl;
return 0;
}
3.3 建議
最好使用标準頭檔案。
iostream是現在C++ 中規定的标準,目的在于使C++ 代碼用于移植和混合嵌入時不受擴充名.h的限制,避免因為.h而造成的額外的處理和修改。
iostream包含的基本功能和對應的舊頭檔案相同,但頭檔案的内容在名字空間std中(在标準化的過程中,庫中有些部分的細節被修改了,是以舊頭檔案和新頭檔案中的實體不一定完全對應)。
一般情況下應該用這個頭檔案,而iostream.h則是老式的,以後有可能被淘汰。
4. 其他參考
string.h c标準庫提供的字元串函數
string.h是C語言裡面關于字元數組的函數定義的頭檔案,常用函數有strlen、strcmp、strcpy等等,更詳細的資訊可以自己檢視(面向過程)。
cstring c标準庫提供的字元串函數
CString常用于MFC程式設計中,是屬于MFC的類,如從對話框中利用GetWindowText得到的字元串就是CString類型,CString定義在afx.h頭檔案中。CString為Visual C++ 中最常用的字元串類,繼承自CSimpleStringT類,主要應用在MFC和ATL程式設計中,是以使用CString時要包含afx.h檔案。
string c++标準庫提供的string類
string是C++ 标準庫(STL)中的類型,它是定義的一個類,定義在string頭檔案中。裡面包含了對字元串的各種常用操作,它較char*的優勢是内容可以動态拓展,以及對字元串操作的友善快捷,用+号進行字元串的連接配接是最常用的操作。
參考資料
- <iostream> 和 <iostream.h>的差別 及 Linux下編譯iostream.h的方法
- C++ 發展概述
- C++ 的發展過程和曆史
- C++ 元程式設計和Boost程式設計庫 (C++ Metaprogramming and Boost MPL )上部
- #include<string.h>、#include<cstring>與#include<string>的差別
- 名字空間-維基百科
- C++ 名字空間/C++ 命名空間