C语言中的运算符

1.下列 C 代码中,不属于未定义行为的有:______。
int i=0;i=(i++);
char *p=”hello”;p[1]=’E’
char *p=”hello”;char ch=*p++
int i=0;printf(“%d%d\n”,i++ i--)
都是未定义行为
都不是未定义行为
 
答案: C
C修改的是指针的值 没有修改指针指向常量的值 是正确的!ABD 行为结果是不可预测的 环境不同结果也不定 固都是未定义的
A:在GCC下输出:0
        在VC6.0下输出:1
B:在GCC下输出:段错误 (核心已转储)
        在VC6.0下输出:已停止工作,出现了一个问题,导致程序停止正常工作。
C:正常
D:在GCC下输出:-1 0
        在VC6.0下输出:0 0
 
2.有两个32bit的数A、B,使用下面方式得到32bit的数C、D。哪一种可以使用C、D得到A、B的值? 
  • C=(int32)(A+B),D=(int32)(A-B)
  • C=(int32)(A+B),D=(int32)((A-B)>>1)
  • C=(int32)(A+B),D=B
  • C=(int32)(A+B),D=(int32)(A+2*B)
  • C=(int32)(A*B),D=(int32)(A/B)
  • 都不可以,可能溢出

    答案:C

    注意考虑整数溢出问题,对于有符号数,A、C、D通过下面方式都可以恢复

    第一项:A=(C+D)/2,B=C-A

    第二项:D右移一位,不知道移出的是1还是0,不能恢复 第三项:A=C-D,B=D

    第三项:A=C-D,B=D  

    第四项:B=D-C,A=C-B

    第五项:虽然可以C*D再开方,但是不能确定A和B的正负 ,A/B可能不是整除, 也不能恢复 

    但是对于无符号数,A不行,这里简单起见,以3bit数为例。例如A=111,B=110。

           C=A+B=001(溢出),D=A-B=001,所以A不能正确恢复了。D答案,同样因为溢出不能恢复。

       C仍然可以,A=C-D=001-110=111。当A+B未溢出时,A=C-D;

                  当A+B溢出时,A=C+2^32-D; 因为溢出相当于减去了2^32。
                  所以合起来的计算公式为:  A=(C+2^32-D)%2^32 (取余数)
                  当A:INT_MAX B:INT_MAX,验证正确。

     

    3.请问 func(0x11530828)的返回值是?

int func(unsigned int i)
 {
     Unsigned int temp = i;
     temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1);
     temp = (temp & 0x33333333) + ((temp & 0xccccccccc) >> 2);
     temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0 >> 4));
     temp = (temp & 0xff00ff) + ((temp & 0xff00fff00) >> 8);
     temp = (temp & 0xffff) + ((temp & 0xffff0000) >> 16);
     Return temp;
 }

首先确定这个题是想考察数的二进制表示中1的个数的“平行算法”,

接下来开始分析改算法是如何实现二进制表示中1的个数统计的,为了方便理解,我们把代码改成如下的形式:
int func(unsigned int i)   

{   

    unsigned int temp = i;   

    temp = (temp & 0x55555555) + ((temp>> 1) &  0x55555555);  //temp相邻位相加     

    temp = (temp & 0x33333333) + ((temp >> 2) & 0x33333333);      //temp相邻(以2为单位)相加   

    temp = (temp & 0x0f0f0f0f) + ((temp>> 4) &  0x0f0f0f0f);        //temp相邻(以4为单位)相加   

    temp = (temp & 0xff00ff) + ((temp>> 8) &    0xff00ff);           //temp相邻(以8为单位)相加   

    temp = (temp & 0xffff) + ((temp>> 16) &     0xffff) ;              //temp相邻(以16为单位)相加   

    return temp;   

}
temp相邻位相加:相加原理若相邻的两个数为00则结果为00,  相邻的两个数为01或10则结果为01,相邻两个数为11则结果为10,也就是先小范围统计每两位中1的个数,后面的步骤在累计有多少个1.
0x11530828的二进制表示如下:  
0001  0001 1001 0011 0000 1000   0010 1000 
  0  1    0  1   1  1   0  2   0  0   1  0   0  1     1  0
      1        1       2       2       0       1       1         1
                 2               4                1                  2 
                                  6                                    3
                                                                        9



 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值