您的位置:首页 > 编程语言 > C语言/C++

C语言中的运算符

2015-08-26 19:49 267 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: