【问题标题】:why different answers?为什么不同的答案?
【发布时间】:2010-09-03 19:38:59
【问题描述】:

以下是 2 个程序

第一

#include<stdio.h>

void main()
{
    int a[5]={1,2,3,4,5};
    int *p;
    p=&a;
    printf("%u %u",p,p+1);
}

第二

#include<stdio.h>

void main()
{
    int a[5]={1,2,3,4,5};
    printf("%u %u",&a,&a+1);
}

现在,在这两个程序中..我在第一个代码中使用 p 打印了 &a 的值,在第二个代码中直接打印了..

为什么结果不同?

我得到的答案是。

for first  3219048884  3219048888
for second 3219048884  3219048904

【问题讨论】:

  • 您能用编辑器中的代码按钮格式化您的代码行吗?让人们更容易提供帮助。
  • 你得到了什么结果?
  • 你看到了什么结果?
  • 其他人在这里指出了问题。我要补充一点:用%u 打印指针是个坏消息。使用%p。此外,出于调试目的以外的任何原因打印指针都没有任何意义。
  • 不要使用void main();使用 int main()int main(void) 或 ...

标签: c arrays pointers


【解决方案1】:

&amp;a 的类型是int (*) [5]。因此&amp;a+1 是一个比a 多5 个ints 的指针。但是p 的类型是int *,因此p+1 是一个比p 更远的指针int

【讨论】:

  • 是的,但这与问题无关,除了系列的最后一个值
  • @kriss:这怎么不相关?这是每个序列中的最后一个值不同,这就是原因。
  • 你的编译器可能是,我的每组值在每次运行时都不同。 C 标准不保证堆栈地址的稳定性。由于 OP 展示了两个程序,因此每次运行时两个输出可能完全不同(它们在我的系统上)。如果我们将这两个程序合二为一,您的回答就很好。
  • @kriss:哦,我明白了。这是一个公平的观点。但是,鉴于 OP 的示例输出,我认为很明显他指的是不同的最后一个值。
【解决方案2】:

当我运行它时,我得到了这个:

1245036 1245040 1245036 1245040
1245036 1245040 1245036 1245056

唯一的区别是在最后一个位置,p+1 vs &amp;a+1

p 是一个指向整数的指针,所以p+1 是下一个整数的地址。 (即内存中的 4 个字节)

a 是一个由 5 个整数组成的数组,所以 &a+1 是下一个由 5 个整数组成的数组的地址。 (即,内存中还有 20 个字节)

【讨论】:

    【解决方案3】:

    在这两个程序中,您都在打印数组的内存地址。

    每次运行程序时,这可能会有所不同。操作系统选择给你的内存可能不同。

    当你的程序声明一个由 5 个整数组成的数组时,操作系统承诺给你 5 个连续的整数,它不承诺你会得到什么内存,或者你每次都会得到相同的内存。

    【讨论】:

      【解决方案4】:

      您有两个具有不同堆栈帧的程序,难怪局部变量的地址不同。每次运行程序时,我可能会改变(这就是我尝试它时所做的,在 Linux 上使用 gcc 编译的代码)。

      但是你会在下面的程序中得到相同的值,除了系列的最后一个值(最后一个除外,因为指针算术的工作方式)。

      #include<stdio.h>
      
      void main()  
      { 
          int a[5]={1,2,3,4,5};  
          int *p; 
          p=&a; 
          printf("%u %u %u %u ",a,a+1,p,p+1);
          printf("%u %u %u %u",a,a+1,&a,&a+1);
      }
      

      对于指针和数组之间差异的(相当)完整的解释,您可以查看我的答案here

      【讨论】:

        【解决方案5】:

        您的第一个程序无效。分配p = &amp;a 是非法的,因为p 的类型为int *&amp;a 的类型为int (*)[5]。这些类型不兼容。如果您的编译器足够宽松以允许这种分配(它至少警告过您吗?),它可能将其解释为p = (int *) &amp;a,即它强制将&amp;a 的值重新解释为int * 指针。因此,您的第一个程序中的所有指针算术都是int * 算术。这就是为什么第一个程序为 a+1p+1 值产生相同的输出。

        在第二个程序中,&amp;a 的值没有被重新解释。它保持其原始类型 ``int ()[5]and it follows the rules of normal pointer arithmetic for typeint ()[5], meaning that when you do&a + 1, the pointer is movedsizeof(int[5])` 字节,因为它应该。这就是结果与第一个程序不同的原因。

        【讨论】:

          【解决方案6】:

          您应该使用p = a 而不是p = &amp;a。像a 这样的数组已经被假定为一个常量指针。您无需使用 &amp; 运算符取消引用它。

          【讨论】:

          • @GMan 那你为什么说*a = 2a[0] = 2 意思一样呢?
          • 因为数组隐式转换为指针。但是数组不是指针。
          猜你喜欢
          • 2014-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多