C 易錯知識點。對方正在輸入

2021-09-11 17:38:08 字數 3820 閱讀 8571

目錄

陣列位址問題

形參和實參的區別:

new使用方法:

有關new的良好變成習慣

陣列初始化int data[3]。此時data中有三個資料,而不是四個。

int main() ;

//data代表著data首元素的位址

cout << "data:" << data << endl;

//data+1代表著data第二元素的位址

//因此其位址比data多sizeof(int)

cout << "data+1:" << data + 1 << endl;

//&data中的data表示的是整個data陣列

//但&data的值也是陣列首元素位址

cout << "&data:" << &data << endl;

//&data+1代表著除了data陣列外,還多了乙個與data相同的陣列

//因此其位址比data多sizeof(data),即4*9=36

cout << "&data+1:" << &data+1 << endl;

//*表示取位址,因此為data[0]

cout << "*data:" << *data << endl;

//可以將data[0]理解為乙個指標,指向data

實參(argument):全稱為"實際引數"是在呼叫時傳遞給函式的引數. 實參可以是常量、變數、表示式、函式等, 無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值, 以便把這些值傳送給形參。 因此應預先用賦值,輸入等辦法使實參獲得確定值。      

形參(parameter):

全稱為"形式引數" 由於它不是實際存在變數,所以又稱虛擬變數。是在定義函式名和函式體的時候使用的引數,目的是用來接收呼叫該函式時傳入的引數.在呼叫函式時,實參將賦值給形參。因而,必須注意實參的個數,型別應與形參一一對應,並且實參必須要有確定的值。

3、swap函式一些注意事項

1)達不到交換的作用

templatevoid swap(t a,tb)

因為當main函式呼叫swap時,僅僅是相當於實參的數值賦予swap函式的形參(除此之外實參無作用),形參中的a,b確實進行了交換,但由於形參是區域性變數,因此在swap函式結束時便銷毀的形參。所以實參並不會進行swap的動作。

2)可以達到交換的作用

templatevoid swap(t &a,t &b)

在swap函式中,其形參使用了引用&。引用即是對某一變數(目標)的乙個別名,對引用的操作與對變數直接操作完全一樣。而且引用本身並不占用記憶體,而是和目標變數共同指向目標變數的記憶體位址。因此對形參的操作就是對main函式中實參的操作,所以可以交換。

templatevoid swap(t *a,t *b)

int main()

swap形參的型別為指標變數,因此main函式中需要傳遞的實參為帶交換變數的位址,這樣形參中的指標才有所指向的位址。在swap函式中,它操作的內容是在記憶體中此位址指向的資料,因此它確確實實交換了main中的變數。在swap結束後,存放實參位址的形參被銷毀,但這不影響我們已經交換了的資料,注意區分與第一種的區別。

//使用異或的概念來交換陣列

templatevoid swap(t &a,t &b)

//使用加法的概念來交換陣列

templatevoid swap(t &a,t &b)

當傳遞的是陣列時,不用引用卻可以交換,具體分析如下:

#include using namespace std;

templatevoid swap_self(t data)

int main() ;

swap_self(data);//傳遞的是陣列的首位址過去

printdata(data, 9);

system("pause");

return 0;

}

1 int *x = new int;       //開闢乙個存放整數的儲存空間,返回乙個指向該儲存空間的位址(即指標)

2 int *a = new int(100); //開闢乙個存放整數的空間,並指定該整數的初值為100,返回乙個指向該儲存空間的位址

3 char *b = new char[10]; //開闢乙個存放字元陣列(包括10個元素)的空間,返回首元素的位址

4 float *p=new float (3.14159);//開闢乙個存放單精度數的空間,並指定該實數的初值為將返回的該空間的位址賦給指標變數p

1. int *a = new int;

delete a;   //釋放單個int的空間

2.int *a = new int[5];

delete a; //釋放int陣列空間

3.指標刪除與堆空間釋放。刪除乙個指標p(delete p;)實際意思是刪除了p所指的目標(變數或物件等),釋放了它所佔的堆空間,而不是刪除p本身(指標p本身並沒有撤銷,它自己仍然存在,該指標所佔記憶體空間並未釋放),釋放堆空間後,p成了空指標,注意,此時p成為了野指標!!delete指標p後必須設定指標p的位址為null方可。

1、指標變數沒有被初始化宣告乙個指標但未分配記憶體空間時,最好將其置為null。           char *pc = null;

2、指標超過了變數的作用範圍。

char *pc = null;

pc = new char[5];

此時不但可以給p[0]到p[4]賦值,還可以給後面的位址賦值,如p[5],p[10]等。

這就是c/c++完美之餘的乙個歷史遺留缺陷,不進行越界檢查,導致編譯沒有任何問題,執行階段有時一不小心也察覺不出,這就要求程式設計師養成良好的習慣:new後面必出現delete。

這就是上面遺留的第二個問題*2:對同乙個指標變數指向的記憶體釋放兩次,與釋放乙個沒有成功分配記憶體或引用越界的指標變數類似,都是不允許的。

3、指標指向的記憶體被釋放了,而指標本身沒有置null

指標p被free或者delete之後,沒有置為null,讓人誤以為p是個合法的指標.

char *p=new char[10];  //指向堆中分配的記憶體首位址,p儲存在棧區

cin>> p;

delete p; //p重新變為野指標

還需加上一句p=null;

C易錯知識點

參考酷客網,對其進行了簡單整理 1 下面的程式並不見得會輸出 hello std out 你知道為什麼嗎?include include intmain return 0 參 stdout 和stderr 是不是同裝置描述符。stdout 是塊裝置,stderr 則不是。對於塊裝置,只有當下面幾種情...

C 易錯知識點歸納

物件導向開發的四大特性 三字元組 內建型別所佔記憶體大小 單位 位元組 typedef 為乙個已知型別取新名字 列舉 派生資料型別,只有賦值運算子沒有定義算術運算 變數命名 字母 下劃線開頭,可以有數字,不能有標點符號。大小寫敏感。變數宣告 未開闢空間。extern實現,若在其後賦初始值便為定義。變...

Java 易錯知識點

1 以下程式執行的結果是 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 classx classy publicclasszextendsx publicstaticvoidmain string args zyxx zyxy yxyz xyz...