c/c++指針總結[pointer summary]


【本文鏈接】

http://www.cnblogs.com/hellogiser/p/pointer-summary.html

1.指針注意事項

(1). 指針類型字符串不容許修改

char *str1=”abcd”; char str2[]=”abcd”;的區別。指針類型的字符串一般不允許修改,如:str1[0]=’c’;這樣的語句會導致運行時錯誤。

 C++ Code 
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只是你傳遞進去的參數的一個副本。而數組傳遞的時候,會退化為指針,其將數組的首地址復制給形參。看下面的一個例子。

 C++ Code 
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指針的同學想在函數內部修改作為參數傳遞進來的指針的值。看以下代碼:

 C++ Code 
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指針本身的地址。代碼如下:

 C++ Code 
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
*/

下面我們再看一例,在函數內部修改指針指向的內容。

 C++ Code 
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分析

 C++ Code 
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

 C++ Code 
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 ;
}

【本文鏈接】

http://www.cnblogs.com/hellogiser/p/pointer-summary.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM