《C++ Primer 5th》笔记(1 / 19):C++基础
文章目錄
- 編寫一個簡單的C++程序
- 編譯、運行程序
- 初識輸入輸出
- 注釋簡介
- 控制流
- while語句
- for語句
- 讀取數量不定的輸入數據
- if語句
- 類簡介
- Sales_item類
- 初識成員函數
- 書店程序
- 一些術語
編寫一個簡單的C++程序
每個C++程序都包含一個或多個函數(function),其中一個必須命名為main。操作系統通過調用main來運行C++程序。
int main() {return 0; }一個函數的定義包含四部分:
雖然main函數在某種程度上比較特殊,但其定義與其他函數是一樣的。main函數的返回類型必須為 int,即整數類型。int類型是一種內置類型(built-intype),即語言自身定義的類型。
函數定義的最后一部分是函數體,它是一個以左花括號(curly brace)開始,以右花括號結束的語句塊(block of statements)。
這個語句塊中唯一的一條語句是 return,它結束函數的執行。在本例中,return還會向調用者返回一個值。當return 語句包括一個值時,此返回值的類型必須與函數的返回類型相容。在本例中,main的返回類型是int,而返回值0的確是一個int類型的值。
注意,語句以;號結束,不能省略。
在大多數系統中,main的返回值被用來指示狀態。返回值0表明成功,非0的返回值的含義由系統定義,通常用來指出錯誤類型。
重要概念:類型
一種類型(Type)不僅定義了數據元素的內容,還定義了這類數據上可以進行的運算。
程序所處理的數據都保存在變量中,而每個變量都有自己的類型。如果一個名為v的變量的類型為T,我們通常說“v是一個T類型變量”。
編譯、運行程序
編寫好程序后,要編譯它。如何編譯程序依賴于你使用的操作系統和編譯器。
很多PC機上的編譯器都具備集成開發環境(Integrated Developed Environment,IDE),將編譯器與其他程序創建和分析工具包裝在一起。在開發大型程序時,這類集成環境是非常有用的工具。
大部分編譯器,包括集成IDE的編譯器,都會提供一個命令行界面。除非你已經了解IDE,否則你會覺得借助命令行界面開始學習C++還是很容易的。這種學習方式的好處是,可以先將精力集中于C++語言本身(而不是一些開發工具),而且,一旦你掌握了語言,IDE通常是很容易學習的。(先學語言,后學IDE)
程序源文件命名約定
無論你使用命令行界面或者IDE,大多數編譯器都要求程序源碼存儲在一個或多個文件中。程序文件通常被稱為源文件(source file)。在大多數系統中,源文件的名字以一個后綴為結尾。后綴告訴系統這個文件是一個C++程序。常見的后綴命名有.cpp、.c。
從命令行運行編譯器
如Linux版的:
gcc prog1.cc g++ -o prog1 prog1.cc初識輸入輸出
C++語言并未定義任何輸入輸出(IO)語句,取而代之,包含了一個全面的標準庫(standard library)來提供IO機制(以及很多其他設施)。
接下來很多示例都使用了iostream庫。
iostream庫包含兩個基礎類型:
一個流就是一個字符序列,是從IO設備讀出或寫入IO設備的。
術語“流”(stream)想要表達的是,隨著時間的推移,字符是順序生成或消耗的。
標準輸入輸出對象
標準庫定義了4個IO對象:
系統通常將程序所運行的窗口與這些對象關聯起來。因此,
- 當我們讀取cin,數據將從程序正在運行的窗口讀入,
- 當我們向cout、cerr和clog寫入數據時,將會寫到同一個窗口。
一個使用IO庫的程序
通過使用IO 庫,擴展main程序,使之能提示用戶輸入兩個數,然后輸出它們的和:
#include <iostream> int main() {std::cout << "Enter two numbers:" << std::endl;int v1 = 0, v2 = 0;std::cin >> v1 >> v2;std::cout << "The sum of " << v1 << " and " << v2<< " is " << v1 + v2 << std::endl;return 0; }輸出結果:
Enter two numbers: 1 2 The sum of 1 and 2 is 3Process returned 0 (0x0) execution time : 3.566 s Press any key to continue.接下來是上一源程序的詳細解釋:
程序的第一行
#include <iostream>告訴編譯器我們想要使用iostream庫。尖括號中的名字(本例中是 iostream)指出了一個頭文件(header)。每個使用標準庫設施的程序都必須包含相關的頭文件。
#include指令和頭文件的名字必須寫在同一行中。通常情況下,#include 指令必須出現在所有函數之外。我們一般將一個程序的所有#include指令都放在源文件的開始位置。
一、向流寫入數據
main 的函數體的第一條語句執行了一個表達式(expression)。在C++中,一個表達式產生一個計算結果,它由一個或多個運算對象和(通常是)一個運算符組成。這條語句中的表達式使用了**輸出運算符(<<)**在標準輸出上打印消息:
std::cout <<"Enter two numbers: " <<std::endl;<<運算符接受兩個運算對象:左側的運算對象必須是一個ostream對象,右側的運算對象是要打印的值。此運算符將給定的值寫到給定的ostream對象中。輸出運算符的計算結果就是其左側運算對象。即,計算結果就是我們寫入給定值的那個ostream對象。
我們的輸出語句使用了兩次<<運算符。因為此運算符返回其左側的運算對象,因此第一個運算符的結果成為了第二個運算符的左側運算對象。這樣,我們就可以將輸出請求連接起來。因此,我們的表達式等價于
(std::cout << "Enter two numbers: ") << std::endl;鏈中每個運算符的左側運算對象都是相同的,在本例中是 std::cout。我們也可以用兩條語句生成相同的輸出:
std::cout << "Enter two numbers : "; std::cout << std::endl;輸出運算符給用戶打印一條消息。這個消息是一個字符串字面值常量(string literal),是用一對雙引號包圍的字符序列。在雙引號之間的文本被打印到標準輸出。
運算符打印 endl,這是一個被稱為操縱符(manipulator)的特殊值。**寫入endl的效果是結束當前行,并將與設備關聯的緩沖區(buffer)中的內容刷到設備中。**緩沖刷新操作可以保證到目前為止程序所產生的所有輸出都真正寫入輸出流中,而不是僅停留在內存中等待寫入流。
二、使用標準庫中的名字
這個程序使用了std::cout和std::endl,而不是直接的cout和endl。
前綴std::指出名字cout和 endl是定義在名為std的命名空間(namespace)中的。**命名空間可以幫助我們避免不經意的名字定義沖突,以及使用庫中相同名字導致的沖突。**標準庫定義的所有名字都在命名空間std中。(這好似我們談到黃埔區,是指上海市的黃埔區,還是廣州市的呢?為了避免誤解,需要在黃埔區這一詞前加上海市或廣州市來區別)。
通過命名空間使用標準庫有一個副作用:當使用標準庫中的一個名字時,必須顯式說明我們想使用來自命名空間std中的名字。例如,需要寫出std: :cout,通過使用作用域運算符(::)來指出我們想使用定義在命名空間std中的名字cout。
如果你一個程序,只使用std這單一命名空間,重復std::會讓程序顯得不那么優雅,將來會回給出一個更簡單的訪問標準庫中名字的方法。(拭目以待)
三、從流讀取數據
在提示用戶輸入數據之后,接下來希望讀入用戶的輸入。
首先定義兩個名為 v1和v2的變量(variable)來保存輸入:
int v1 = 0,v2 = 0;我們將這兩個變量定義為int類型,int是一種內置類型,用來表示整數。還將它們初始化(initialize)為0。初始化一個變量,就是在變量創建的同時為它賦予一個值。
下一條語句是
std::cin >> v1 >> v2 ;它讀入輸入數據。輸入運算符(>>)與輸出運算符類似,它接受一個istream作為其左側運算對象,接受一個對象作為其右側運算對象。它從給定的istream讀入數據,并存入給定對象中。與輸出運算符類似,輸入運算符返回其左側運算對象作為其計算結果。因此,此表達式等價于
(std::cin >> v1) >> v2;由于此運算符返回其左側運算對象,因此我們可以將一系列輸入請求合并到單一語句中。本例中的輸入操作從std: :cin讀入兩個值,并將第一個值存入v1,將第二個值存入v2。換句話說,它與下面兩條語句的執行結果是一樣的
std::cin >> v1; std::cin >> v2;四、完成程序
剩下的就是打印計算結果了:
std::cout << "The sum of " << v1 << " and " << v2 << " is " << vl + v2 << std::endl;這條語句將每個運算對象打印在標準輸出上。(雖然有點長)
本例一個有意思的地方在于,運算對象并不都是相同類型的值。某些運算對象是字符串字面值常量,例如"The sum of "。其他運算對象則是int值,如v1、v2以及算術表達式v1+v2的計算結果。標準庫定義了不同版本的輸入輸出運算符,來處理這些不同類型的運算對象。(類比Java的對象toString())。
注釋簡介
注釋可以幫助閱碼者理解程序。注釋通常用于概述算法,確定變量的用途,或者解釋晦澀難懂的代碼段。編譯器會忽略注釋,因此注釋對程序的行為或性能不會有任何影響。
雖然編譯器會忽略注釋,但讀者并不會。即使系統文檔的其他部分已經過時,程序員也傾向于相信注釋的內容是正確可信的。因此,錯誤的注釋比完全沒有注釋更糟糕,因為它會誤導閱碼者。因此,當你修改代碼時,切記注釋也要修改。
C++有兩種注釋:
注釋另有一個用法:你調試代碼時,一段代碼暫時不能移除且又不想主程序執行它,此時你可以注釋掉這一段代碼。
控制流
程序控制流主要有三種:
while語句
while語句反復執行一段代碼,直至給定條件為假為止。
用while語句編寫一段程序,求1到10這10個數之和:
#include <iostream> int main() {int sum = 0, val = 1;// keep executing the while as long as val is less than or equal to 10while (val <= 10) {sum += val;// assigns sum + val to sum++val;// add 1 to val}std::cout << "Sum of 1 to 10 inclusive is "<< sum << std::endl;return 0; }輸出結果:
Sum of 1 to 10 inclusive is 55Process returned 0 (0x0) execution time : 0.012 s Press any key to continue.while語句的形式為:
while (condition)statementwhile 語句的執行過程是交替地檢測condition條件和執行關聯的語句statement,直至condition為假時停止。所謂條件(condition)就是一個產生真或假的結果的表達式。只要condition為真,statement 就會被執行。當執行完statement,會再次檢測condition。如果condition仍為真,statement再次被執行。while 語句持續地交替檢測condition和執行statement,直至condition為假為止。
上面程序相關專有名詞
for語句
在我們的while循環例子中,使用了變量val來控制循環執行次數。我們在循環條件中檢測val的值,在 while循環體中將val遞增。
這種在循環條件中檢測變量、在循環體中遞增變量的模式使用非常頻繁,以至于C++語言專門定義了第二種循環語句—for語句,來簡化符合這種模式的語句。
可以用for語句來重寫從1加到10的程序:
#include <iostream> int main() {int sum = 0;// sum values from 1 through 10 inclusivefor (int val = 1; val <= 10; ++val)sum += val;// equivalent to sum = sum + valstd::cout << "Sum of 1 to 10 inclusive is "<< sum << std::endl;return 0; }每個 for語句都包含兩部分:循環頭和循環體。
循環頭控制循環體的執行次數,它由三部分組成:
讀取數量不定的輸入數據
#include <iostream> int main() {int sum = 0, value = 0;// read until end-of-file, calculating a running total of all values readwhile (std::cin >> value)sum += value;// equivalent to sum = sum + valuestd::cout << "Sum is: " << sum << std::endl;return 0; }輸出結果:
3 4 5 6 7 8 9 10^Z Sum is: 52Process returned 0 (0x0) execution time : 16.531 s Press any key to continue.當我們使用一個istream對象作為條件時,其效果是檢測流的狀態。如果流是有效的,即流未遇到錯誤,那么檢測成功。當遇到文件結束符(end-of-file),或遇到一個無效輸入時(例如讀入的值不是一個整數),istream對象的狀態會變為無效。處于無效狀態的istream對象會使條件變為假。
從鍵盤輸入文件結束符:
再談編譯:
編譯器的一部分工作是尋找程序文本中的錯誤。編譯器沒有能力檢查一個程序是否按照其作者的意圖工作,但可以檢查形式(form)上的錯誤。下面列出了一些最常見的編譯器可以檢查出的錯誤:
錯誤信息通常包含一個行號和一條簡短描述,描述了編譯器認為的我們所犯的錯誤。
兩個好習慣:
if語句
#include <iostream> int main() {// currVal is the number we're counting; we'll read new values into valint currVal = 0, val = 0;// read first number and ensure that we have data to processif (std::cin >> currVal) {int cnt = 1;// store the count for the current value we're processingwhile (std::cin >> val) {// read the remaining numbersif (val == currVal) // if the values are the same++cnt; // add 1 to cntelse { // otherwise, print the count for the previous valuestd::cout << currVal << " occurs "<< cnt << " times" << std::endl;currVal = val;// remember the new valuecnt = 1;// reset the counter}}// while loop ends here// remember to print the count for the last value in the filestd::cout << currVal << " occurs "<< cnt << " times" << std::endl;}// outermost if statement ends herereturn 0; }輸出結果:
41 41 41 41 41 14 41 14^Z 41 occurs 5 times 14 occurs 1 times 41 occurs 1 times 14 occurs 1 timesProcess returned 0 (0x0) execution time : 19.803 s Press any key to continue.注意,相等運算符==與賦值運算符=的區別。
關鍵概念:C++程序的縮進和格式
C++程序很大程度上是格式自由的,也就是說,我們在哪里放置花括號、縮進、注釋以及換行符通常不會影響程序的語義。
雖然很大程度上可以按照自己的意愿自由地設定程序的格式,但我們所做的選擇會影響程序的可讀性。例如,我們可以將整個main函數寫在很長的單行內,雖然這樣是合乎語法的,但會非常難讀。
關于C/C++的正確格式的辯論是無休止的。我們的信條是,不存在唯一正確的風格,但保持一致性是非常重要的。
我們要牢記一件重要的事情:其他可能的程序格式總是存在的,當你要選擇一種格式風格時,思考一下它會對程序的可讀性和易理解性有什么影響,而一旦選擇了一種風格,就要堅持使用。
類簡介
在C++中,我們通過定義一個類(class)來定義自己的數據結構(data structure)。一個類定義了一個類型,以及與其關聯的一組操作。類機制是C++最重要的特性之一。
實際上,C++最初的一個設計焦點就是能定義使用上像內置類型一樣自然的類類型(class type)。
為了使用標準庫設施,我們必須包含相關的頭文件。類似的,我們也需要使用頭文件來訪問為自己的應用程序所定義的類。
習慣上,頭文件根據其中定義的類的名字來命名。我們通常使用.h作為頭文件的后綴,但也有一些程序員習慣.H、.hpp 或.hxx。標準庫頭文件通常不帶后綴。編譯器一般不關心頭文件名的形式,但有的IDE對此有特定要求。
Sales_item.h一覽:
/* This file defines the Sales_item class used in chapter 1.* The code used in this file will be explained in* Chapter 7 (Classes) and Chapter 14 (Overloaded Operators)* Readers shouldn't try to understand the code in this file* until they have read those chapters. */#ifndef SALESITEM_H // we're here only if SALESITEM_H has not yet been defined #define SALESITEM_H// Definition of Sales_item class and related functions goes here #include <iostream> #include <string>class Sales_item { // these declarations are explained section 7.2.1, p. 270 // and in chapter 14, pages 557, 558, 561 friend std::istream& operator>>(std::istream&, Sales_item&); friend std::ostream& operator<<(std::ostream&, const Sales_item&); friend bool operator<(const Sales_item&, const Sales_item&); friend bool operator==(const Sales_item&, const Sales_item&); public:// constructors are explained in section 7.1.4, pages 262 - 265// default constructor needed to initialize members of built-in typeSales_item() = default;Sales_item(const std::string &book): bookNo(book) { }Sales_item(std::istream &is) { is >> *this; } public:// operations on Sales_item objects// member binary operator: left-hand operand bound to implicit this pointerSales_item& operator+=(const Sales_item&);// operations on Sales_item objectsstd::string isbn() const { return bookNo; }double avg_price() const; // private members as before private:std::string bookNo; // implicitly initialized to the empty stringunsigned units_sold = 0; // explicitly initializeddouble revenue = 0.0; };// used in chapter 10 inline bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs) { return lhs.isbn() == rhs.isbn(); }// nonmember binary operator: must declare a parameter for each operand Sales_item operator+(const Sales_item&, const Sales_item&);inline bool operator==(const Sales_item &lhs, const Sales_item &rhs) {// must be made a friend of Sales_itemreturn lhs.units_sold == rhs.units_sold &&lhs.revenue == rhs.revenue &&lhs.isbn() == rhs.isbn(); }inline bool operator!=(const Sales_item &lhs, const Sales_item &rhs) {return !(lhs == rhs); // != defined in terms of operator== }// assumes that both objects refer to the same ISBN Sales_item& Sales_item::operator+=(const Sales_item& rhs) {units_sold += rhs.units_sold; revenue += rhs.revenue; return *this; }// assumes that both objects refer to the same ISBN Sales_item operator+(const Sales_item& lhs, const Sales_item& rhs) {Sales_item ret(lhs); // copy (|lhs|) into a local object that we'll returnret += rhs; // add in the contents of (|rhs|) return ret; // return (|ret|) by value }std::istream& operator>>(std::istream& in, Sales_item& s) {double price;in >> s.bookNo >> s.units_sold >> price;// check that the inputs succeededif (in)s.revenue = s.units_sold * price;else s = Sales_item(); // input failed: reset object to default statereturn in; }std::ostream& operator<<(std::ostream& out, const Sales_item& s) {out << s.isbn() << " " << s.units_sold << " "<< s.revenue << " " << s.avg_price();return out; }double Sales_item::avg_price() const {if (units_sold) return revenue/units_sold; else return 0; } #endifSales_item類
類的作用是表示一本書的總銷售額、售出冊數和平均售價。
現在可以不關心這些數據如何存儲、如何計算。為了使用一個類,我們不必關心它是如何實現的,只需知道類對象可以執行什么操作。
每個類實際上都定義了一個新的類型,其類型名就是類名。因此,我們的sales_item類定義了一個名為sales_item的類型。與內置類型一樣,我們可以定義類類型的變量。當我們寫下如下語句
Sales_item sales_item;是想表達item是一個sales_item類型的對象。我們通常將“一個sales_item類型的對象”簡單說成“一個sales_item對象”,或更簡單的“一個sales_item”。
除了可以定義sales_item類型的變量之外,我們還可以:
-
調用一個名為isbn的函數從一個sales_item對象中提取工ISBN書號。
-
用輸入運算符(>>)和輸出運算符(<<)讀、寫sales_item類型的對象。
-
用賦值運算符(=)將一個sales_item對象的值賦予另一個sales_item對象。
-
用加法運算符(+)將兩個sales_item對象相加。兩個對象必須表示同一本書(相同的ISBN)。加法結果是一個新的sales_item對象,其ISBN與兩個運算對象相同,而其總銷售額和售出冊數則是兩個運算對象的對應值之和。
-
使用復合賦值運算符(+=)將一個sales_item對象加到另一個對象上。
關鍵概念:類定義了行為
當你讀這些程序時,一件要牢記的重要事情是,類Sales_item的作者定義了類對象可以執行的所有動作。即,Sales_item類定義了創建一個 Sales_item對象時會發生什么事情,以及對Sales_item對象進行賦值、加法或輸入輸出運算時會發生什么事情。
一、讀寫Sales_item
#include <iostream>//標準頭文件用<> #include "Sales_item.h"//用自定義的頭文件 int main() {Sales_item book;// read ISBN, number of copies sold, and sales pricestd::cin >> book;// write ISBN, number of copies sold, total revenue, and average pricestd::cout << book << std::endl;return 0; }輸出結果:
0-201-70353-X 4 24.99^Z 0-201-70353-X 4 99.96 24.99Process returned 0 (0x0) execution time : 28.364 s Press any key to continue.這里涉及運算符重載,重點回看頭文件Sales_item.h:
std::istream& operator>>(std::istream& in, Sales_item& s) {double price;in >> s.bookNo >> s.units_sold >> price;// check that the inputs succeededif (in)s.revenue = s.units_sold * price;else s = Sales_item(); // input failed: reset object to default statereturn in; }std::ostream& operator<<(std::ostream& out, const Sales_item& s) {out << s.isbn() << " " << s.units_sold << " "<< s.revenue << " " << s.avg_price();return out; }二、Sales_item對象的加法
#include <iostream> #include "Sales_item.h" int main() {Sales_item item1, item2;std::cin >> item1 >> item2;// read a pair of transactionsstd::cout << item1 + item2 << std::endl;// print their sumreturn 0; }輸出結果:
0-201-78345-X 3 20.00 0-201-78345-X 2 25.00 0-201-78345-X 5 110 22Process returned 0 (0x0) execution time : 70.536 s Press any key to continue.這里也運算符重載,重點回看頭文件Sales_item.h:
// assumes that both objects refer to the same ISBN Sales_item& Sales_item::operator+=(const Sales_item& rhs) {units_sold += rhs.units_sold; revenue += rhs.revenue; return *this; }// assumes that both objects refer to the same ISBN Sales_item operator+(const Sales_item& lhs, const Sales_item& rhs) {Sales_item ret(lhs); // copy (|lhs|) into a local object that we'll returnret += rhs; // add in the contents of (|rhs|) return ret; // return (|ret|) by value }使用文件重定向
當你測試程序時,反復從鍵盤敲入這些銷售記錄作為程序的輸入,是非常乏味的。大多數操作系統支持文件重定向,這種機制允許我們將標準輸入和標準輸出與命名文件關聯起來:
$ addItems <infile >outfile假定$是操作系統提示符,我們的加法程序已經編譯為名為addItems.exe的可執行文件(在 UNIX中是addItems),則上述命令會從一個名為infile的文件讀取銷售記錄,并將輸出結果寫入到一個名為outfile的文件中,兩個文件都位于當前目錄中。
初識成員函數
#include <iostream> #include "Sales_item.h" int main() {Sales_item item1, item2;std::cin >> item1 >> item2;// first check that item1 and item2 represent the same bookif (item1.isbn() == item2.isbn()) {std::cout << item1 + item2 << std::endl;return 0;// indicate success} else {std::cerr << "Data must refer to same ISBN"<< std::endl;return -1;// indicate failure} }什么是成員函數?
上一程序中的item1.isbn()
調用名為isbn 的成員函數(member function)。成員函數是定義為類的一部分的函數,有時也被稱為方法(method)。
我們通常以一個類對象的名義來調用成員函數。例如,上面相等表達式左側運算對象的第一部分
item1.isbn()。
使用點運算符(.)來表達我們需要“名為item1的對象的isbn成員”。點運算符只能用于類類型的對象。其左側運算對象必須是一個類類型的對象,右側運算對象必須是該類型的一個成員名,運算結果為右側運算對象指定的成員。
當用點運算符訪問一個成員函數時,通常我們是想(效果也確實是)調用該函數。我們使用調用運算符(())來調用一個函數。調用運算符是一對圓括號,里面放置實參( argument)列表(可能為空)。成員函數isbn并不接受參數。因此
iteml.isbn()調用名為item1的對象的成員函數isbn,此函數返回item1中保存的ISBN書號。
NOTE: .不是調用運算符,而是()。
書店程序
現在我們已經準備好完成書店程序了。我們需要從一個文件中讀取銷售記錄,生成每本書的銷售報告,顯示售出冊數、總銷售額和平均售價。我們假定每個ISBN書號的所有銷售記錄在文件中是聚在一起保存的。
我們的程序會將每個ISBN的所有數據合并起來,存入名為 total的變量中。我們使用另一個名為trans 的變量保存讀取的每條銷售記錄。如果trans和total指向相同的ISBN,我們會更新total的值。否則,我們會打印 total的值,并將其重置為剛剛讀取的數據(trans):
#include <iostream> #include "Sales_item.h" int main() {Sales_item total;// variable to hold data for the next transaction// read the first transaction and ensure that there are data to processif (std::cin >> total) {Sales_item trans;// variable to hold the running sum// read and process the remaining transactionswhile (std::cin >> trans) {// if we're still processing the same bookif (total.isbn() == trans.isbn())total += trans;// update the running total else {// print results for the previous bookstd::cout << total << std::endl;total = trans; // total now refers to the next book}}std::cout << total << std::endl; // print the last transaction} else {// no input! warn the userstd::cerr << "No data?!" << std::endl;return -1;// indicate failure}return 0; }一些術語
緩沖區(buffer)一個存儲區域,用于保存數據。IO設施通常將輸入(或輸出)數據保存在一個緩沖區中,讀寫緩沖區的動作與程序中的動作是無關的(read or write the buffer independently from actions in the program)(Note:不是buffer.read()或buffer.write(),而是cin>>xx,cout <<xx,我是這樣理解的,不知道對嗎?)。我們可以顯式地刷新輸出緩沖,以便強制將緩沖區中的數據寫入輸出設備。默認情況下,讀cin會刷新cout;程序非正常終止時也會刷新cout。
類(class)一種用于定義自己的數據結構及其相關操作的機制。類是C++中最基本的特性之一。標準庫類型中,如istream和 ostream都是類。(Facility for defining our own data structures together with associated operations. The class is one of the most fundamental features in C+ + . Library types, such as istream and ostream, are classes. )
類型(Type)不僅定義了數據元素的內容,還定義了這類數據上可以進行的運算。(A type
defines both the contents of a data element and the operations that are possible on those data. )程序所處理的數據都保存在變量中,而每個變量都有自己的類型。(The data our programs manipulate are stored in variables and every variable has a type. )如果一個名為v的變量的類型為T,我們通常說“v是一個T類型變量”。(When the type of a variable named v is T, we often say
that “v is a T.” )
類類型(class type)類定義的類型。類名即為類型名。(A type defined by a class. The name of the type is the class name. )(Note:個人理解class和type是一對孿生子。)
花括號(curly brace)。
數據結構(data structure)數據及其上所允許的操作的一種邏輯組合。(A logical grouping of data and operations on that data. )
初始化(initialize)在一個對象創建的時候賦予它一個值。
未初始化的變量(uninitialized variable)未賦予初值的變量。類類型的變量如果未指定初值,則按類定義指定的方式進行初始化。定義在函數內部的內置類型變量默認是不初始化的,除非有顯式的初始化語句。試圖使用一個未初始化變量的值是錯誤的。未初始化變量是bug 的常見成因。
操縱符(manipulator)對象,如std::endl,在讀寫流的時候用來“操縱”流本身。
總結
以上是生活随笔為你收集整理的《C++ Primer 5th》笔记(1 / 19):C++基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kaggle(04)---avazu_c
- 下一篇: 《Python Cookbook 3rd