第四章內容: 1.錯誤函數訂正 p100頁 4.2.2 sprt(x)改為sqrt(x) 開根號函數
2.codeblock 和 dev 下運行結果的不同 查看以下代碼,實現的是字串反轉功能。
#include <iostream>#include <string>#include <cstdio>#include<cstring>using namespace std;void WordReversal( const char olist[],char newList[], int listSize){ for(int k=0,n=listSize - 1;k < listSize;k++,n--){ newList[n] = olist[k]; }}int main(){ const int SIZE = 3; char list1[SIZE]; cin >> list1; char newList[SIZE]; WordReversal(list1, newList, 3); cout << newList; return 0;}
codeblocks下的運行結果
dev下的運行結果
改變main函數中的代碼
int main(){ const int SIZE = 3; char newList[SIZE]; 把newList的聲明放到list1前面, char list1[SIZE]; cin >> list1; WordReversal(list1, newList, 3); cout << newList; return 0;}codeblocks下再次運行得到的結果。
分析,三次運行得到的結果都不一樣。原因是什麼。先分析代碼: 1.對於C串,需要一個終結字元'\0'作為結束標誌,定義長度為3的char數組,並且輸入長度為3的字串,會導致儲存'\0'的位置恰好已經越界。因此如果一個char數組長度為n,想要儲存c串的話,最多隻能儲存n-1長度的c串,因為至少要留一個位置儲存'\0' 2.WordReversal函數中實現了字串的反轉,但是並未把終止符'\0'複製到對應位置,導致輸出時在輸出123後依然會繼續輸出其它字元。 其它分析: 1. 首先肯定是編譯器不同導致產生的不同結果,如果邏輯正確的話,應該結果是一樣的,因此大家再次遇到這種問題,先檢查代碼邏輯問題。 2.為什麼codeblocks下會輸出321123. 可以猜測在分配記憶體是newList剛好在list1前,在newList沒有終止符的情況下,cout繼續輸出了lsit1中的內容,直到遇到輸入123時在list1後寫入的終止符才停止。而修改了main函數中的代碼,輸出一個桃心是因為newList的記憶體位址在List1後面,然後緊接著一個記憶體位址儲存的東西就未知了。
3.再次提提ASCII編碼 參考資料百度百科: 點擊開啟連結 http://baike.baidu.com/link?url=G-MNClonJye7qworrj168QZI9QkZNmbhyqOtOfYcrbXYcMYQULrhioz_0aAKadpAHRnbaAIxhDeBKafdowF9BK
編碼:把一個字元對應表到它的二進位碼叫做編碼 在ASCII中 0~31及127(共33個)是控制字元或通訊專用字元(其餘為可顯示字元),能夠表示128個字元,第八位是同位位元。
4.學習一下freopen函數可以方便debug 參考資料百度百科:點擊開啟連結 http://baike.baidu.com/link?url=inkB8kSRkuYBZED49Vhe7R0G-CfYCcLMAMQbvas85UtbEYPxiOiOvmC_I1NVRbRLaJ0Qb5-UslUojiVyzeXLqfgFYVvEi_8_IB0-232PI0G
百科中解釋為用於重新導向輸入輸出資料流,我們看看如何使用
#include<iostream>#include<cstdio> //引用標頭檔using namespace std;int main(){ freopen("data.txt","r",stdin); //指定輸入的檔案,這種寫法(沒有寫完整路徑)是預設程式和檔案在一個目錄下 freopen("anser.txt","w",stdout); //指定輸出檔案,預設程式和檔案在一個目錄下 int n; char word[10]; cin>>n; for(int i = 0;i < n; i++){ cin>>word; cout<<word<<endl; }} 未運行前目錄下檔案,以及data.txt中資料
運行後目錄下檔案,以及anser.txt中資料。anser.txt是自動產生的(如果不存在該檔案),否則會隨程式運行覆蓋原檔案。
在看看運行程式後,黑框子裡都有啥。
啥都沒有,因為輸入輸出都重新導向了。 如果把以下代碼注釋掉呢,看看黑框子裡的情況
freopen("anser.txt","w",stdout);
輸出還在黑框子中。 因此如果在debug的時候,可以考慮寫一個資料檔案,然後用freopen讀入,輸出還在黑框子中,這樣就不用每次手動複製黏貼了。
第五章內容: 1.迴圈 迴圈主要的三種方式:
while( ... ){ ... } do{ ... }while(...); for(... ; ... ; ...){ ... }兩個相關語句: break 跳出迴圈 continue 直接進入下一個迴圈
我們討論一下再多重迴圈中,如何在用深層的迴圈得到的結果控制外層的迴圈。 例子: 當i + j + k = 100 的時候 結束當前迴圈以及第二層迴圈, i + j + k = 200 的時候結束所有迴圈
#include<iostream>#include<cstdio> using namespace std;int main(){ for(int i = 0;i < 200; i++){ int flag1 = 0;//標記1 用於判斷i + j + k是否等於200了 for(int j = 0;j < 200; j++){ int flag2 = 0; //標記2 用於判斷i + j + k 是否等於100了 for(int k = 0;k < 200; k++){ if(i + j + k == 100){ flag2 = 1; break; } if(i + j + k == 200){ flag1 = 1; break; } } if(flag2) //條件成立結束迴圈 break; if(flag1) break; } if(flag1) //條件成立結束迴圈 break; }}
從上面代碼可以看出,兩個標記的值會在條件成立時賦值為1 即 true。 然後會分別觸發兩次或三次break語句。 寫起來比較繁瑣但是是可以實現的。
下面展示一下goto的用法,不做介紹,寫起來方便,但是不符合當前的要求。有興趣的自己尋找資訊。
#include<iostream>#include<cstdio>using namespace std;int main(){ for(int i = 0;i < 200; i++){ for(int j = 0;j < 200; j++){ for(int k = 0;k < 200; k++){ if(i + j + k == 100){ cout<<i + j + k <<endl; goto flag2; } if(i + j + k == 200){ cout<<i + j + k <<endl; goto flag1; } } } flag2:; } flag1:;}
第六章內容: 1.函數結構 P177 6.2 函數由函數名、參數、傳回值類型和主體構成
2.函數調用 P178 6.3 相當於執行函數中的代碼 傳回值是函數執行結束後返回的結果,該結果可以在調用方被儲存或者忽略掉。
int max(int a,int b){ if(a > b) return a; else return b;}int main(){ int a = max(1,2); int b = a>b?a:b; max(1,2); a>b?a:b;}看上面的代碼,求最大值,函數如果有傳回值,那麼返回的結果儲存和不儲存都是可以的,就像一個運算式得到的結果我們可以儲存或者忽略掉。 注意以下問題
#include<iostream>#include<windows.h>using namespace std;void f(){}int f2(int n){ if(n % 2== 0) //這事一個有傳回值的函數, return 1; //但是在 n%2==0的時候,沒有返回任何值}int main(){ int x = f(); //這是一個無傳回值函數,卻用採用函數傳回值方式複製 int y = f2(1); cout<<y<<endl;}
P179中間部分說明了,main函數也是一種函數,只是main函數是作業系統用來識別一個程式的入口的函數。我們甚至也可以調用main函數。
int ans = 10;int main(){ if(ans == 0) return 0; cout<<ans<<endl; ans--; main();}任一函數也可以調用其他函數,函數自己調用自己的行為稱之為遞迴調用。寫過DFS(深度優先搜尋的)就非常熟悉了。
3.函數重載 P186 函數名可以相同,函數的簽名不同即可。
4.函數原型聲明 P189 聲明一個函數,而沒有實體
5.內嵌函式 P191 提升函數效能,減少CPU寄存器壓棧,關鍵字inline
6.局部、全域和靜態局部變數 參考資料: http://www.cnblogs.com/DannyShi/p/4584750.html 變數
http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 記憶體堆和棧區別
P192 6.1.1 修正一下:全域變數不在堆中分配記憶體,在靜態記憶體區中(然而我並不是很清楚如何分配的)
7引用 P197