程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c/c++指針總結[pointer summary]

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

編輯:C++入門知識

【本文鏈接】

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved