复习笔记(一)——C++基础
C++與C有什么關系?它們的區別是什么?
① 在C語言中引入了面向對象的思想
②C++是一種混合型的語言,同時支持結構化程序設計和面向對象程序設計方法
③兼容C語言,可不加修改地使用C語言代碼
④允許數據抽象,支持封裝、繼承和多態等特征
目錄
- C++標準庫
- 關鍵字
- 數據類型
- 數據類型分類
- 數據類型概述
- bool類型
- 結構體位段
- 強制類型轉換
- 域運算符
- 動態分配內存
- new運算符
- delete運算符
- new和malloc區別
- 函數重載
- 帶默認形參值的函數
- 內聯函數
- 引用類型
- 按引用傳遞
C++標準庫
直接使用標準C中所有庫,如以下是常用的標準C函數庫頭文件:
stdio.h、 stdlib.h、 string.h、 ctype.h
C++編譯器都提供有完整的標準庫
C++標準庫中的幾乎所有內容都是在命名空間std中定義的
使用C++標準庫將獲得非常多的功能
關鍵字
關鍵字是系統已經預定義的單詞,有專用的定義。這些關鍵詞都是保留字,用戶不可再重新定義。
C++區分大小寫,關鍵字全部由小寫字母組成。標準C++(ISO14882)定義了74個關鍵字,具體的C++編譯器還會做一些增刪
數據類型
數據類型分類
C++中數據有常量和變量之分,它們分別屬于以下這些類型
數據類型概述
基本數據類型有4種:整型(int)、實型(float、double)、字符型(char)、邏輯型(bool)
**注意:C語言沒有bool型
空類型void:用于顯示說明一個函數不返回任何值
構造類型又稱為組合類型:是由基本類型按照某種規則組合而成的
指針類型:變量用于存儲另一變量的地址,而不能用來存放基本類型的數據
類類型:是體現面向對象程序設計的最基本特征,也是體現C++與C最大的不同之處
bool類型
邏輯型也稱布爾型,其取值為true(邏輯真)和false(邏輯假),存儲字節數在不同編譯系統中可能有所不同,VC++6.0中為1個字節。
可以當作整數用(true一般為1,false為0)
把其它類型的值轉換為布爾值時,非零值轉換為true,零值轉換為false
結構體位段
C++定義結構體中,可以為其成員定義時指定所占的位數(1個字節為8個位)
#include<stdio.h> struct Date { int year : 12; int month : 12; int day : 16; }; int main() {printf("sizeof(struct Date) = %d\n",sizeof(struct Date));return 0; } 執行結果: sizeof(struct Date) = 8強制類型轉換
①強制類型轉換格式如下:
type(表達式),例如:int(num); (type)表達式,例如:(int)num;作用:將表達式強制轉換為type類型,但表達式的值及其類型不變
②新增的強制類型轉換運算符:
格式:static_cast(表達式)
例如:
域運算符
C++中增加的作用域標識符 ::
①用于對與局部變量同名的全局變量進行訪問
②用于表示類的成員,這將在關于類的一節中詳細說明
示例:
#include<stdio.h>int var=1; void main(void) {int var=0;printf("var=%d\n",var); //局部變量var=::var; //引用全局變量printf("after var=::var %d\n",var); }執行結果: var=0 after var=::var 1動態分配內存
靜態分配內存:在編譯時確定了固定的內存地址與內存大小,如:函數里的局部變量、全局變量等。
動態分配內存:由程序控制,運行時主動性的向系統申請所需大小的內存段,并且每次分配到的內存地址不固定。
C++ 可以使用malloc、realloc、calloc和free函數實現,也可以使用運算符new和delete實現。
new運算符
new 運算符 可以用于創建堆空間成功返回首地址,失敗返回NULL
語法:指針變量=new 數據類型;
指針變量=new 數據類型[長度];
例如:
int *p; p=new int; char *pStr=new char[50];delete運算符
delete運算符 可以用于釋放堆空間
語法:delete 指針變量;
delete [] 指針變量;
例如:
delete p; delete [] pStr;動態內存分配示例:
#include <stdlib.h> #include <stdio.h> int main() {int * a;int i, num;char ch;printf("Please enter the number of integers: ");scanf("%d",&num);printf("");a = new int [num];if (a == NULL) {printf( "malloc error! exit.\n" );return 1;}for( i = 0; i < num; i ++ ){*(a+i) = i+1;}for (i = 0; i < num; i ++ )printf( "a[%d] = %d\n",i,a[i] );printf("\n");delete [ ] a ;return 0; }執行結果: Please enter the number of integers: 3 a[0] = 1 a[1] = 2 a[2] = 3new和malloc區別
1、屬性
new/delete是C++關鍵字,需要編譯器支持。malloc/free是庫函數,需要頭文件支持。
2、參數
使用new操作符申請內存分配時無須指定內存塊的大小,編譯器會根據類型信息自行計算。而malloc則需要顯式地指出所需內存的尺寸。
3、返回類型
new操作符內存分配成功時,返回的是對象類型的指針,類型嚴格與對象匹配,無須進行類型轉換,故new是符合類型安全性的操作符。而malloc內存分配成功則是返回void * ,需要通過強制類型轉換將void*指針轉換成我們需要的類型。
4、分配失敗
new內存分配失敗時,會拋出bac_alloc異常。malloc分配內存失敗時返回NULL。
5、自定義類型
new會先調用operator new函數,申請足夠的內存(通常底層使用malloc實現)。然后調用類型的構造函數,初始化成員變量,最后返回自定義類型指針。delete先調用析構函數,然后調用operator delete函數釋放內存(通常底層使用free實現)。
malloc/free是庫函數,只能動態的申請和釋放內存,無法強制要求其做自定義類型對象構造和析構工作。
6、重載
C++允許重載new/delete操作符,特別的,布局new的就不需要為對象分配內存,而是指定了一個地址作為內存起始區域,new在這段內存上為對象調用構造函數完成初始化工作,并返回此地址。而malloc不允許重載。
7、 內存區域
new操作符從自由存儲區(free store)上為對象動態分配內存空間,而malloc函數從堆上動態分配內存。自由存儲區是C++基于new操作符的一個抽象概念,凡是通過new操作符進行內存申請,該內存即為自由存儲區。而堆是操作系統中的術語,是操作系統所維護的一塊特殊內存,用于程序的內存動態分配,C語言使用malloc從堆上分配內存,使用free釋放已分配的對應內存。自由存儲區不等于堆,如上所述,布局new就可以不位于堆中。
函數重載
C++允許用相同的函數名來定義一組功能相同或類似的函數,程序的可讀性增強
函數重載又稱為函數的多態性
函數重載不同形式:
①形參數量不同
②形參類型不同
③形參的順序不同
④形參數量和形參類型都不同
調用重載函數時,編譯器通過檢查實際參數的個數、類型和順序來確定相應的被調用函數
合法的重載例子:
int abs(int i); long abs(long l); double abs(double d);非法的重載例子:
int abs(int i); long abs(int i); void abs(int i); //如果返回類型不同而函數名相同、形參也相同,則是不合法的,編譯器會報"語法錯誤"函數重載實例:
#include <stdio.h> int max(int x, int y); double max(double x, double y); void main() { int a=10, b=20 ,c;double x=10.3, y=10.6, z;c = max(a,b);z = max(x,y);printf("\nc=%d z=%.1f\n",c,z); } int max(int x, int y) { printf("\nint function"); if(x>y) return x; elsereturn y; } double max(double x, double y) { printf("\ndouble function"); if(x>y) return x; elsereturn y; }執行結果 int function double function: c=20 z=10.6帶默認形參值的函數
函數聲明或者定義的時候,可以給形參賦一些默認值
調用函數時,若沒有給出實參,則按指定的默認值進行工作
函數既有定義又有聲明時,聲明時指定后,定義后就不能再指定默認值
默認值的定義必須遵守從右到左的順序,如果某個形參沒有默認值,則它左邊的參數就不能有默認值。
void func1(int a, double b=4.5, int c=3); //合法 void func1(int a=1, double b, int c=3); //不合法函數調用時,實參與形參按從左到右的順序進行匹配
實例:
#include <stdio.h> double power(double x=10.0, int n=2); void main() { printf("power(3,5)=%.1f\n",power(3,5)); printf("power(3)=%.1f\n",power(3));printf("power()=%.1f\n",power()); } double power(double x, int n){ int i;double s=1.0;s = x + n;return s; }執行結果: power(3,5)=8.0 power(3)=5.0 power()=12.0帶默認形參值的函數的二義性:
重載的函數中如果形參帶有默認值時,可能產生二義性
示例:
#include <stdio.h> int add(int x=5, int y=6); float add(int x=5, float y=10.0); void main() { int a; float b; a= add(10,20); b= add(10); printf("a= %d\n" , a); printf("b= %d\n",b); }b=add(10)語句產生二義性,可以認為該語句是調用第一個函數,也可以是第二個,因此編譯器不能確定調用的是哪一個函數。
內聯函數
當程序執行函數調用時,系統要建立棧空間,保護現場,傳遞參數以及控制程序執行的轉移等等,這些工作需要系統時間和空間的開銷。有些情況下,函數本身功能簡單,代碼很短,但使用頻率卻很高,程序頻繁調用該函數所花費的時間卻很多,從而使得程序執行效率降低。
為了提高效率,一個解決辦法就是不使用函數,直接將函數的代碼嵌入到程序中。但這個辦法也有缺點,一是相同代碼重復書寫,二是程序可讀性往往沒有使用函數的好。
為了協調好效率和可讀性之間的矛盾,C++提供了另一種方法,即定義內聯函數,方法是在定義函數時用修飾詞inline。
實例:
//讀入一行字符串,逐個判斷是否為數字字符: # include <iostream.h> inline IsNumber(char ch) { return ch>='0' && ch<='9'?1:0; } void main() {char ch;cout<<"請在鍵盤輸入一個字母或數字:";while(cin.get(ch), ch!='\n'){if (IsNumber(ch)) cout<<"是數字字符"<<endl;else cout<<"不是數字字符 "<<endl;} }//因使用頻度很高,說明為內聯函數。使用內聯函數注意點:
1.遞歸函數不能定義為內聯函數
2.內聯函數一般適合于不存在while和switch等復雜的結構且只有1~5條語句的小函數上,否則編譯系統將該函數視為普通函數。
3.內聯函數只能先定義后使用,否則編譯系統也會把它認為是普通函數。
4.使用inline的修飾時,gcc編譯器會根據實際情況,看是否需要內聯,太過復雜的函數,編譯器是不會進行內聯的。而有些簡單的函數,就算沒有使用inline修飾,編譯器也會進行內聯。
引用類型
引用是一種特殊的變量,可以認為是一個變量的別名
定義引用的一般格式:類型說明符 &引用名 = 變量名;
例如:
int a=1; int &b=a; // b是a的別名,因此a和b是同一個單元注意:定義引用時一定要初始化,指明該引用變量是誰的別名
對數組只能引用數組元素,不能引用數組(數組名本身為地址)。
不能定義引用的引用(引用也是地址),所以當函數的參數為引用時,引用不能作實參。
按引用傳遞
引用傳遞方式是在函數定義時在形參前面加上引用運算符"&"
例如:
swap(int &a,int &b);按值傳遞方式容易理解,但形參值的改變不能對實參產生影響
地址傳遞方式通過形參的改變使相應的實參改變,但程序容易產生錯誤且難以閱讀
引用作為參數對形參的任何操作都能改變相應的實參的數據,又使函數調用顯得方便、自然
實例:
#include <stdio.h> void swap(int &x, int &y); void main() {int a, b;a = 10;b = 20;swap(a, b);printf("a=%d,b=%d",a,b); } void swap(int &x, int &y) {int temp;temp = x;x = y;y = temp; }執行結果: a=20,b=10注意:引用作參數時,函數的實參與形參在內存中共用存儲單元,因此形參的變化會使實參同時變化。
總結
以上是生活随笔為你收集整理的复习笔记(一)——C++基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言—文件基础
- 下一篇: 复习笔记(二)——C++面向对象设计和使