输出指针程序

时间:2013-04-10 12:14:12

标签: c pointers

我对指针知之甚少。

我遇到了以下程序。输出似乎正常,但实际上发生的事情我无法理解。

#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]);
     }
}

4 个答案:

答案 0 :(得分: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[]的元素。

答案 1 :(得分: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

答案 2 :(得分:0)

以下是发生的事情:

您定义数据类型k

的变量int

您定义的数组a的值为1, 2, 3

您定义了一个指针数组b

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

.................................和类似的f

您从0迭代到2,并将值分配给bcd,......最多f

你再次从0迭代到2并打印:

b中每个元素指向的值,c,.....高达f

编辑:发生了什么b [k] = a + k,你在你的记忆中前进了k个区块,其地址被分配给b [k],所以,b [k]点在你的记忆中的那个块(可能是任何值)

答案 3 :(得分:0)

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

a[]是一个包含3个元素1, 2, and 3的数组,a本身引用数组的0th元素,即a是该元素的地址数组的第一个元素。

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

因此,考虑循环的第一遍,并且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]

现在这些事情发生在你使用的每个数组中,只需要额外的指针级别。这意味着,您将保留前一个数组元素的地址。