【本文鏈接】
http://www.cnblogs.com/hellogiser/p/pointer-summary.html
1.指針注意事項
(1). 指針類型字符串不容許修改
char *str1=”abcd”; char str2[]=”abcd”;的區別。指針類型的字符串一般不允許修改,如:str1[0]=’c’;這樣的語句會導致運行時錯誤。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void
test_string() { char *str1 = "abcd" ; char str2[] = "1234" ; cout << str1 << endl; // abcd cout << str2 << endl; // 1234 cout << *str1 << endl; // a cout << *str2 << endl; // 1 //str1[0]='X'; // ERROR str2[ 0 ] = 'Y' ; // right cout << *str2 << endl; // Y } |
(2).指針/數組作為參數進行傳遞
在C語言中,參數是使用值傳遞的。 int func(int a );當調用者調用該函數的時候將傳遞一個值給a,這個a只是你傳遞進去的參數的一個副本。而數組傳遞的時候,會退化為指針,其將數組的首地址復制給形參。看下面的一個例子。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ void fun( char str[]) { printf( "After transform:%d\n" , sizeof (str)); //4 } int main() { char strs[] = "abcdefg" ; printf( "Before transform:%d\n" , sizeof (strs)); //8 fun(strs); return 0 ; } |
(3). 在函數內部修改指針本身(無效)vs修改指針指向的內容(OK)
許多初學C指針的同學想在函數內部修改作為參數傳遞進來的指針的值。看以下代碼:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ #include "stdafx.h" #include <iostream> using namespace std; typedef struct Link_Node { int Elem; struct Link_Node *next; } LinkNode, *PLinkList; void CreateList(LinkNode *header) { int i = 0 ; header = (LinkNode *)malloc( sizeof (LinkNode)); header->Elem = 10 ; header->next = NULL ; } int main() { LinkNode *head = NULL ; CreateList(head); if (head != NULL ) printf( "%d\n" , head->Elem); free(head); return 0 ; } /* A: head---0 ---CreateList--- B: header---0 C: NODE B: header---C ---CreateList--- A: head---0 */ |
此做法無效,在函數內部修改header的地址,函數結束后回到main函數,head仍然是null。
我們可以修改其指向的變量的值,而不能修改指針本身的內容了。為了能夠修改指針本身的內容,我們需要傳遞指針本身的地址。所以在上面那例中,需要傳遞head指針本身的地址。代碼如下:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ #include "stdafx.h" #include <iostream> using namespace std; typedef struct Link_Node { int Elem; struct Link_Node *next; } LinkNode, *PLinkList; void CreateList(LinkNode **header) { int i = 0 ; (*header) = (LinkNode *)malloc( sizeof (LinkNode)); (*header)->Elem = 10 ; (*header)->next = NULL ; } int main() { LinkNode *head = NULL ; CreateList(&head); if (head != NULL ) printf( "%d\n" , head->Elem); free(head); return 0 ; } /* A: head---0 ---CreateList--- B: header---A C: NODE A: head---C B: header---A ---CreateList--- A: head---C */ |
下面我們再看一例,在函數內部修改指針指向的內容。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ #include "stdafx.h" #include <iostream> using namespace std; void Trans( int *Arr, int nLength) { for ( int i = 0 ; i < nLength; i++) { // modify content of *pointer Arr[i] += i + 20 ; } } int main() { int nArr[ 5 ] = { 0 }; int i; printf( "Before:\n" ); for (i = 0 ; i < 5 ; i++) printf( "%d " , nArr[i]); //0 0 0 0 0 Trans(nArr, 5 ); printf( "\nAfter\n" ); for (i = 0 ; i < 5 ; i++) printf( "%d " , nArr[i]); // 20 21 22 23 24 return 0 ; } |
http://blog.csdn.net/gamecreating/article/details/5382711
http://www.cnblogs.com/nezha/p/3204410.html
2. 指針vs數組
數組名不是變量!指針是變量!
數組名僅僅是一個符號,不是變量,它沒有自己的存儲空間,而指針是個變量,有自己的空間。
C標准有一條:當數組出現在函數的參數中時,無論是形參還是實參,都轉換為指針再進行操作。
http://blog.jobbole.com/44863/
3. 指針的指針
http://blog.jobbole.com/60647/
4. 數組指針vs指針數組
http://blog.csdn.net/touch_2011/article/details/6966980
http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html
簡單舉例說明:
int *p[2]; 首先聲明了一個數組,數組的元素是int型的指針。
int (*p)[2]; 聲明了一個指針, 指向了一個有兩個int元素的數組。(數組指針,也稱行指針)
其實這兩種寫法主要是因為運算符的優先級, 因為[]的優先級比*高。所以第一種寫法,p先和[]結合,所以是一個數組,后與*結合,是指針。后一種寫法同理。
指針數組如下處理就會很清楚: typedef int* intPtr; intPtr p[2]; 一目了然,所以為了避免迷惑,做適當的typedef也是很有必要的。
同理,數組指針也可以作類似處理: typedef int intArray2[2]; intArray2 * p; 和原來的聲明都是等價的。
數組指針(也稱行指針)
定義 int (*p)[n];
()優先級高,首先說明p是一個指針,指向一個整型的一維數組,這個一維數組的長度是n,也可以說是p的步長。也就是說執行p+1時,p要跨過n個整型數據的長度。
如要將二維數組賦給一指針,應這樣賦值:
int a[3][4];
int (*p)[4]; //該語句是定義一個數組指針,指向含4個元素的一維數組。
p=a; //將該二維數組的首地址賦給p,也就是a[0]或&a[0][0]
p++; //該語句執行過后,也就是p=p+1;p跨過行a[0][]指向了行a[1][]
所以數組指針也稱指向一維數組的指針,亦稱行指針。
指針數組
定義 int *p[n];
[]優先級高,先與p結合成為一個數組,再由int*說明這是一個整型指針數組,它有n個指針類型的數組元素。這里執行p+1是錯誤的,這樣賦值也是錯誤的:p=a;因為p是個不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它們分別是指針變量可以用來存放變量地址。但可以這樣 *p=a; 這里*p表示指針數組第一個元素的值,a的首地址的值。
如要將二維數組賦給一指針數組:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
這里int *p[3] 表示一個一維數組內存放着三個指針變量,分別是p[0]、p[1]、p[2]
所以要分別賦值。
這樣兩者的區別就豁然開朗了,數組指針只是一個指針變量,似乎是C語言里專門用來指向二維數組的,它占有內存中一個指針的存儲空間。指針數組是多個指針變量,以數組形式存在內存當中,占有多個指針的存儲空間。
還需要說明的一點就是,同時用來指向二維數組時,其引用和用數組名引用都是一樣的。
比如要表示數組中i行j列一個元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
優先級:()>[]>*
sizeof分析
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ int _tmain( int argc, _TCHAR *argv[]) { // array pointer int a[ 2 ][ 3 ] = { 1 , 2 , 3 , 4 , 5 , 6 }; int (*p)[ 3 ]; p = a; // test sizeof // for a cout << sizeof (a) << endl; // 24 cout << sizeof (a + 0 ) << endl; // 4 (24 in debug local watch) cout << sizeof (a + 1 ) << endl; // 4 (24 in debug local watch) cout << sizeof (a[ 0 ]) << endl; // 12 cout << sizeof (a[ 1 ]) << endl; // 12 cout << sizeof (*(a + 0 )) << endl; // 12 cout << sizeof (*(a + 1 )) << endl; // 12 cout << sizeof (a[ 0 ][ 0 ]) << endl; // 4 // for p cout << sizeof (p) << endl; // 4 cout << sizeof (p + 0 ) << endl; // 4 cout << sizeof (p + 1 ) << endl; // 4 cout << sizeof (p[ 0 ]) << endl; // 12 cout << sizeof (p[ 1 ]) << endl; // 12 cout << sizeof (*(p + 0 )) << endl; // 12 cout << sizeof (*(p + 1 )) << endl; // 12 cout << sizeof (p[ 0 ][ 0 ]) << endl; // 4 return 0 ; } |
5. 函數指針
http://www.cnblogs.com/nezha/p/3204410.html
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/6/3 */ typedef int (*func)( char a[], int nLength); int total( char a[], int nLength) { int nTotal = 0 ; for ( int i = 0 ; i < nLength; ++i) nTotal += a[i]; return nTotal; } int main() { char a[] = "abcde" ; int nLength = strlen(a); func fp; fp = total; printf( "%d\n" , fp(a, nLength)); return 0 ; } |
【本文鏈接】