指標初步
定義一個指標變數:int * a=NULL; int 是指標的類型,其實應該說是指標指向的資料的類型。
程式運行時,資料都是放在記憶體中的,既然在記憶體中,就處於記憶體中的某個位置,這就是資料的地址。指標中儲存的就是這個地址。所以不論什麼類型的指標,指標變數本身之間並沒有區別,值都是一個整數值。32位程式中這個整數是32位的,64位程式中這個整數是64位的。其實指標變數與整型變數之間跟本沒有區別,就看你怎麼解釋它了。一個整數你可以把它解釋為指標也可以解釋為整數,所以指標與整數之間可以輕鬆轉換。
你完全可以定義指標時直接給它賦一個整數值,表示這個指標指向這個整數所代表的地址位置,而這個位置的資料如何去解釋它呢。就看指標的類型了。但是一般我們不能這樣做,這樣容易崩潰,因為你隨便指定的這個位置不是一個有效位置。所以在使用指標之前要讓指標指向一個有效位置,比如 a=&b; b是一個int型變數。“&”是取得b的地址,此時a就指向了一個有效地址。
使用指標所指向的資料,需要“*a”的方式,比如 *a=100; 這樣看起來很像以間接的方式使用變數b。我們的計算機程式中用到的scanf()函數,其接收使用者輸入值的參數是一個指標,但這個指標必須指向有效記憶體才能接收到資料,否則會引起崩潰。
要區分好指標與指標指向的資料之間的區別。指標本身佔4個位元組或8個位元組,而指標指向的資料不一定佔多少位元組。比如指向一個char型資料,那麼指標指向的內容只佔一位元組。指標也可能指向了一大塊記憶體,比如用malloc在堆中申請的記憶體。
指標變數本身的銷毀不影響指標指向記憶體,就是說它們倆的生命期是完全沒關係的。一般指標都是臨時變數(在棧中分配),如果指標指向的記憶體是堆中分配的話,當函數返回時指標變數會被自動銷毀,而其指向的記憶體卻沒有被釋放,那麼那塊記憶體就再也不能被釋放了,於是它就成了記憶體漏洞。
指標與所指向內容的關係,如下:
中間紅色是指標d的值,正好是變數a的首位元組的地址,也就是a的地址。這是64位程式的情況,可以看到地址佔了8個位元組。
以上是VS中的樣子,QtCreator中是這樣的:
注意這個是兩個程式,所以a在記憶體中的位置不一樣,所以d的值不一樣。
陣列變數本身其實也是一個指標。但是編譯器把它當數組對待,比如sizeof()計算一個指標時得到的是不是4就是8,而計算一個數組時,得到的是整個數組所佔的位元組數。而同時陣列變數又完全可以當作指標使用。
關於指標的詳細解釋,請參考視頻教程:http://edu.csdn.net/course/detail/2318 數組
數組是一坨類型相同的資料排列在一起組成的,因為每一個元素佔用的位元組數相同,所以跟據一個元素的序號就可以計算出它在記憶體中的位置,所以數組元素可以用序號來訪問。
//定義一個float型數組,數組的類型表示其每一項都是一個float型值 //數組有19項,這個數組 佔19x4 個位元組。沒有初始化,數組每一項的值都是隨機值 float farr[19]; //沒有在中括弧中指定數組的數量,但對數組進行了初始化,從大括弧中可以 //數出數組的項數。 float farr1[] = {55.3, 44.2, 5, 33.3};
為什麼要用數組呢? 比如要寫一個函數,求10個數的平均數,那麼這個函數就要有10個參數。如果求100個數的平均數呢?難不成給它100個參數?這肯定不現實。我們如果把這一百個數放到數組中,然後把數組傳給函數,那麼只需要一個參數就夠了。如下:
#include <stdio.h>//前置聲明float average(int numbers[]);//入口函數int main(int argc, char *argv[]){ //定義一個數組,給10個元素 int arr[] = {1,22,3,4,76,443,32,45,34,23}; //調用求平均數函數 float avg = average(arr); //列印平均值 printf("%f\n",avg); return 0;}//求平均值函數,參數是一個數組float average(int numbers[10]){ //先求數組中各元素的和 int he =numbers[0]+numbers[1]+numbers[2]+numbers[3]+ numbers[4]+numbers[5]+numbers[6]+numbers[7]+ numbers[8]+numbers[9]; //求平均值 float ret = he/10.0f; //返回結果 return ret;}
上一篇:成為C++高手之最終版計算機
下一篇:成為C++高手之for迴圈