在論壇裡經常見到一些新人對指標提出一些問題,作為乙個經歷過許多錯誤後的新手,我想把自己的經歷說出來,避免讓後來人繼續這樣的錯誤。
在講解指標之前,需要理解一下記憶體空間。記憶體是隨機訪問器,計算機上電後便利用記憶體進行運轉。其有一定的容量,為了標識每個儲存單元的位置,我們為記憶體設定了記憶體位址。記憶體的具體組織結構可以參考計算機組成原理。
指標是一種指向某種型別的特殊的型別。一般用*定義。如int *p,這樣就定義了乙個指向int型別的指標。指標用於指向某塊記憶體空間,該記憶體空間裡面存放了其所指向的記憶體位址。所以,在使用指標之前,必須明白這指標指向了什麼記憶體空間,給指標賦值可以使用取位址符(&),如p = &a;每次需要訪問指標所指向的內容時,便使用解引用符號*進行訪問。如:printf(「%d」,*p);
上面簡單介紹了下指標的定義,賦值等操作。下面介紹下一些新手容易迷糊的地方吧。
1. char *str1=」abcd」; char str2=」abcd」;的區別
c標準沒有規定這兩種定義字串的方式的差別。但是,指標型別的字串一般不允許修改。如:str1[0]=』c』;這樣的語句會導致執行時錯誤。錯誤型別:不允許寫入什麼的。據說,在某些編譯器中可以設定成可以修改的。
2.指標/陣列作為引數進行傳遞
在c語言中,引數是使用值傳遞的。
int func(int a );當呼叫者呼叫該函式的時候將傳遞乙個值給a,這個a只是你傳遞進去的引數的乙個副本。而陣列傳遞的時候,會退化為指標,其將陣列的首位址複製給形參。看下面的乙個例子。
c/c++ code?
void fun(char str)
int main()
輸出:before transform:8
after transform:4
在傳遞之前,我們可以獲得陣列所占用的記憶體空間的大小;而傳遞後,我們只能獲得乙個指標的大小了。
許多初學c指標的同學想在函式內部修改作為引數傳遞進來的指標的值。看以下**。
c/c++ code?
typedef struct link_nodelinknode,*plinklist;
void createlist(linknode *header)
int main()
許多人疑惑為什麼沒有輸出呢?請各位謹記:c語言使用值傳遞進行引數傳遞。這就是問題所在。在傳遞指標的時候,呼叫者傳遞了原指標所指向的記憶體位址給形參。也就是說,在傳遞引數的時候,系統定義了另外乙個指標,也就是我們在此定義的header指標。我們把原指標的值傳遞給了header指標。所以header指向了本例中的null。然後我們去修改header所指向的值。當函式結束後,這個指標的生命週期也結束了。所以對main函式中的head沒有任何修改。
下面我們再看一例。
c/c++ code?
void trans(int* arr,int nlength)
int main()
動態開闢陣列
指標可以用來分配記憶體,作為陣列來使用。
開闢一維陣列:int *parr = (int*)malloc(10*sizeof(int));釋放空間:free(parr);
開闢二維或者多維陣列需要分級申請記憶體:int **parr;
parr = (int **)malloc(sizeof(int*)*3);
for(i=0;i<3;i++)
*(parr+i) = (int *)malloc(sizeof(int)*5);
當然釋放空間的時候也需要分級釋放咯; for(i=0;i<3;i++) free(*(parr+i));
函式指標和指標函式
在計算機記憶體中,所有的資料都有唯一的位址,當然可執行的程式也是有位址的。函式**是程式的演算法指令部分,它們和陣列一樣也占用儲存空間,都有相應的位址。可以使用指標變數指向陣列的首位址,也可以使用指標變數指向函式**的首位址,指向函式**首位址的指標變數稱為函式指標。定義形式為:函式型別 (*指標變數名)(形參列表);如:int (*func)(char a,int nlength)。不過,我們經常會遇到這樣的定義方式:typedef int (*func)(char a,int nlength);其實使用typedef主要是為了定義函式指標方便,不需要每次都敲那麼的**。(其實懶也是技術驅動的一種動力啊!)我這裡就簡單的介紹點東西。在搞演算法的時候,函式指標大有用處,可以用它實現很多beautiful演算法。比如那些自動機等等。
c/c++ code?
typedef int (*func)(char a,int nlength);
int total(char a,int nlength)
{ int ntotal = 0;
for(int i=0;i
乙個函式不僅可以帶回乙個整型資料的值,字元型別值和實型型別的值,還可以帶回指標型別的資料,使其指向某個位址單元。在這裡,我就不多說什麼了。僅提醒各位初學者一下:返回的位址必須不能是該函式的棧空間裡的。那樣待函式返回後,獲得到的位址將是乙個錯誤的位址。
傳遞指標和傳遞指標的指標
總是不懂指標 看了乙個csdn的問題 豁然開朗 在寫乙個棧的東西,在銷毀的時候有點小問題 define position int define size t int define elemtype char define buttom 1 struct ststack typedef struct ...
指標的傳遞
關於指標作為形參時,值是如何傳遞和改變的。當呼叫函式向被呼叫函式傳遞乙個指標值,而在被呼叫函式中對這個指標所表示的位址的值進行重新賦值將會改變呼叫函式中的值。include voidfoo char p p world n 0 printf s p voidmain char p hello,wor...
關於指標傳遞和指標的引用傳遞
指標傳遞的實質 指標傳遞引數本質上是值傳遞的方式,它所傳遞的是乙個位址值。值傳遞過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在棧中開闢了記憶體空間以存放由主調函式放進來的實參的值,從而成為了實參的乙個副本。引用傳遞的實質 在引用傳遞過程中,被調函式的形式引數雖然也作為區域性變數在棧中開...