0
void main()
{
   int a[]={3,5,6,10,2};
   int *p;
   p=&a;
   int **q;
   q=&p;
   p=p+2;
   (*p)++;
   printf("%u\n",p);
   printf(" %u \n",&a);
   printf("%u",q);
}

这给出的输出为:

738565800
738565792 
738565784

被打印出来的值怎么q总是比 a 的地址小 8 呢?有人可以解释这种关系吗?

4

4 回答 4

1

让我们从您的程序中删除不必要的杂物,并修复它以正确打印指针(如hacks建议的那样):

int a[]={3,5,6,10,2};
int *p;
printf("%p\n", (void*)&p);
printf("%p\n", (void*)&a);

它在您的系统上的行为方式相同(我不能确定;这种东西是依赖于实现的)。

编译器(或操作系统)按顺序(降序或升序 - 这可能不同)将地址分配给局部变量。似乎您的系统为源代码中前面声明的变量提供了更大的地址。

地址的不同是每个变量的大小(以字节为单位)。

您可以像这样可视化变量的存储:

+------+
| p    | (address 0x7fff759edd88)
| p    | (... continued at address 0x7fff759edd8c)
+------+
| a[0] | (address 0x7fff759edd90)
| a[1] | (address 0x7fff759edd94)
| a[2] | (address 0x7fff759edd98)
| a[3] | (address 0x7fff759edd9c)
| a[4] | (address 0x7fff759edda0)
+------+

请注意,您的原始程序p以一种相当迂回的方式打印地址(首先将其分配给q,然后打印q)。

于 2013-10-07T19:06:26.360 回答
1

使用%p说明符打印地址

printf("%p\n", (void*)p);
printf(" %p \n",(void *)&a);
printf("%p", (void *)q);  

使用%u说明符打印指针值会调用未定义的行为。%u预计unsigned int
您可以使用sizeof函数来计算这些类型的大小

printf("%zu\n",sizeof(p));    // 4
printf("%zu \n",sizeof(&a));  // 4 
printf("%zu",sizeof(q));      // 4
于 2013-10-07T18:17:47.923 回答
0

这不是您的问题(anatolyg 已回答您提出的问题),但您的类型不匹配。表达式的类型&aint (*)[5](指向 5 元素数组的指针int)。类型对于指针以及其他一切都很重要。假设你想p成为一个简单的指针int,你只需写

int *p;
p = a;

除非它是sizeofor 一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of T”类型的表达式将转换为“pointer to T”类型的表达式,表达式的值将是数组第一个元素的地址;&因此,在这种情况下 无需使用运算符。

另外,使用int main( void )代替void main().

这两个问题都应该被你的编译器标记出来;确保在启用所有警告的情况下进行编译。

于 2013-10-07T20:56:55.643 回答
0

在 C 语言级别上没有对代码行为的有意义的解释。您的代码示例包含错误代码以及产生未定义行为的代码。因此,您观察到的结果只能通过该未定义行为的半随机半实现相关表现来解释。

特别是,您的代码中存在以下问题。

p = &a;

这是非法的。&a具有类型int (*)[5],而p声明为int *。在 C 中不允许从这种不兼容的类型进行赋值。这是 C 中的约束违规,即通常应该导致编译错误

void main()

C 中的函数main需要返回int,而不是void

printf("%u\n",p);
printf(" %u \n",&a);
printf("%u",q);

尝试使用%u格式说明符打印指针值会导致未定义的行为。%u需要一个unsigned int参数,而不是一个指针参数。

现在,这种损坏代码的典型行为(如果你设法通过一些宽松的编译器强制它)通常会产生以下情况。q您观察到的值是指针p在内存中的位置。&a您观察到的值是数组a在内存中的位置。因此,您观察到的 8 个字节的差异仅仅意味着p并且a在内存中彼此相距 8 个字节。p位于较低地址,而a位于较高地址。这里的所有都是它的。

于 2013-10-07T21:33:12.650 回答