接着上午有关 X&(X-1) 的另一个例题:

用一个表达式,判断一个数X是否是2N次方(2,4,8,16,…),不可用循环语句。

[中国台湾某著名CPU生产公司2007年10月面试题]

解析:2、4、8、16这样的数转化成二进制是10、100、1000、10000。如果X减1后与X 做与运算,答案若是0,则X是2N次方。

答案:!(X&(X-1))

下午:

1.

基本的优先级需要记住:

指针最优,单目运算优于双目运算。如正负号。

先算术运算,后移位运算,最后位运算。

逻辑运算最后计算。

请特别注意:1 << 3 + 2 && 7等价于 (1 << (3 + 2))&&7.

例:

类型转换问题;算符的优先级问题。

对于第一个问题

unsigned char b=~a>>4,在计算这个表达式的时候,

编译器会先把a和4的值转换为int类型(即所谓整数提升)后再进行计算,

当计算结果出来后,再把结果转换成unsigned char赋值给b。

对于第二个问题

因为“~”的优先级高于“>>”和“+”,本题的过程是这样的:

对于1010 0101取反0101 1010;再右移

这里有一个问题,是先右移4位再加1呢,还是直接右移5(4+1)位。

因为“+”的优先级高于“>>”,所以直接右移5位。结果是0000 0010。

最后的结果应该是2才对,但把如上的指令放到vs2008中运行,答案居然是250。

那么到底是什么地方出了问题?在调试的过程中进入汇编指令。可以看到高级语句转换为汇编语言以后,是 执行取反 再位移 的。

我们看到eax是16位的寄存器,于是在机器中

0xA5的寄存中表达是0000 0000 1010  0101 ,

取反是1111 1111 0101 1010,

那么右移5位是0000 0111 1111 1010,

由于是unsigned char型的只能表示低8位的数值,即250

2.

(x&y)+((x^y)>>1),效果就是求x与y的平均值

把x和y里对应的每一位(指二进制位)都分成三类,每一类分别计算平均值,最后汇总。

其中 一类是x,y中对应位 都是1, 用x&y计算其平均值;

一类是x,y中对应位 有且只有一位是1,用(x^y)>>1计算其平均值;

一类是x,y中对应位 均为0, 无须计算。

第一部分

x,y对应位均为1,相加后再除以2还是原来的数,如两个00001111相加后除以2仍得00001111。
第二部分

对应位有且只有一位为1,用“异或”运算提取出来,然后>>1(右移一位,相当于除以2)。

第三部分

对应位均为零,因为相加后再除以二还是0,所以不用计算。

三部分汇总之后就是(x&y)+((x^y)>>1)

这样可以避免溢出:
假设x,y均为unsigned char型数据(0~255,占用一字节),显然,x,y的平均数也在0~255之间,但如果直接x+y可能会使结果大于255,这就产生溢出,虽然最终结果在255之内,但过程中需要额外处理溢出的那一位,在汇编中就需要考虑这种高位溢出的情况,如果(x&y)+((x^y)>>1)计算则不会。

3.

利用  位运算  实现两个整数的   加法运算

!!!!!!重点: 异或 常被认作不进位的加法运算

#include <stdio.h>  
int main(void) {   
    int add(int a,int b);  
    int m,a,b;  
    scanf("%d,%d",&a,&b);  
    m = add(a,b);  
    printf("m=%d",m);  
    return 0;  
}  
int add(int a,int b){  
    if(b == 0) return a;//没有进位时,完成运算,a为最终和。  
    int sum,carry;  
    sum = a ^ b;//没有进位的加法运算  
    carry = (a & b) << 1;//进位,左移运算。  
    return add(sum , carry);//递归,相加。  
}

注释:

*  x ^ y :实现不进位的加法,那么我们接下来就要将进位的数据加上,就可以实现了。

*  x & y : 这个操作,即是找出相同位,为什么我们需要找出相同的位呢,因为只 1 & 1 ,这种情况才会  产生进位,可能有人会想那 0 & 0 呢,这个没有影响的。

