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

4 回答 4

2

第一个for循环只是基本的指针运算。a[]持有ints,之后的每个数组都持有一个指针。
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[]一遍又一遍地打印元素。

于 2013-04-10T12:40:00.387 回答
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]);
     }

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

对于一个有趣的阅读,也看到这个

于 2013-04-10T12:24:33.463 回答
0

这是发生的事情:

您定义一个k 数据类型的变量int

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

你定义了一个指针数组,b

你定义了一个指针数组,c

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

您从 0 迭代到 2,并将值分配给b, c, d, .... uptof

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

b, c, ..... upto中的每个元素所指向的值f

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

于 2013-04-10T12:22:57.137 回答
0

首先尝试了解正在b[k] = a + k做什么。其余的都是一样的。

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

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

因此,考虑循环的第 1 遍,并且 k = 0。

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

而对于c[0] = b + 0,你正在存储一个address of address of int,所以c被声明为双指针int **c[3]

现在这些事情发生在你使用的每个数组上,只是多了一层指针。这意味着,您持有前一个数组元素的地址。

于 2013-04-10T12:26:59.467 回答