2015-10-26 169 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

我认为这可能会帮助他给他一个具体的实际使用双指针。你们需要放松一下。 –