*  (x & y) << 1:为什么要左移呢,其实也很简单,即然后我们都已经找出需要进位的位,那么说明在该位置的前面一位,应该加上1,所以应该左移1位,就是加上余数

4.

有两个变量a和b,不用“if”、“?:”、“switch”或其他判断语句,找出两个数中间比较大的。

第一种:

int max = ((a+b)+abs(a-b))/2;

abs是取绝对值。
如果a>b,那么a-b>0,所以表达式就变成了(a+b+a-b)/2=(a+a)/2=a。
如果a<b,那么a-b<0,取绝对值变成-(a-b),所以表达式变成了(a+b-a+b)/2=(b+b)/2=b。

第二种:

int c = a-b;

char *strs[2] = {"a large","b large"};

c = unsigned(c)>>(sizeof(int)*8-1);//判断符号位

注释:

sizeof(int) 字节数

sizeof(int)*8 位数

右移sizeof(int)*8 - 1 符号位

该语句的目的是求出c的最高位的值,

当该值为1时,表示c为负数,因此判断出a小于b。

当该值为0时,表示c为零或者整数,因此判断出a大于等于b

5.

给三个整数a、b、c,函数实现取三个数的中间数,不可以使用sort,整数操作尽可能少。

(思路:输入的三个值 中值就是第二大的数值

选中两个进行比较 找到较大的

较大的与第三个值比较

1.如果较大的 < 第三个值 那这个较大的 就是第二大的数值 就是中值

2.较大的 > 第三个值  比较第三个值与 较小的值

1.第三个值 > 较小的值 第三个值 是中值

2.第三个值 < 较小的值 较小的值 是中值)

注意等于号

int median( int a, int b, int c )

{

int min,max;

if ( a < b )

{

min = a;

max = b;

}

else

{

min = b;

max = a;

}

// 此时有 min<=max

if ( max <= c )

return max;

else // min <= max, c <max,

{

// 比较min和c

if ( min <= c ) // min <=c < max

return c;

else

return min; // c< min <= max

}

}

6.

如何将a、b的值进行交换,并且不使用任何中间变量?

(单纯的加减交换会有溢出的可能 尽量用异或)
void swap(int& a, int& b) //使用位运算也可以交换两个值

{

a = a^b;

b = a^b;

a = a^b;

}

7.

评价一下C与C++的各自特点。如果一个程序既需要大量运算,又要有一个好的用户界面,还需要与其他软件大量交流,应该怎样选择合适的语言?

因为C++是面向对象的,在封装、继承、多态这些特性上,会有比较大的开销,所以单从运行效率而言,C更适合一些。

但是和C++相比,C的图形库相对而言种类比较少,而且比较简单,所以在比较复杂的界面设计上,C++会更有优势。因此到底用C还是C++并没有并且的答案,如果目标平台的硬件性能比较弱,并且GUI界面比较简单,推荐用C,反之推荐C++。

7-19下午刷题未知点集合相关推荐

  1. 7-20上午刷题未知点集合

    1. switch中的"fall through":如果case语句后面不加break,就依次执行下去. 2. 下面代码输出结果是多少? A.array: 1 6 3 4 5 6 ...

  2. 7-19上午刷题未知点集合

    问题1 X&(X-1)是什么意思? 问题2 对于算法,一个是要求高效 同时 要便于识别错误 问题3 #include<iostream> #include<stdio.h&g ...

  3. 7-25日牛客网刷题 未知点、错题 集合

    1.在C++11标准的语法中,auto被定义为自动推断变量的类型. 例如: auto x=5.2; //这里的x被auto推断为double类型 2.注意点: C语言中最简单的数据类型包括:整型.实型 ...

  4. 7-19晚牛客网刷题未知点、错题 集合

    1. 初始化为NULL(0)的类指针可以安全的调用不涉及类成员变量的类成员函数而不出错,但是如果类成员函数中调用了类成员变量则会出错 2. 悄咪咪加一个注意点: 注意enum在c语言中是关键字 ,c语 ...

  5. 【清北学堂济南刷题班】集合

    集合 [问题描述] 给定一个可重集合,一开始只有一个元素0 .然后你可以操作若干轮,每一 轮,你需要对于集合中的每个元素 x 进行如下三种操作之一: 1.将 x 变为 x +1. 2 .将 x 分裂为 ...

  6. 8-13 刷题 复习 知识点集合

    1. //把数据类型去掉了看 简单很多的 指针常量 指针常量:顾名思义它就是一个常量,但是是指针修饰的.  格式为: int * const p //指针常量 在这个例子下定义以下代码: int a, ...

  7. Leetcode刷题Day15

    4.19 上次刷题仿佛是上辈子的事情了,最近忙ddl的各种,加上依然没有从emo里缓回来,现在虽然好像依然没有缓回来,但是还是在grief process里心情起起伏伏 今天看到很多年前学过的一句话, ...

  8. 牛客刷题-Java面试题库【动态更新添加题目】(2023.06.19更新)

    讲在前面 ✨ 牛客刷题日记–理解为重中之重 刷题一方面是持续的了解到自己哪方面比较欠缺,另一方面也是从各大厂的面试题可以看出当前所需的技术栈的偏重点,持续的巩固基础和查漏补缺,一如代码深似海–学无止境 ...

  9. 力扣(LeetCode)刷题,简单题(第19期)

    目录 第1题:两数之和2-输入有序数组 第2题:换酒问题 第3题:山脉数组的峰顶索引 第4题:矩阵中的幸运数 第5题:去掉最低工资和最高工资后的工资平均值 第6题:非递增顺序的最小子序列 第7题:独一 ...

最新文章

  1. 测序发展史,150年的风雨历程 (第二版)
  2. Playmaker全面实践教程之Playmaker常用工具
  3. RK1109 RK1126等芯片来袭,2020年瑞芯微旗下SoC一览
  4. 2019蓝桥杯省赛---java---B---4(数的分解)
  5. CutJS – 用于 HTML5 游戏开发的 2D 渲染引擎
  6. C++编程学到什么程度可以面试工作?
  7. 自动化测试基础篇--Selenium中数据参数化之TXT
  8. Wordpress 5.2 beta 2 发布,支持 Emoji 12
  9. 风云2号卫星云图_今天从零教你开始利用Python打造词云图!
  10. 3dmax模型导入unity
  11. 老人拿家谱自称傅友德后代,学者:朱元璋诛九族却放过了六岁小孩
  12. android2012系统,压倒性份额四核技术 Android系统2012前瞻
  13. Qt如何自适应4k这些高分辨率屏幕
  14. 【django】简易视频播放功能
  15. 华为服务器1u系列,服务器 1u 尺寸
  16. kafka和zookeeper下载地址和安装方法和JAVA消费者方法
  17. OC 基础 UIButton
  18. 图解六种全面质量管理工具用法和举例
  19. MySQL安装----最详细的教程(测试木头人)
  20. 神经网络训练tricks

热门文章

  1. 下列哪个滤波器是非线性的_正确选择射频滤波器的八大窍门
  2. Anolis 安装图解
  3. mybatis 中case_mybatis 对string类型判断比较 group case when then 综合
  4. clover引导macos big sur_安装MAC OS系统看完后能让你马上用上最新苹果系统
  5. winform list集合怎么 in过滤_python3基础04字典(dict)和集合(set)
  6. 数据链路层、交换机内容整合
  7. 快速上手linux玩转典型网络,5- 快速上手Linux玩转典型应用- Linux常用命令
  8. apply_async进程不执行_c/c++面试精选题(八)简单回答,进程和线程关系及区别...
  9. java cpu监控,java系统监控CPU 磁盘
  10. java读取属性文件的方法_java读取属性文件的方法