【发布时间】:2016-11-02 02:55:46
【问题描述】:
我正在经历 K&R 并决定做一个实验。在 K&R 中,首先教导 while 循环,然后教导 for 循环。在这样做的过程中,同一个程序是用while 循环和for 循环编写的。这些程序都有相同的输出并且在功能上做同样的事情。然后我想用vim -d <(xxd celsius) <(xxd ccelsius)比较两个二进制文件,并认为它们是同一个文件;但是,它们不是。虽然文件的某些部分相同,但也存在显着差异。我想知道为什么存在这些差异,以及是否有任何方法可以使文件编译为相同的二进制文件。我使用gcc 作为我的编译器。
C 文件
摄氏度.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 ................
【问题讨论】:
-
用
-S编译得到两个程序的汇编代码。汇编代码的区别会更容易理解。 -
@user3386109 我确实这样做了。不幸的是,我不太了解汇编,但它比十六进制要清楚得多。不过,我肯定会做得更多。我真的有助于了解程序的实际外观。
-
编译器并不完美。他们不会产生最好的二进制文件(假设存在给定源程序的最佳二进制版本)。它们只是产生源程序的正确二进制表示,并且有许多不同的二进制文件可以产生相同的输出。因此,如果您为编译器提供两个不同的源程序,那么您将获得不同的二进制文件也就不足为奇了。
-
cc不是特定的编译器,而是系统默认使用的别名。 -
@Olaf 哎呀。我会解决的。
cc是我机器上gcc的别名。