为什么这两个文件有不同的十六进制输出?

时间:2016-11-01 18:09:30

标签: c gcc hex

我正在经历K&amp; R并决定做一个实验。在K&amp; R中,首先教授while循环,然后教授for循环。在这样做时,同一程序使用while循环和for循环编写。这些程序具有相同的输出和功能相同的功能。然后我想用vim -d <(xxd celsius) <(xxd ccelsius)比较两个二进制文件,并认为它们是同一个文件;但是,他们不是。虽然文件的某些部分是相同的,但也存在显着差异。我想知道为什么存在这些差异,以及是否有任何方法可以使文件编译为相同的二进制文件。我使用gcc作为我的编译器。

C档案

celsius.c

#include <stdio.h>

/* print Fahrenheit-Celsius table
 *  for fahr = 0, 20, ..., 300; floating-point version */
int main(void)
{
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;  /* lower limit of temperature table */
    upper = 300;    /* upper limit */
    step = 20;  /* step size */

    fahr = lower;
    while (fahr <= upper) {
        celsius = (5.0/9.0) * (fahr-32.0);
        printf("%3.0f %6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
}

ccelcius.c

#include <stdio.h>

/* print Fahrenheit-Celsius table */
int main(void)
{
    float fahr;

    for (fahr = 0; fahr <= 300; fahr = fahr + 20)
        printf("%3.0f %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

十六进制差异文件

diff <(xxd celsius) <(xxd ccelsius)

14,15c14,15
< 000000d0: c00e 0000 0100 0000 a700 0000 0000 0000  ................
< 000000e0: c00e 0000 0400 0000 0000 0000 0000 0000  ................
---
> 000000d0: e00e 0000 0100 0000 8d00 0000 0000 0000  ................
> 000000e0: e00e 0000 0400 0000 0000 0000 0000 0000  ................
19,20c19,20
< 00000120: 680f 0000 0100 0000 0600 0000 0000 0000  h...............
< 00000130: 680f 0000 0100 0000 0000 0000 0000 0000  h...............
---
> 00000120: 6e0f 0000 0100 0000 0600 0000 0000 0000  n...............
> 00000130: 6e0f 0000 0100 0000 0000 0000 0000 0000  n...............
24,25c24,25
< 00000170: 700f 0000 0100 0000 1a00 0000 0000 0000  p...............
< 00000180: 700f 0000 0200 0000 0000 0000 0000 0000  p...............
---
> 00000170: 740f 0000 0100 0000 1a00 0000 0000 0000  t...............
> 00000180: 740f 0000 0200 0000 0000 0000 0000 0000  t...............
29c29
< 000001c0: 900f 0000 0100 0000 0c00 0000 0000 0000  ................
---
> 000001c0: 900f 0000 0100 0000 1800 0000 0000 0000  ................
34,35c34,35
< 00000210: 9c0f 0000 0100 0000 0d00 0000 0000 0000  ................
< 00000220: 9c0f 0000 0000 0000 0000 0000 0000 0000  ................
---
> 00000210: a80f 0000 0100 0000 0b00 0000 0000 0000  ................
> 00000220: a80f 0000 0000 0000 0000 0000 0000 0000  ................
39,40c39,40
< 00000260: ac0f 0000 0100 0000 4800 0000 0000 0000  ........H.......
< 00000270: ac0f 0000 0200 0000 0000 0000 0000 0000  ................
---
> 00000260: b40f 0000 0100 0000 4800 0000 0000 0000  ........H.......
> 00000270: b40f 0000 0200 0000 0000 0000 0000 0000  ................
73c73
< 00000480: 1985 c866 b4a1 304e 965d 4a68 80be 0434  ...f..0N.]Jh...4
---
> 00000480: 37e9 3480 21a8 3e96 b783 ea6a 3feb 00d8  7.4.!.>....j?...
76c76
< 000004b0: 2800 0080 1800 0000 c00e 0000 0000 0000  (...............
---
> 000004b0: 2800 0080 1800 0000 e00e 0000 0000 0000  (...............
237,256c237,256
< 00000ec0: 5548 89e5 4883 ec20 c745 fc00 0000 00c7  UH..H.. .E......
< 00000ed0: 45f0 0000 0000 c745 ec2c 0100 00c7 45e8  E......E.,....E.
< 00000ee0: 1400 0000 f30f 2a45 f0f3 0f11 45f8 f30f  ......*E....E...
< 00000ef0: 1045 f8f3 0f2a 4dec 0f2e c80f 825d 0000  .E...*M......]..
< 00000f00: 0048 8d3d 9400 0000 f20f 1005 8000 0000  .H.=............
< 00000f10: f30f 100d 8000 0000 f30f 1055 f8f3 0f5c  ...........U...\
< 00000f20: d1f3 0f5a caf2 0f59 c1f2 0f5a c0f3 0f11  ...Z...Y...Z....
< 00000f30: 45f4 f30f 5a45 f8f3 0f5a 4df4 b002 e825  E...ZE...ZM....%
< 00000f40: 0000 00f3 0f10 45f8 f30f 2a4d e8f3 0f58  ......E...*M...X
< 00000f50: c1f3 0f11 45f8 8945 e4e9 90ff ffff 8b45  ....E..E.......E
< 00000f60: fc48 83c4 205d c390 ff25 a200 0000 0000  .H.. ]...%......
< 00000f70: 4c8d 1d91 0000 0041 53ff 2581 0000 0090  L......AS.%.....
< 00000f80: 6800 0000 00e9 e6ff ffff 0000 0000 0000  h...............
< 00000f90: 721c c771 1cc7 e13f 0000 0042 2533 2e30  r..q...?...B%3.0
< 00000fa0: 6620 2536 2e31 660a 0000 0000 0100 0000  f %6.1f.........
< 00000fb0: 1c00 0000 0000 0000 1c00 0000 0000 0000  ................
< 00000fc0: 1c00 0000 0200 0000 c00e 0000 3400 0000  ............4...
< 00000fd0: 3400 0000 680f 0000 0000 0000 3400 0000  4...h.......4...
< 00000fe0: 0300 0000 0c00 0100 1000 0100 0000 0000  ................
< 00000ff0: 0000 0001 0000 0000 0000 0000 0000 0000  ................
---
> 00000ec0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
> 00000ed0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
> 00000ee0: 5548 89e5 4883 ec20 0f57 c0c7 45fc 0000  UH..H.. .W..E...
> 00000ef0: 0000 f30f 1145 f8f3 0f10 0591 0000 000f  .....E..........
> 00000f00: 2e45 f80f 825b 0000 0048 8d3d 9800 0000  .E...[...H.=....
> 00000f10: f20f 1005 8800 0000 f30f 100d 7400 0000  ............t...
> 00000f20: f30f 5a55 f8f3 0f10 5df8 f30f 5cd9 f30f  ..ZU....]...\...
> 00000f30: 5acb f20f 59c1 f20f 1145 f00f 28c2 f20f  Z...Y....E..(...
> 00000f40: 104d f0b0 02e8 2400 0000 8945 ecf3 0f10  .M....$....E....
> 00000f50: 0543 0000 00f3 0f58 45f8 f30f 1145 f8e9  .C.....XE....E..
> 00000f60: 93ff ffff 8b45 fc48 83c4 205d c390 ff25  .....E.H.. ]...%
> 00000f70: 9c00 0000 4c8d 1d8d 0000 0041 53ff 257d  ....L......AS.%}
> 00000f80: 0000 0090 6800 0000 00e9 e6ff ffff 0000  ....h...........
> 00000f90: 0000 9643 0000 0042 0000 a041 0000 0000  ...C...B...A....
> 00000fa0: 721c c771 1cc7 e13f 2533 6420 2536 2e31  r..q...?%3d %6.1
> 00000fb0: 660a 0000 0100 0000 1c00 0000 0000 0000  f...............
> 00000fc0: 1c00 0000 0000 0000 1c00 0000 0200 0000  ................
> 00000fd0: e00e 0000 3400 0000 3400 0000 6e0f 0000  ....4...4...n...
> 00000fe0: 0000 0000 3400 0000 0300 0000 0c00 0100  ....4...........
> 00000ff0: 1000 0100 0000 0000 0000 0001 0000 0000  ................
258c258
< 00001010: 800f 0000 0100 0000 0000 0000 0000 0000  ................
---
> 00001010: 840f 0000 0100 0000 0000 0000 0000 0000  ................
518,519c518,519
< 00002050: 2502 0000 0003 00c0 1d00 0000 0000 0000  %...............
< 00002060: c01d 0000 0000 0000 0200 0000 0f01 1000  ................
---
> 00002050: 2502 0000 0003 00e0 1d00 0000 0000 0000  %...............
> 00002060: e01d 0000 0000 0000 0200 0000 0f01 1000  ................
521c521
< 00002080: c00e 0000 0100 0000 1c00 0000 0100 0001  ................
---
> 00002080: e00e 0000 0100 0000 1c00 0000 0100 0001  ................

2 个答案:

答案 0 :(得分:3)

在第一个例子中

celsius = (5.0/9.0) * (fahr-32.0);

使用double计算结果,然后将其截断为float,然后将其提升回double以使用%f格式打印。< / p>

在第二个示例中,计算再次使用double

printf("%3.0f %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

float没有截断,因为预计会有double。因此计算结果略有不同。

答案 1 :(得分:1)

如果你进行了反汇编的差异,那么当使用优化编译时,结果几乎完全相同,即使二进制文件没有完全匹配(我已经改变了两个源文件以仅使用浮点数,因为天气风向标的评论):

<强> celsius.c

#include <stdio.h>

/* print Fahrenheit-Celsius table
 *  for fahr = 0, 20, ..., 300; floating-point version */
int main(void)
{
    float fahr, celsius;
    static const int lower = 0;
    static const int upper = 300;
    static const int step = 20;

    fahr = lower;
    while (fahr <= upper) {
        celsius = (5.0f/9.0f) * (fahr-32.0f);
        printf("%3.0f %6.1f\n", fahr, celsius);
        fahr = fahr + step;
    }
}

<强> ccelsius.c

#include <stdio.h>

/* print Fahrenheit-Celsius table */
int main(void)
{
    float fahr;

    for (fahr = 0; fahr <= 300; fahr = fahr + 20)
        printf("%3.0f %6.1f\n", fahr, (5.0f/9.0f)*(fahr-32.0f));
}

编译     cc -Wall -O3 celsius.c -o celsius&amp;&amp; cc -Wall -O3 ccelsius.c -o ccelsius

diff&lt;(objdump -d celsius)&lt;(objdump -d ccelsius)

2c2
< celsius:     file format elf64-x86-64
---
> ccelsius:     file format elf64-x86-64