今天早上的企鹅公司的实习笔试题。大家来讨论下!
第一题:signed char a=0xe0;
unsigned int b=a;
unsigned char c=a;
下面说法正确的是:
A (a>0 )&&(b>0)为真 B c==a 为真 C b的16进制为0xffffffe0 D 都不对
第二题:int main()
{
long long a=1;
long long b=2;
long long c=3;
printf("%d,%d,%d",a,b ,c);
return 0;
}
输出结果是什么?(32位环境,cpu为小端模式,所有参数用栈传递)
第三题:unsigned int a= 0x1234;
unsigned char b=*(unsigned char *)&a;
在32位大端模式处理器上变量b= ?。
希望大家给出详细点的分析。。分析好的我都会给分的。。希望大家多讨论!! C
[解决办法]
1, 整形比较小于int的会扩宽的int再比较, 而有符号数扩宽填充符号位, 无符号数填充0, 导致扩宽后两个整形的二进制不再相等, 选择C.
2,
1)无论32/64, long long都是8字节整形, %d会将参数栈上的内存解释为4字节int, 所以会造成打印结果异常.
2)由于任何多字节变量都要做内存对齐, 原则是自身长度与sizeof(int)间较小值, 所以3个long long在栈上是可以紧密排列的, 并且第一个long long对齐在sizeof(int)对齐内存地址.
3)栈地址向低增长, 函数参数入栈从右向左, 所以第一个long long是参数栈上最低地址的参数, 总共只需要1.5个long long就足以打印完3个%d.
4)小端情况下, 第一个%d解释了第一个long long的低4字节, 打印1. 第二个%d解释了第一个long long的高4字节, 打印0. 第三个%d解释了第二个long long的低4字节, 打印2.
3, unsigned int a= 0x1234; 其中int是4字节, 补齐16进制表示为: 0x00 00 12 34
unsigned char b=*(unsigned char *)&a; 由于大端存储, 所以上述int a变量的最低地址存储的是
十六进制表示中最左边的1字节, 为0x00.
[解决办法]
第一题:signed char a=0xe0;
unsigned int b=a;
unsigned char c=a;
下面说法正确的是:
A (a>0 )&&(b>0)为真 B c==a 为真 C b的16进制为0xffffffe0 D 都不对
【分析】:
a = -16
c = 224
b = 0xffffffe0 (负数扩展前面补1)
c==a全部转化为int, -16 == 224 false
【答案】
C
第二题:int main()
{
long long a=1;
long long b=2;
long long c=3;
printf("%d,%d,%d",a,b,c);
return 0;
}
输出结果是什么?(32位环境,cpu为小端模式,所有参数用栈传递)
【分析】:
传入参数,由右往左,栈空间内存从高往低,little endian, 栈空间如下:
内存高位->
00000000 00000011
00000000 [00000010](c)
[00000000](b) [00000001](a)
<-内存低位
因此printf会按照4bytes取参数.
【答案】
输出: 1, 0, 2
第三题:unsigned int a= 0x1234;
unsigned char b=*(unsigned char *)&a;
在32位大端模式处理器上变量b= ?。
【分析】
bit endian CPU下面a的内存布局
内存低位->内存高位
00001234
b为0x00
【答案】
b=0
个人感觉这几题对实习生是不是难了点, QQ不会吧真实招聘的题目随便拿来给实习生做了吧.
[解决办法]
变参调用只能是__cdecl调用协定. 具体理解就是由format string来决定的, %d的意思就是double word, 4字节.
具体参考
http://blog.csdn.net/jiqiren007/article/details/6151640