2013-04-10 50 views
3

我对指针的了解不多。指针程序的输出

我遇到以下程序。输出看起来很正常,但实际发生的事情我无法弄清楚。

#include<stdio.h> 
#include<conio.h> 
void main() 
{ 
    int k; 
    int a[] = {1,2,3}; int *b[3] ; int **c[3]; 
    int ***d[3]; int ****e[3]; int*****f[3]; 
    for (k = 0 ; k <3; k++) 
    { 
     b[k] = a + k; c[k] = b + k ; d[k] = c + k; 
     e[k] = d + k ; f[k] = e + k; 

    } 
    for (k = 0 ; k <3; k++) 
    { 
     printf("%3d", *b[k]); printf("%3d", **c[k]); 
     printf("%3d", ***d[k]); printf("%3d", ****e[k]); 
     printf("%3d\n", *****f[k]); 
    } 
} 
+0

是这个功课还是有人试图惹你?把那个人打了一遍,然后回答他:-) – 2013-04-10 12:35:27

+0

我发现这对工程考试的老问题 – 2013-04-10 12:39:55

+0

是的,这解释:-) – 2013-04-10 12:40:45

回答

2

第一个for循环只是基本的指针算术。 a[]持有int s,之后的每个数组都包含一个指针。
b[]是一个指向int
c[]是一个指针,指针int

所以它的东西,像这样的记忆:

Memory Address:  0x00441234 <---+ 0x00441238 <----+  0x0044123C <---+ 
        **********  | **********  |  **********  | 
var name:   * a (+0) *  | * a (+1) *  |  * a (+2) *  | 
        **********  | **********  |  **********  | 
value:    * 1 *  | * 2 *  |  * 3 *  | 
        **********  | **********  |  **********  | 
            |     |     | 
            |     |     | 
        +-> 0x00442345 | +->0x00442349  | +->0x0044234D  | 
        | ************ | | ************ | | ************ | 
        | * b (+0) * | | * b (+1) * | | * b (+2) * | 
        | ************ | | ************ | | ************ | 
        | *0x00441234* -+ | *0x00441238* --+ | *0x0044123C* --+ 
        | ************ | ************  | ************  
        |     |     | 
        |     |     | 
        | 0x00443345  | 0x00443349  | 0x0044334D  
        | ************ | ************  | ************  
        | * c (+0) * | * c (+1) *  | * c (+2) *  
        | ************ | ************  | ************  
        +-- *0x00442345* +-*0x00442349*  +-*0x0044234D* 
         ************  ************  ************  

而且给每个元素的D点每一个元素C等等。最终的结果是你将每个数组中的每个元素(通过一些指针链)重新设置为a的元素。然后在第二个for循环中,您将一遍又一遍地打印a[]的元素。

+0

你是5-6手吗?和5-6键盘?:-) – 2013-04-10 12:41:31

+0

@Koushik他可能有[this](http://www.asciiflow.com/#Draw)。 ;) – 2013-04-10 12:44:43

+0

@SuvP哦哇,这是一个不错的链接。谢谢。 – 2013-04-10 12:46:01

0

这里是发生了什么:

您定义的数据类型的变量kint

你定义一个数组,a有值,1, 2, 3

你定义一个指针数组,b

您定义了一个数组指向指针的指针,c

.................................和高达f

类似的

您从0迭代到2,并且分配值bcd,....高达f

您再次从0迭代到2和印刷:

由每个元件在b指出的值,c,..... upto f

EDIT:发生了什么b [k] = a + k,你是否在你的记忆中前进了k个块,其地址被分配给了b [k],所以b [k]指向你的块内存,(可以是任何值)

+0

@Rohit:看到编辑 – cipher 2013-04-10 12:32:03

1
 int k; 
    int a[] = {1,2,3}; //array of 3 ints 
    int *b[3] ; //array of 3 integer pointers 
    int **c[3]; //array of 3 integer double pointers 
    int ***d[3]; //array of 3 pointers to integer double pointers 
    int ****e[3]; //array of 3 pointers to pointers to integer double pointers 
    int*****f[3]; //array of 3 pointers to pointers to pointers to integer double pointers 
    for (k = 0 ; k <3; k++) 
    { 
     b[k] = a + k; 
      //a gives base address to array a 
      //Add k to it and store it in b[k]. Note, this isn't normal arithmetic its 
      //pointer aritmetic 
     c[k] = b + k ; 
     d[k] = c + k; 
     e[k] = d + k ; 
     f[k] = e + k; 
    } 
    for (k = 0 ; k <3; k++) 
    { 
     printf("%3d", *b[k]); //dereference single level pointer 
     printf("%3d", **c[k]); //dereference second level pointer 
     printf("%3d", ***d[k]); printf("%3d", ****e[k]); 
     printf("%3d\n", *****f[k]); 
    } 

你可以有任意数量的指针级别。即指向(指向...的指针)等等[达到由标准定义的限制]

有关有趣的阅读,请参阅this

0

首先尝试了解b[k] = a + k在做什么。休息是一样的。

a[]是具有3个元素1, 2, and 3a阵列本身指的是阵列的0th元件,即a是数组的第一元素的地址。

现在a + k,在指针算术中,表示名为a的数组的kth元素。

因此,考虑循环的第一遍,且k = 0

你的第一个语句变成b[0] = a + 0。通知a + 0是一个地址,它被一个元素b包含。因此,b应该是int *的类型,并且在您的代码中它声明为int *b[3]

而对于c[0] = b + 0,您存储的是address of address of int,所以c被声明为双指针int **c[3]

现在,这些事情发生在您使用的每个数组上,只是具有额外级别的指针。这意味着,您持有前一个数组元素的地址。