2015-10-26 138 views
0

下面是我創建的一個示例程序,用於指針的使用。解引用雙指針,三指針等

#include <iostream> 
using namespace std; 

void addOne(int** ptr); 
void addTwo(int*** ptr); 
void addThree(int**** ptr); 
void addFour(int***** ptr); 

int main() 
{ 
    int* ptr = nullptr; 
    int x = 1; 
    ptr = &x; 

    cout << "Original value of x: " << *ptr << endl; 

    addOne(&ptr); 

    cin.get(); 
    return 0; 
} 

void addOne(int** ptr) 
{ 
    **ptr += 1; 
    cout << "After adding 1: " << **ptr << endl; 
    addTwo(&ptr); 
} 

void addTwo(int*** ptr) 
{ 
    ***ptr += 2; 
    cout << "After adding 2: " << ***ptr << endl; 
    addThree(&ptr); 
} 

void addThree(int**** ptr) 
{ 
    ****ptr += 3; 
    cout << "After adding 3: " << ****ptr << endl; 
    addFour(&ptr); 
} 

void addFour(int***** ptr) 
{ 
    *****ptr += 4; 
    cout << "After adding 4: " << *****ptr << endl; 
} 

上面的程序給我下面的輸出:

Original value of x: 1 
After adding 1: 2 
After adding 2: 4 
After adding 3: 7 
After adding 4: 11 

現在專注於addFour功能:

void addFour(int***** ptr) 
{ 
    *****ptr += 4; 
    cout << "After adding 4: " << *****ptr << endl; 
} 

現在我所做的就是我減少* S的數量在addFour函數中這樣做:

void addFour(int***** ptr) 
{ 
    ****ptr += 4; 
    cout << "After adding 4: " << ****ptr << endl; 
} 

當我做了上面的代碼,它給了我下面的輸出:

Original value of x: 1 
After adding 1: 2 
After adding 2: 4 
After adding 3: 7 
After adding 4: 010EFDE0 

我的問題則是,什麼是下面的語句做,因爲我減少* S的數量:

****ptr += 4; 
cout << "After adding 4: " << ****ptr << endl; 

有人可以爲我解釋這個嗎?

+7

你到底想幹什麼? –

+0

我試圖觀察指針的行爲。這是在課堂上討論的。我只是想了解發生了什麼。 – Omicron

+0

@Omicron如果你真的想寫C++代碼,最好忘記指針。對於99%的真實世界用例,根本不需要它們(不管星號有多少)。 –

回答

3

您將addFour中的解除引用減少爲四個級別,但該功能仍需要int*****

大部分代碼是無關緊要的,可以降低到這樣的事情:

int x = 1; 

cout << "Original value of x: " << *&x << endl; 
x += 1; 
cout << "After adding 1: " << **&&x << endl; 
x += 2; 
cout << "After adding 2: " << ***&&&x << endl; 
x += 3; 
cout << "After adding 3: " << ****&&&&x << endl; 
x += 4; 
cout << "After adding 4: " << *****&&&&&x << endl; 

到目前爲止,您的提領操作地址和抵消。但你要問這是什麼:

cout << "After adding 4: " << ****&&&&&x << endl; 

很簡單,你沒有那麼留給你的&x,不x進行最後的解引用。

&x是一個指針。在上面的例子中,你會看到內存中的地址x,以十六進制表示。在你的情況下,你的ptr有一個未指定的值,因爲超出對象邊界的指針算術有未定義的行爲,但實際上你打印的地址值爲x加上sizeof(int)

+0

換言之,聲明:'**** ptr + = 4; cout <<「在添加4之後:」<< **** ptr << endl;'正在處理三層指針變量本身的內容?而不是對指針ptr的引用的內容? – Omicron

+1

@Omicron:不知道你剛剛說了什麼,對不起。 _「指針ptr的引用內容」_ ?? –

+0

我的意思是,聲明:'**** ptr + = 4;'將四個添加到存儲在ptr指針變量中的地址? – Omicron

1

addOne收到ptr的地址,指向x並將其存儲到本地變量ptr中。

addTwo收到地址addOne::ptr並將其存儲在其本地ptr變量中。

addThree收到地址addTwo::ptr並將其存儲在其本地ptr變量中。

addFour收到地址addThree::ptr並將其存儲在其當地的ptr變量中。因此,在addFour(第二版):

  • *ptraddThree::ptr
  • **ptraddTwo::ptr
  • ***ptraddOne::ptr
  • ****ptrmain::ptr

然後,您將int指針增加4,從而計算從地址x開始的第四個int的地址,然後打印該地址。

當然,在第一個版本*****ptrmain::x,然後由4

1

試圖以圖形可視化這個增量INT x,您有:

P -> P -> P -> P -> P -> X 

X是價值,P是指針。
每次你寫&,你都會移動到左邊,每次你寫*時,你都會向右移動。

所以,如果你有&&&&&x,你增加****x,你這樣做:

P -> P -> P -> P -> P -> X 
         \ 
         > ? 

您移動四個層次的權利,並且增加指針在那裏,這現在指向X.後的存儲位置

然後您打印****x,這是一個指針,因爲您向右移動了四個級別。

+0

即使有更好的理解,請注意'&&&&& x'是無效的C++。 – Jarod42

-1
 // if you want to understand pointers this is my fave example 

    struct block 
     { 
     int data; 
     struct block *next_block; 
     }; 

    struct block *block_head = NULL; 

    add_block(int n) /* add n in the sorted position */ 
    { 
     struct block *new, *prev = NULL, *bp = block_head; 

     new = malloc(sizeof(struct block)); 
     new->data = n; 
     while(bp != NULL) 
      if(bp->data > n) 
      { 
       prev = bp; 
       bp = bp->next_block; 
      } 
      else 
      { 
       if(prev == NULL) 
       {    
        new->next_block = bp; 
        block_head = new; 
       } 
       else 
       { 
        new->next_block = bp; 
        prev->next_block = new; 
       } 

    if(block_head == NULL) 
     block_head = new; 
    else 
     { 
     prev->next_block = new; 
     new->next_block = NULL; 
     } 
} 

// the above is how you usually do a linked list but it's messy and ugly 
// not elegant 
// the elegant way to do this is with a double pointer 

    add_block(int n) /* add n in the sorted position */ 
    { 
     struct block *new, **bp = &block_head; 

     new = malloc(sizeof(struct block)); 
     new->data = n; 
     while(*bp != NULL) 
      if((*bp)->data > n) 
       bp = &((*bp)->next_block); 
      else 
       break; 
     new->next_block = *bp; 
     *bp = new; 
} 

// if you can understand the elegant version, you probably got pointers down cold. 
+0

謝謝你。我很感激幫助。 – Omicron

+1

這是如何相關? –

+0

我認爲這可能會幫助他給他一個具體的實際使用雙指針。你們需要放鬆一下。 –