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)的返回值是?
首先确定这个题是想考察数的二进制表示中1的个数的“平行算法”,
接下来开始分析改算法是如何实现二进制表示中1的个数统计的,为了方便理解,我们把代码改成如下的形式:
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
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
相关文章推荐
- c++ 可重载运算符和不可重载运算符
- OutMan——C语言中文件的操作
- c++中不能重载的运算符
- c/c++ 取得当前目录
- C语言基础知识之(八):二维数组,二维字符串数组,代码安全
- C++中的error C2662,const的this指针问题
- 关于const的底层实现
- 寻找距离某数最近的素数(C语言)
- C++的一道笔试题
- Thinking in C++之1.继承与组合概念、区别及优缺点
- c++ 时间类型详解 time_t
- 到C++11中的智能指针
- C++11新特性之Lambda函数
- Eclipse IDE for C/C++ Developers和MinGW安装配置C/C++开发学习环境详解
- c++-------------数组
- C++ primer 【笔记】C++中this指针的用法详解
- 【C++】阅读计划
- [C++11 并发编程] 11 - 线程间同步 - 等待一个消息或某种条件
- C++虚基类的作用
- 【黑马程序员】C语言-链表