我对指针知之甚少。
我遇到了以下程序。输出似乎正常,但实际上发生的事情我无法理解。
#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 :(得分: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,并将值分配给b
,c
,d
,......最多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]
。
现在这些事情发生在你使用的每个数组中,只需要额外的指针级别。这意味着,您将保留前一个数组元素的地址。