首页 > 试题广场 >

假设在一个 32 位 little endian 的机器上运

[单选题]
假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include <stdio.h>
int main(){
  long long a = 1, b = 2, c = 3; 
  printf("%d %d %d\n", a, b, c);  
 return 0;
}
  • 1,2,3
  • 1,0,2
  • 1,3,2
  • 3,2,1

注:
1 printf()是一个库函数,C,C++中函数的参数是从右往左入栈的;
2 栈的生长方向是从高往低的
3 小端模式是低位存储在低字节
4 %d格式输出的是4个字节大小,而long long为8个字节

所以,a=1,b=0,c=2

发表于 2015-10-08 15:53:51 回复(24)
printf函数的原型是printf(const char*,...);
第二个参数是任意个数目的参数,所以printf函数不是分个把参数入栈,而是一股脑全部压入堆栈,因此对于8字节的数据来说,堆栈中的数据是1000 0000 2000 0000 3000 0000,%d按四字节输出,因此,第一个%d输出1,第二个%d输出0,第三个%d输出2。
如果改成printf("%d  ", a);printf("%d  ", b);printf("%d\n", c);那结果就是1,2,3.
发表于 2015-04-29 16:49:01 回复(11)
在栈中分配空间是逆向的 a。b。 c。 (高地址。到地址) 又因为是小端存储(低位存放到低地址处) 0000 0001 0000 0002 0000 0003 printf函数 参数入栈是 从右到左入栈的 所以c先入栈,然后b 最后c入栈 栈底---c-------b--------a---栈顶 0000 0003 0000 0002 0000 0001 出栈时 从栈顶依次输出 所以输出 是1 0 2
发表于 2017-04-10 00:31:49 回复(3)
little endian指低位字节排放在内存的低地址端(就是起始地址)
long占8个字节,假设其实地址是0,一个地址存一个字节,按照地位编址1,2会按照如下方式存储
地址 0 1 2 3 4 5 6 7 8 ...
内容 1 0 0 0 0 0 0 0 2 ...
%d只能按照四字节连续输出
那么第一个输出的便是0001=1 第二个输出0000=0 第三个输出0002 
编辑于 2015-08-20 17:17:57 回复(4)
整合一下:
little endian指低位字节排放在内存的低地址端(就是起始地址)
long占8个字节,假设其实地址是0,一个地址存一个字节,按照地位编址1,2会按照如下方式存储
地址 0 1 2 3 4 5 6 7 8 ...
内容 1 0 0 0 0 0 0 0 2 ...
%d只能按照四字节连续输出
那么第一个输出的便是0001=1,第二个输出0000=0,第三个输出0002。 
如果改成printf("%d  ", a);printf("%d  ", b);printf("%d\n", c);
那么数据将分别入栈,然后顺序输出。就不存在上述问题了。
因此,结果就是1,2,3.
发表于 2015-11-07 11:16:44 回复(0)
大端是低位存高地址,小端是低位存低地址。long long类型占8个字节 a: 01 00 00 00 00 00 00 00 b: 02 00 00 00 00 00 00 00 c: 03 00 00 00 00 00 00 00 函数调用栈是由高地址向低地址增长,入栈顺序为c,b,a,打印时每次获取4个字节,采用10进制形式进行打印,出栈顺序为后进先出,所以为a,b,c 二进制:01000000 00000000 02000000,转为10进制,所以结果为1,0,2。所以选B
编辑于 2022-09-10 11:33:02 回复(0)
今天天王老子来了答案也是 1 2 3
ubuntu版本Linux ubuntu 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux


发表于 2022-02-25 15:09:03 回复(2)
首先printf("%d %d %d\n", a, b, c)函数的参数是从右往左入栈的,先c,再b, 后a。
然后,输出的过程就是一个出栈的过程。%d表示每次从栈顶弹出4个字节对应的数据。
因此输出是 1,0,2
答案是 B
发表于 2016-03-25 17:16:38 回复(0)
发表于 2022-09-12 10:30:58 回复(0)
%lld时,才会输出1,2,3
发表于 2015-10-14 17:20:53 回复(0)
以下是引用前面大佬的回答: 
  1 printf()是一个库函数,C,C++中函数的参数是从右往左入栈的; 
  2 栈的生长方向是从高往低的 
  3 小端模式是低位存储在低字节 
  4 %d格式输出的是4个字节大小,而long long为8个字节 

从这开始是我自己补充一下:
由“小端模式是低位存储在低字节”和“long long为8个字节 ”
得出变量的二进制表示  高位<->地位
1的二进制:00000001
2的二进制:00000010
3的二进制:00000011

依据a,b,c变量定义的顺序,先定义的在低地址,后定义的在高地址。

由“printf()是一个库函数,C,C++中函数的参数是从右往左入栈的” 和 “栈的生长方向是从高往低的 ” 和 “端模式是位存储在字节(我自己的记忆方法:小端,小弟弟,小低低,大端更符合人们从左到右的阅读习惯) ” 得知  
栈:从上到下依次是高位到地位,上面是栈底,下面是栈顶,所以栈中数据如下(忽略文字描述):
3的二进制在栈中存放情况
0000
0011
2的二进制在栈中存放情况
0000
0010
1的二进制在栈中存放情况
0000
0001

printf打印其实就是一个出栈的过程,由于系统是32位的,所以int类型的变量占4位,所以出栈顺序依次是:
a对应的二进制0001十进制1
b对应的二进制0000十进制0
c对应的二进制0010十进制2
所以最终输出结果是102

发表于 2023-11-28 09:40:12 回复(1)

编辑于 2020-04-30 08:37:49 回复(0)
发表于 2023-08-09 21:34:17 回复(0)
有没有谁真的在32位小端机上测试过?
发表于 2018-04-06 14:52:06 回复(2)
考察printf的输出方式:把入栈的数据没有选择的按照顺序输出!
所以你想输出的格式一定和原数据符合,不然会窜位的。
发表于 2018-03-23 22:25:26 回复(0)
小端模式 1表示为:0000 0001,2表示为0000 0010,3表示为0000,0011 大端模式1表示为:1000 0000,2表示为0100 0000,3表示为1100 0000 printf ()函数参数是从左向右入栈,由高位到低位~小端模式,而出栈是由低位到高位~大端模式!
发表于 2017-08-29 16:55:39 回复(0)
我的电脑是windows系统,win是小端模式。输出就是123。中国做学问的不多,考究回子的八种写法的人多
发表于 2025-02-07 22:09:16 回复(0)
我对这个程序进行了调试, 发现内存当中对这三个数字的存储方式如下
0019FEB4  |00000001
0019FEB8  |00000000
0019FEBC  |00000002
0019FEC0  |00000000
0019FEC4  |00000003
0019FEC8  |00000000
然后, printf在进行打印的时候, 调用了另外一个函数, 并且在调用这个函数的时候, 传给它的参数为
  1. "%d %d %d"字符串常量在内存当中的地址
  2. 0019FEB4: 也就是需要答应的第一个变量的地址.
之后, 程序按照给定的%d %d %d从0019FEB4地址开始按照int类型的长度取出了3个数字, 这三个数字就是00000001, 00000000,00000002进行输出, 也就是我们结果当中看到的.

总结一下: printf当中对于这种任意长度的参数的处理方式,就是仅仅提供第一个参数的地址, 然后根据给定的输出规则(是按照int进行读取还是按照char还是其他的方式进行读取), 来从第一个变量的依次读取相应的数据进行输出

发表于 2023-08-11 18:22:42 回复(0)
在栈中分配空间是逆向的 a。b。 c。 (高地址。到地址) 又因为是小端存储(低位存放到低地址处) 0000 0001 0000 0002 0000 0003 printf函数 参数入栈是 从右到左入栈的 所以c先入栈,然后b 最后c入栈 栈底---c-------b--------a---栈顶 0000 0003 0000 0002 0000 0001 出栈时 从栈顶依次输出 所以输出 是1 0 2
发表于 2023-01-03 11:38:27 回复(0)
这题毛病,如果不是abc发明c语言的人可以**了
发表于 2021-04-13 14:00:51 回复(0)