HW面试

题目源自第一次去华为面试的时候一面面试官出的代码。

int val = 0x123456789;
char* prt =(char*) &val;
printf("%x\n",prt[0]);

运行结果如下图:



目前为止自己的分析如下~

1.对于0x123456789来说,由于十六进制的每1位对应于二进制的4位,则每2位对应1个字节,int数据类型大小为23456789转换为二进制已经有8个字节,最高位的1被舍弃。

2.因此val为 0010 0011 0100 0101 0110 0111 1000 1001.

3.prt为指向char类型的指针,char类型大小为1个字节,因此对指针来说,+1就等于地址往后跳1个字节。(若数据类型为int,则+1等于地址往后跳4个字节)

4.首先不考虑为什么输出的是89这两位,考虑为什么输出为ffffff89,将代码稍加修改为

int val = 0x123456789;
char* prt =(char*) &val;
printf("%x\n",prt[0]);
printf("%x\n",prt[1]);
printf("%x\n",prt[2]);
printf("%x\n",prt[3]);
printf("%x\n",*(prt+3));

运行结果如下图:


可见其余前几位输出均与原来相等。

考虑到prt所指地址存的数据为 1000 1001,当将这个数据作为一个十六进制输出时,数据类型为int为有符号类型,则首位的1将会看做符号位,将1000 1001按位取反加1,得到 0111 0111,对应的十进制为119,加上符号位则为-119,将-119重新写为int类型则为 1111 1111 1000 1001,按十六进制输出则为 ffffff89。

5.搞清楚为什么输出会变成ffffff89后,考虑为什么prt指向的地址所存数据为89而不是23。由于这里的val存放在栈区,个人猜测可能与栈内存的生长方向有关。


 栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意  
  思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有  
  的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将  
  提示overflow。因此,能从栈获得的空间较小。    
  堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储  
  的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小  
  受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。  

假设val存在地址 0001~0004中,则存储方式如下:

0001:1000 1001

0002:0110 0111

0003: 0100 0101

0004: 0010 0011

当prt所指类型为char,指针为从栈顶向下1个字节,为0001。

以上为个人想法,不保证正确性,留待以后随时修改。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值