我尽可能地尝试这段代码,但我找不到原因?

时间:2014-09-04 08:16:45

标签: c

这是C中的程序及其输出

#include <stdio.h>
#include <conio.h>

void main()
{
    int i, t[4], s[4];

    for(i=0;i<=3;i++)
    {
        printf("\n%d",&s[i]);
        printf("  %d",&t[i]);
    }

    for(i=0;i<=3;i++)
    {
        printf("\n%d %d",&s[i],&t[i]);
    }
}

输出:

8600 8608
8602 8610
8604 8612
8606 8614

8600 8641
8602 8641
8604 8641
8606 8641

我想知道在第二个for循环语句中发生了什么,与第一个for循环不同。

3 个答案:

答案 0 :(得分:4)

程序中唯一明显的问题是您传递的对应于printf %d格式的指针参数。这是未定义的行为。它可能适用于某些编译平台,但你不应该依赖它。

最可能的解释是,在您的平台上,将指针参数传递给可变参数函数(如printf)的ABI与传递int参数的ABI不同。据我们所知,在您的平台上,指针的宽度与int的宽度不同。

使用%p格式打印指针。或者更好的是,使用printf("%p", (void*)…);,这是更可移植的,以防所有指针类型都没有相同的表示。

答案 1 :(得分:2)

问题是您使用错误的格式代码来打印指针。正如@PascalCuoq所说,你应该使用%p,而不是%d

原因是你的系统上的指针和整数大小明显不同。

当您将两个指针传递给不同的printf个调用%d时,将打印指针值的第一部分。

当您将两个指针传递给同一个printf调用时,获取错误的长度将意味着它将打印两个不与任一指针对齐的不同值。

答案 2 :(得分:1)

你的printf语句正在打印一个整数,让你放一个指针(&t[i]表示 t i 元素的地址数组)。

整数和指针不一定是相同的字节数,printf的大多数实现从每个%字段的堆栈中获取固定数量的字节。此外,当printf从堆栈中获取其字段数据时,机器的'endianism'将确定地址的最小位或最高位是否以整数形式使用。看起来你在16位机器上运行24位地址和LSB排序 - 某种微控制器,我猜。

您的数组位于内存地址(从输出转换为十六进制: s :0xC12198 t :0xC121A0 (我认为24位地址。)

第一个循环在不同的printf语句中单独处理每个数组,因此您可以看到每个数组的最低有效位随每次迭代递增。

第二个循环尝试在一个`printf中处理两个数组。所以你得到的值表示其中一个地址的递增部分,加上第二个是地址的最重要部分,它没有递增,而第二个数组的地址根本没有输出。