今天是第一次筆記,說實話拖了很久,因爲剛剛到家,沒有穩定的學習環境,各種事情分心,就連C++Primer 的第一章都看了那麼長時間,直到今天才有時間來寫筆記。每次看書都能有點收穫,蠻欣慰的。
若存在錯誤 請指正 萬分感謝
1.1 簡介:
1.每個C++程序包含一個或多個functions,其中一定有main函數,此函數是操作系統執行程序的入口。
2.函數定義幾個要素:return type; function name; parameter list; function body.
3.main function‘s return type must be int and void is banned.
4.函數體以左花括號(curly brace)開始,以右花括號的語句塊結束(block of statements)
5.main 函數的返回值來指示函數的執行狀態,一般0表示執行成功,非0值的具體含義由系統定義,通常用了表示錯誤的類型。
6.類型概念:類型是程序設計的最基本概念,類型既定義了數據元素內容,也定義了其上可以進行的操作。比如定義一個int 型的變量,那麼同時也定義了其上可以進行的操作,比如加法等。其實和類的概念很相像。程序所處理的數據都保存在變量中,每個變量都有自己的類型。若一個名爲v的變量類型爲T,等價於v具有類型T,也等價於v是T類型變量。
1.2 相關:
1.Integrated Development Environment IDE。
2.程序源文件名約定:通常是 .cpp;.c;.cxx;.cc;.cp
3.從命令行運行編譯器:$ CC prog1.cc其中CC是編譯器的名字 ,prog1.cc 是源文件。
執行後生成一個可執行文件:如prog1.exe
獲取返回值:$ echo %ERRORLEVEL%
1.3初始化輸入輸出:
1.C++爲定義IO語句,而且 用標準庫提供IO機智。
2.流的理解:一個流就是一個字符序列,是從IO設備讀取或寫入IO設備的。術語流想表達的是隨着時間的推移,字符是順序生成或消耗的。
3.四個對象:cin,cout,cerr,clog.四個對象。標準輸入,標準輸出,標準錯誤。
4.這四個對象通常和程序所運行的窗口關聯起來,因爲當我們讀取cin時,將從程序運行的窗口讀入當我們向cout/cerr/clog寫數據的時候,也會寫到同一窗口。
5.向流寫入數據:C++中一個表達式產生一個計算結果,它是 由一個或者對歌運算對象和一個或者多個運算符構成的,比如使用了<<運算符,:
std::cout<<"Enter two numbers"<<std::endl;
這個地方的輸出運算符<<需要兩個運算對象,左邊的運算對象是一個ostream 對象,右邊是一個常量字符串。此運算符將給定的值寫到cout對象中,此表達式的計算結果是ostream對象。
爲什麼可以連續使用<<運算符呢?因爲一個輸出運算符的結果是ostream對象,所以可以連用,那麼上面的語句等價於:
(std::cout<<"Enter two numbers")<<std::endl;//也等價於:std::cout<<"Enter two numbers";std::cout<<std::endl;
因爲cout對象是關聯到屏幕這個文件的,所以string literal被打印到屏幕上。
std::endl是操縱符(manipulator)功能:結束當前行,並且將與它關聯的設備的緩衝區刷新到設備中。緩衝刷新操作可以確保目前程序所產生的輸出都真正的寫入到流中,而不是僅僅停在內存中等待寫入。
6.程序調試經常添加打印語句,應該保持刷新流,否則程序崩潰,輸出還停留在buffer中,可能會錯誤推斷程序出錯的位置。
7.使用標準庫中名字,需要使用std+作用域運算符(::)
8.向流寫入數據:需要使用>>運算符。>>運算符類似輸出運算符,左運算對象是一個istream對象,右邊運算對象是需要操作的變量。>>運算符的連用操作類似<<輸出運算符。
9.解釋一個語句:std::cout<<"The sum of "<<v1<<" and "<<v2<<" is "
<<v1+v2<<std::endl;
這個地方的運算對象並不是同類型,但是爲何可以進行運算呢?你看上面既有整型,字符串,還要兩個整型數據的運算結果。但是仍然可以進行運算,原因就是重載了運算符,更多的內容後面會介紹。
1.3 註釋簡介:
1.單行註釋//
2.界定符註釋,注意不能嵌套。注意多行註釋的好風格:如
/*
*
*
*/
1.4 控制流語句:
程序是順序執行的,通過流程控制語句可以寫出各種跳轉語句。
1.5 while 語句:
while(condition) {statements} 執行流程:檢測條件,執行語句(快),再次檢測。如果條件爲假,跳出循環, 否則繼續執行。
1.6 for 語句:
上面那種在循環中檢測變量,在循環體中改變執行條件。C++中重新定義了一種循環語句,簡化上述模式。for語句的構造,循環頭,循環體。其中循環頭由三部分構成,initialization statement,condition,expression 執行的流程:執行初始化語句,條件檢測執行,執行循環體,執行循環頭的表達式,再次進行條件檢測。若條件不成立,跳出循環,順序執行循環後的語句。
1.7 讀取不定量的數據:
這個例子我感覺十分有意思,用一個變量卻做了多個變量的事情。
示例:
#include <iostream>
int main(){
int sum = 0, var = 0;
while (std::cin>>var){
sum += var;
}
std::cout << "The sum is " << sum << std::endl;
system("pause");
return 0;
}
這個例子和我一開始想的完全不一樣,這個程序一開始輸入所有要進行計算的數字,而不是我認爲的是輸入一次判讀一次。這個程序是一次性把所有的輸入都保存在緩衝區中,然後程序在檢測的時候進行讀取就可以了,而不是直接的要求用戶輸入。這個例子可以很好的加深對while語句的理解。在上述的例子中,檢測的到底是什麼呢?是var變量嘛?實際上根據<<運算符函數的運算結果可以知道返回的計算結果是一個對象。所以這個地方檢測的是對象,對象是個複雜的東西,至於一個cin對象裏面到底是啥,等我有機會翻開源碼一探究竟吧。對流的檢測實際上是檢測流的狀態,如果流是有效的,那麼程序可以繼續執行,如果流是無效的或者遇到文件結束符(eof),那麼條件爲假,退出循環。windows
中的文件結束符是 Ctrl + Z 鍵。UNIX系統中,是Ctrl D。
1.8 錯誤類型檢測:
編譯器無法檢測邏輯上的錯誤,只能檢測到一個錯誤的原則進行,然後進行編譯。不要根據編譯器的提示一下改正所以錯誤,因爲編譯器的報錯具有連帶性形式上的錯誤。一般分爲三類:
語法錯誤,類型錯誤,聲明錯誤。改錯的時候一般按照先改第,所以有的可能是連壞反應。
1.9 if 語句:
#include <iostream>
int main(){
int var = 0;
int CurVal = 0;//正在統計的數.
int cnt = 0;//計數器.
if (std::cin >> CurVal )//如果有需要處理的數字。
++cnt;
while (std::cin >> var){
if (var == CurVal)
++cnt;
else{
std::cout << CurVal << " occurs " << cnt << " times " << std::endl;
cnt = 1;
CurVal = var;
}
}
std::cout << CurVal << " occurs " << cnt << " times " << std::endl;
system("pause");
return 0;
}
真是一個很巧妙的例子,要多多揣摩這個模式以及涉及的思想。
1.10 類簡介:
類的是C++的特性,類定義了一個類型,以及其上可以進行的操作。C++最初的設計焦點就是自然地使用上像內置型一樣的類類型。在1.5節的例子中,我們進行類對象的加減,我們可以發現這個同內置類型的數據運算非常相似,只不過我們把運算對象由內置對象替換成類類型。而且這個例子中重新定義了和的概念。比如這個地方的ISBN相加就是無意義的。學習的過程就是推翻自己最初認知的過程。一開始建立的認知對學習有幫助,但是一方面也會阻礙自己對新事物的學習啊。
1.11調用運算符():
我希望自己能建立一種觀念,一切皆函數,一切皆運算。就像調用運算符,輸出輸入運算符這種,雖然表面看不出來,但是實際上當成函數理解纔是正確的。一開始我的理解實在是太狹隘了,以致我遲遲不能接受正確的觀念。
總結:
相關術語摘錄:
assignment :
抹去一個對象的當前值,用一個新值取代。這個地方就可以很好的解釋了賦值和初始化。賦值一定是在有一個值的基礎上進行的。
buffer :
緩衝區,分爲輸入輸出緩衝區。IO設施通常將輸入輸出的數據保存在一個緩衝區中。讀寫緩衝區的操作與程序是無關的,我們可以顯式的刷新緩衝區,以便強制的將緩衝區的內容刷新到設備中。默認情況下,cin會刷新cout,程序的非正常終止也會刷新cout.關於緩衝區的詳細知識可以看看計算機組成原理。
condition:
求值結果爲真假的表達式。
end_of_file :
文件結束符。系統特定的標識符,指出文件中無更多的數據了。
expression :
最小的計算單元。一個表達式包含一個或者多個運算對象,通常還包含一個或者多個運算符。表達式的求值會產生一個結果。
習題解答:
1.1
//命名約定 :.cpp
#include <iostream>
int main(){
return 0;
}
1.2
#include <iostream>
int main(){
return -1;//無提示。
}
1.3
#include <iostream>
int main(){
std::cout << "Hello," << " World." << std::endl;
return 0;
}
1.4
#include <iostream>
using namespace std;
int main(){
int var1 = 0, var2 = 0;
cout << "Enter two numbers ";
cin >> var1 >> var2;
cout << "The value of var1 multiply var2 is " << var1*var2 << endl;
system("pause");
return 0;
}
1.5
#include <iostream>
using namespace std;
int main(){
int var1 = 0, var2 = 0;
cout << "Enter two numbers ";
cin >> var1
>> var2;
cout << "The value of var1 multiply var2 is "
<< var1*var2
<< endl;
system("pause");
return 0;
}
1.6
//不合法
修改方案:std::cout<<"The sum of "<<v1
<<" and "<<v2
<<" is "<<v1+v2<<std::endl;
1.7
#include <iostream>
using namespace std;
int main(){
/*
*int var1 = 0,/* */ var2 = 0;
*cout << "Enter two numbers ";
*cin >> var1
>> var2;
*/
cout << "The value of var1 multiply var2 is "
<< var1*var2
<< endl;
system("pause");
return 0;
}
//錯誤信息:
error C2065: “var2”: 未聲明的標識符
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(6): error C2100: 非法的間接尋址
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(6): error C2088: “<<”: 對於 class 非法
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(7): error C2100: 非法的間接尋址
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(8): error C2065: “var1”: 未聲明的標識符
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(8): error C2065: “var2”: 未聲明的標識符
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(9): warning C4138: 在註釋外找到“*/”
1>d:\visual studio 2013 代碼\consoleapplication18\consoleapplication18\源.cpp(9): error C2059: 語法錯誤:“/”
1.8
#include <iostream>
int main(){
std::cout << "/*"; //正確
std::cout << "*/"; //正確
//std::cout <</* "*/" */; //錯誤
std::cout <</* "*/" /* "/*" */; //正確。
system("pause");
return 0;
}
1.9
#include <iostream>
int main(){
int sum = 0;
int var = 50;
while (var <= 100){
sum += var;
++var;
}
std::cout << "The sum from 50 to 100 is " << sum << std::endl;
system("pause");
return 0;
}
1.10
#include <iostream>
int main(){
int var =10;
while (var >=0){
std::cout << var << " ";
--var;
}
system("pause");
return 0;
}
1.11
#include <iostream>
int main(){
int begin_var = 0;
int end_var = 0;
std::cout << "Enter two numbers ";
std::cin >> begin_var >> end_var;
if (begin_var >end_var){
int temp = end_var;
end_var = begin_var;
begin_var=temp;
}
std::cout << "Print number from " << begin_var << " to " << end_var << std::endl;
while (end_var>=begin_var){
std::cout << begin_var++<< " ";
}
system("pause");
return 0;
}
1.12//求 -100 到 100 的和.
//結果是 0.
1.13
#include <iostream>
int main(){
int sum = 0;
for (int i = 50; i < 101; ++i){
sum += i;
}
std::cout << "The sum from 50 to 100 is " << sum << std::endl;
system("pause");
return 0;
}
#include <iostream>
int main(){
for (int i = 10; i >-1; --i){
std::cout << i << " ";
}
system("pause");
return 0;
}
#include <iostream>
int main(){
int begin_var = 0, end_var = 0;
std::cout << "Enter two numbers ";
std::cin >> begin_var >> end_var;
if (begin_var > end_var){
int temp = end_var;
end_var = begin_var;
begin_var = temp;
}
std::cout << "Print numbers from " << begin_var << " to " << end_var << std::endl;
for (int i =begin_var; i <=end_var; ++i){
std::cout << i << " ";
}
system("pause");
return 0;
}
1.14
for循環的有點在我看來就是簡潔吧。while循環感覺比較隨意,有點拖沓。
1.15
//略
1.16
#include <iostream>
int main(){
int var = 0;
int sum = 0;
std::cout << "Enter numbers or (Ctrl z to stop ) ";
while (std::cin >> var)//重點關注程序的執行流程,其次就是對對象的檢測是如何的。
sum += var;
std::cout << "The sum is " << sum << std::endl;
system("pause");
return 0;
}
一個cin>>var裏面究竟可以容納多少東西呢?正常情況下我們只可以讀取出一個一個出來,但是通過循環卻能緩衝中內容全部讀取出來,真的是顛覆了對輸入輸出的理解。
#include <iostream>
int main(){
int var = 0;
int sum = 0;
std::cout << "Enter numbers or (Ctrl z to stop ) ";
while (std::cin >> var)//重點關注程序的執行流程,其次就是對對象的檢測是如何的。
//sum += var;
std::cout << var << " ";
//std::cout << "The sum is " << sum << std::endl;
system("pause");
return 0;
}
這個簡單的例子卻是給我一個很好的啓示:是否可以抽象出一個模型出來?一個變量卻完成了多個變量的任務。
1.17
#include <iostream>
int main(){
int CurVal = 0, var = 0;
int cnt = 0;
std::cout << "Enter numbers or Ctrl to stop ";
if (std::cin >> CurVal){ //確保有數字可以處理。
++cnt;
while (std::cin >> var){
if (var == CurVal)
++cnt;
else{
std::cout << "The " << CurVal << " occurs "
<< cnt << " times " << std::endl;
cnt = 1;
CurVal = var;
}
}
}
std::cout << "The " << CurVal << " occurs "
<< cnt << " times " << std::endl;
}
//程序可以處理全部重複的輸入,也可以處理全部不同的輸入。1.18 略
1.19 參看1.10。
1.20
#include "Sales_item.h"
int main(){
Sales_item book;
std::cin >> book;
std::cout << book;
system("pause");
return 0;
}
1.21
#include "Sales_item.h"
int main(){
Sales_item book1,book2;
std::cin >> book1 >> book2;
std::cout << book1 + book2;
system("pause");
return 0;
}
1.22
#include "Sales_item.h"
int main(){
Sales_item book, sum;
std::cout << "Enter Sales_items or Press CTRL Z to stop ";
while (std::cin >> book)
sum += book;
std::cout << "The sum is " << sum << std::endl;
system("pause");
return 0;
}
//這個代碼是不是感覺很熟悉啊,我們真的可以像對待內置類型數據那樣處理類類型數據(自定義類型數據).
1.23
#include "Sales_item.h"
int main(){
Sales_item book, CurBook;
int cnt = 0;
if (std::cin >> CurBook){//有數據可以處理
++cnt;
while (std::cin >> book){
if (book.isbn()== CurBook.isbn())
++cnt;
else{
std::cout << "The " << CurBook.isbn()<< " occurs "
<< cnt << " times " << std::endl;
cnt = 1;
CurBook = book;
}
}
}
std::cout << "The " << CurBook.isbn()<< " occurs "
<< cnt << " times " << std::endl;
system("pause");
return 0;
}
1.24 參看1.23
1.25
#include "Sales_item.h"
int main(){
Sales_item total, Book;
if (std::cin >> total){//有數據可以處理
while (std::cin >> Book){
if (total.isbn() == Book.isbn())
total += Book;
else{
std::cout << "The " << total << std::endl;
total = Book;
}
}
}
std::cout << "The " << total<< std::endl;
system("pause");
return 0;
}
和上面的一樣,都是一些比較經典代碼,確實值得反覆揣摩。其中的設計思想姑且一次是無法把握的。
就拿while之前的那個if語句設計,的確是精巧至極。因爲if不是循環,所以你後面的輸入是算在while循環中的,也就是說對象裏面存儲的是不包含第一個輸入的。試想一下,給你一串數字,讓你統計出現的次數,怎麼辦?假設相同的數字是聚攏在一起的。我的第一反映是數組啊,多組數字,肯定是數組了。但是這個案例提供了一個更好的解決辦法。多揣摩經典代碼,多學習。