C++ 課本學習筆記(1)


1.3   C++C的擴充

1.3.1   C++的輸入輸出

1. 標準輸入輸出流coutcin。在頭文件<iostream>

2. cerr:標準出錯輸出
clogcerr的緩衝形式

3. cin>>>>常稱爲“提取運算符”。用”>>” 從鍵盤取得數據並送到輸入流cin中,然後再送到內存。

4. 簡單的程序:
int mian(){

cout<<”Please enter your name : ”<<endl;
char name[20];
cin>>name;
cout<<”Hello,”<<name<<endl;
return 0;
}
注意:程序中對變量的定義放在了執行語句後面,在C中是不允許的。

   C++允許對變量的聲明放在程序的任何位置,但必須在使用變量之前。

1.3.2 const定義常變量

1. 在C中,常用#define指令定義符號常量,如: #define PI 3.14159
實際上,只是在預編譯時進行字符置換,把程序中出現的字符串PI 全部置換成3.14159
預編譯之後,程序中就沒有PI這個標識符了。
注意:PI不是變量,沒有類型,不佔用存儲空間。

2. 看簡單程序:
int a=1,b=2;
#define  PI  3.14159
#define R a+b
cout<<PI*R*R<<endl;


輸出的並不是3.14159*a+b*a+b),而是3.14159*a+b*a+b,程序因此常常會出錯。

C++提供了用const定義常變量的方法,如: const float PI 3.14159

注意:PI具有變量的屬性,有數據類型,佔用存儲空間,有地址,可以用指針指向它,知識在程序運行期間值是固定的,不能改變。

 

1.3.3   函數原型聲明

1. C中,以下三種聲明方式都能通過編譯:
int max(int x,int y);
int max();
  max();

C++中,如果函數調用的位置在函數定義之前,則必須進行函數原型聲明,使編譯系統嚴格檢查。

int max(int x,int y);
  int max(int,int);

注意:在編譯時,只檢查參數類型,而不檢查參數名。

 

1.3.4  函數的重載

1. 在C中,規定在同一作用域(例如同一文件模板中),不能有同名的函數
C++  允許在同一作用域中用同一函數名定義多個函數,但是,函數的參數個數和參數類型不相同。

2. 簡單程序:
int max(int a,int b, int c){

if(b>a) a=b;

if(c>a) a=c;

return   a;

}
float max(float a,float b, float c){

if(b>a) a=b;

if(c>a) a=c;

return   a;

}

int main(){

int a,b,c;

float d,e,f;
cin>>a>>b>>c;

cin>>d>>e>>f;

int m;

m=max(a,b,c);

cout<<”max_i=”<<m<<endl;

float n;

n=max(d,e,f);

cout<<”max_f=”<<n<<endl;

}

 

系統會根據實參的類型找到與之匹配的函數,然後調用該函數。

 

1.3.5  函數模板

1. 簡單程序:
template<typename T>

T max(T a,T b,T c){

if(b>a) a=b;

if(c>a) a=c;

return   a;

}

int main(){

int i1=8,i2=5,i3=6,i;

double d1=56.9,d2=90.765,d3=43.1,d;

i=max(i1,i2,i3);

d=max(d1,d2,d3);

cout<<”i_max=”<<i<<endl;

cout<<”d_max=”<<d<<endl;

}

通用函數定義:

template<class T>

template<typename T>

 

注意: 它只適用於函數的參數個數相同而類型不同,且函數體相同的情況,如果參數個數不同,則不能用函數模板。

 

1.3.6  有默認參數的函數

1. float volume(float h,float r=12.5)

實參與形參的結合是從左至右順序進行的,因此指定默認值的參數必須放在形參表中的最右端,否則出錯。

 

注意:

1. 如果在函數調用前需要函數聲明,此時必須在函數聲明中給出默認值,在函數定義時可以不給出默認值。也就是在調用之前將默認值的信息通知編譯系統。由於編譯是從上到下逐行進行的,如果在函數調用之前未得到默認值的信息,則編譯到函數調用時,會認爲實參個數與形參個數不匹配而報錯。

2. 一個函數既不能作爲重載函數,又作爲有默認參數的函數,會出現二義性。

 

1.3.7   變量的引用

1. int a;

int &b=a;  

這就聲明瞭ba的引用,即a的別名。

注意:

1.  對變量聲明一個引用,並不另開闢內存單元,ba都代表同一變量單元,因此在 建立引用時只有聲明,沒有定義。

 

2.  在聲明一個引用時,必須同時使之初始化,不能再作爲其他變量的引用。

 

3.  區分是聲明引用還是取地址操作:

&a的前面有類型符時(int &a),必然是引用,如(p=&a)此時是取地址操作。

 

4.   int a=3;

int &b=a;

int &c=b;

此時,整型變量a有兩個別名,bc

 

5.  不能建立void類型的引用
因爲任何存在的變量都是非void類型。

 

6.  不能建立引用的數組
char c[6]=”hello”;

     char &rc[6]=c;
數組名c只代表數組首元素的地址,本身並不是一個佔有存儲空間的變量。

 

7.  可以用const對引用加以限定
int i=5;
 const int &a=i;

     a=3;      //錯誤

     i=3;      //合法

     並不阻止改變引用所代表的變量的值。

 

8.   int i=5;

const &a=i+3;    //合法

此時編譯系統這樣處理:生成一個臨時變量存放表達式的值,引用是該臨時變量的別名,如下:

int temp=i+3;

const int &a=temp;

   臨時變量是內部實現的,用戶不能訪問。

 

2.  C++  添加引用主要是利用它作爲函數參數,擴充函數傳遞數據的功能。

C中,函數參數傳遞有以下兩種情況:

1.  將變量名作爲實參(形參和實參不是同一存儲單元)

2.  傳遞變量的指針

C++中,傳送變量的別名。實際上,實參傳給形參的是實參的地址。

 

3. 使用引用和指針變量作爲形參的不同:
設立指針變量需要另開闢內存單元,而引用不是獨立的變量,不單獨佔內存單元。

 

1.3.8  內置函數

調用函數需要時間,如果有些函數頻繁調用,會降低程序執行效率。

C++提供內置函數(也叫內聯函數,內嵌函數)。即在編譯時將所調用的函數的代碼嵌入到主調函數中。

inline int max(int a ,int b,int c)

注意:只有對於規模小且頻繁使用的函數,纔可以大大提高運行效率。

 

1.3.9   作用域運算符

先看程序:
float a=13.5

int main(){

int a=5;

cout<<a;

return 0;

}

輸出5

如果想輸出全局變量,C++提供作用域運算符“::”。

程序改爲:

int main(){

int a=5;

cout<<a<<endl;

cout<<::a<<endl;

return 0;

}

“::a”表示全局作用域中的變量。注意:“::”不能訪問函數中的局部變量。

 

1.3.10  字符串變量

1. 字符數組處理字符串外,C++提供了字符串類型定義字符串變量。

string不是C++具有的基本類型(charintfloatdouble),它是在標準庫中的一個字符串類。

#include<string>

 

2. char str[10];
str=”Hello”;  //錯誤

 

string  word = ”Canada”;    //在定義字符串變量時,不必指定長度

word[2] = ‘m’;      //修改後位“Camada

 

3. 定義字符串數組(區別於字符數組)

string name[3]={“zhang”,”li”,”wang”};

說明:每個字符串元素中只包含字符串本身的字符不包括“\0”。

疑問:字符串數組中每個元素的長度不同,定義時怎麼給數組分配存儲空間的呢?

解答:實際上,編譯系統爲每個字符串分配固定的字節數(4個字節),在這個存儲單元中,並不是直接存放字符串本身,而是存放字符串的地址。name[0]存放的是“zhang”的首地址。

 

1.3.11  動態分配/撤銷內存的運算符newdelete

1. 在C語言中,利用mallocfree分配和撤銷內存空間的。但是malloc必須指定開闢內存的大小。
   在C++中,利用newdelete取代。

new  類型[初值]

delete p;

delete []pt;

注意:用new分配數組空間時不能制定初值。

 

2. 簡單程序:
struct student{

char name[10];

int num;

};

int main(){

student *p;

p=new student;

strcp(p->name,”wang”);

.......

}

說明:

定義一個指向結構體的指針p。用new開闢空間存放一個student類型的變量。執行new後返回一個指向student的指針存放在p中。

如果內存不足,new會返回一個NULL

newdelete是運算符,不是函數,因此執行效率高。

 

1.4  C++程序的編寫和實現

1. 編寫源程序(.cpp

2. 對源程序進行編譯(生成.obj文件)

作用:對源程序進行詞法檢查和語法檢查,errorwarning

3. 將目標文件進行連接(生成.exe可執行文件)

.obj輸入內存,與系統提供的庫文件等連接。

4. 運行程序

5. 分析結果

 

2.2  類的聲明和對象的定義

1. 類是對象的抽象,而對象是類的具體實例。

 

2. 用struct聲明的類,如果對其成員既不指定private也不指定public,則系統默認認爲是公共的。

class聲明的類,如果對其成員既不指定private也不指定public,則系統默認認爲是私有的。

 

3. 一個對象所佔的空間只取決於該對象中數據成員所佔的空間,而與成員函數無關。
函數的目標代碼是存儲在對象空間之外的,如果一個類定義了10個對象,這些對象的成員函數對應的是同一個成員函數代碼段。(this指針)

 

4. 如果在類體中定義的成員函數中不包括循環等控制結構,C++系統則會自動對它們作爲inline函數來處理。

 

5. 如果只聲明瞭類而未定義對象,則類的一般成員函數是不佔內存的,只有在定義了類對象時,才爲數據成員分配空間。


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章