int a=301;char *p=(char *)&a; printf("%d,%d",*p,*++p);

  题目:

#include<stdio.h>
int main(){

int a=301;    //   1_0010_1101B
int x=1; 
x>>8?printf("big\n"):printf("small\n");  //检测大小端

char *p=(char *)&a;
printf("%d,%d",*p,*++p);   
return 0;
}

/*

首先面对两个问题:1, int 型被强转为char型  ,那 a 的值为?       2 , * 和++ 优先级问题     

printf("%d,%d",*p,*++p);   //(pirntf 计算参数%d顺序问题,对 ++ 运算有影响的。)

*/

//win10 DEV编译器  答案:small     1,1

解释:

第一个问题:

注意:   一个字节 = 8 bit       ,  十进制 简称 D ,  二进制 简称 B。

 大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。                      ----百度百科

运行结果看见是小端模式,int a = 301 在内存储存格式为 图1 .     301(D)  = 0001 0010  1101(B)    

                  内存地址                     内容          二进制数据
              FFFC1    低地址           0010  1101      低字节
              FFFC2           0000   0001
              FFFC3           0000  0000
              FFFC4    高地址           0000  0000      高字节

                                                                          图 1 小端模式储存 int a=301

char 占一个地址 , int  占四个地址  。int 型强转为char  型 时,char 就是图中 FFFC1地址所在的内容数据 0010  1101。

所以强转之后的a  的值是地址为 FFFC1所在的值:0010 1101 (B) = 45 (D)

第二个问题:

++ 和 * 是同一个优先级 ,那就看运算顺序,是自右向左的,所以  *++p  是先自加(++),在取值(*)  的。*++p 的地址就是FFFC1加一的地址FFFC2所在内容    0000   0001(B) =1 (D)

 

------------------------------------------------------------------------------------

好了,自己模拟计算答案了,printf("%d,%d",*p,*++p);   // 输出  45 ,1  ^ -- ^ ,哎,和答案不一样呢,

坑好多,见下文解释,printf()运算参数是自右向左的,真搞不明白,这样就是先计算 *++p ,在计算 *p,  答案就是 1 ,1 了。

心累。

**************************************************************

 无论在什么系统printf的执行顺序都是从右至左,只不过编译器不同,程序内存分配方式不同,i++对i加1的时机也不同,所以结果不同。 printf("%d,%d,%d\n",i++,++i,i); 出现4,5,5的结果比较好理解:i和++i都共享一个内存,也就是为i分配的内存;而执行i++会为表达式单独分配内存,把当时i的值存储进去,然后i加1;所以执行printf语句时,i初始值为3,执行++i后,i变为4,执行i++先把为表达式分配内存,表达式的值为4,然后i加1变为5;最后输出时,i++这个表达式的值为4,而++i和i都用此时为i分配的内存的值,也就是5。之所以这样分配可能是编译器优化内存分配方式,节省内存吧。总结起来就是,编译器会为i++表达式实时单独分配内存,而i和++i由始至终都共享i的内存,最后输出时,i++输出当初执行i++时的表达式的值,而i和++i输出最后i的内存中的值。 出现4,4,3的结果比较不让人理解,我看也就是vc6.0这么诡异:无论是i,i++还是++i,编译器都会为当时的表达式单独分配内存,从右向左执行时,i表达式的值存为3,i仍为3,++i表达式的值为4,i变为4,i++表达式的值为4,i仍为4,为什么仍为4,因为要等到printf这条语句执行完以后,i才会+1变为5。假如在这个i++左边再添加一个i,用来输出,那么它仍为4,也就是说printf("%d,%d,%d,%d",i,i++,++i,i)的结果为4,4,4,3。不过下一条printf语句输出i的结果就是5了。总结起来是这样,在vc6.0里i,i++和++i都会实时为各自表达式单独分配内存,++i对i的影响是实时的,但是i++对i的内存的值的影响是等到本条printf语句执行完才起作用。 我们平常说i++是对i先使用后加一,也就是先把i作为表达式的值,然后把i加1赋给i,通常认为这个“后”是在i++这个式子之后,没想到vc6.0中,这个“后”竟然要后到整条printf语句执行完以后。                                         

                                                                                                                            -----引自博客评论

 

 

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值