考虑此程序:
#include <stdio.h>
int main()
{
double *dp;
double **dpp;
dpp=&dp;
dp++;
dpp++;
return 0;
}
假设dp
具有地址100,而dpp
的地址为1000。这些指针的地址在增加后是什么?
最简单的事情是使您的程序可编译并给予严格定义的行为,然后运行它。
#include <stdio.h>
int main(void)
{
double d[2] = { 3.141593, 2.718128 };
double *dp = &d[0];
double *dpa[2] = { &d[0], &d[1] };
double **dpp = dpa;
printf("dp = %pn", (void *)dp);
printf("dpp = %pn", (void *)dpp);
dp++;
dpp++;
printf("dp = %pn", (void *)dp);
printf("dpp = %pn", (void *)dpp);
return 0;
}
注意代码如何仔细确保指针始终指向有效数据。您可以将打印扩展到打印*dpp
(另一个指针)和**dpp
和*dp
(均为双重值)。
在我的机器上(Mac OS X 10.9.1,GCC 4.8.2,64位编译),输出为:
dp = 0x7fff56945510
dpp = 0x7fff56945520
dp = 0x7fff56945518
dpp = 0x7fff56945528
编译32位时,输出为:
dp = 0xbfffc600
dpp = 0xbfffc5f0
dp = 0xbfffc608
dpp = 0xbfffc5f4
dp
中8的跳跃是sizeof(double) == 8
的结果(对于32位和64位汇编)。32位汇编4的dpp
的更改和64位汇编的8个更改是sizeof(double *) == 4
的结果,32位的结果是CC_9,而sizeof(double *) == 8
的64位。
dp++
是未定义的行为,因为dp
从未初始化。无法保证会发生什么。
可能发生的事情会发生什么,尽管依靠这将是一个不当的决定,因为sizeof(double)
的内存数值会增加,而dpp
的数值被sizeof(double *)
递增。sizeof(double)
大概是8,sizeof(double *)
可能是4或8。
double *dp
=>是指向double的变量的指针(dp
的大小仅为4个字节)
double **dp1
=>是指向指针的指针,指向双重指向(dp1
的大小为4个字节)
指针的大小总是4个字节(假设32位机器;在64位机器上,是8个字节)即指针尺寸取决于内存地址的大小。
当您增加dp++
时,您将指向尺寸为8个字节的双重指向指向双字节,以使其增量为8个字节(100 => 108)。
当您将指针递增指针时,其大小为4个字节,因此仅增量4个字节(1000 => 1004)
指针增量取决于它指向的对象的类型。
在您的代码中,您尚未直接声明double
类型的变量;您有初始化的**dp1
,这将导致不确定的行为。
double a = 10.00;
dp = &a;
添加上面的两行以更好地理解您的代码(只是其中之一)。