博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【程序员面试宝典】错题好题汇总ch5
阅读量:5130 次
发布时间:2019-06-13

本文共 4326 字,大约阅读时间需要 14 分钟。

错题,知识盲点、查漏补缺
好题,开阔思路、锻炼思维

ch5
1.
#include
using namespace std;int i = 1;int main(){ int i = i; cout<
<
结果与分析:
main中的i从声明起就已经覆盖了全局变量i,所以直接用未定义的i进行赋值结果是未定的。
 
2.
#include
using namespace std;int func(int x){ int count = 0; while(x){ count++; x = x&(x - 1); } return count;}int main(){ cout<
<

 

结果与分析:
一开始看到这个题,我第一反应是按照x&(x-1)这条语句去执行一下,然后我笔算了一下9999 = 2^13 + 2^10 + 2^9 + 2^8 + 2^3 + 2^2 + 2 + 1,二进制表示就是10011100001111。这时候发现如果x位与x-1的话,会消耗掉最低位的1,连续执行下去的话就会把所有的1全部消耗掉。所以最后得出count是8。
思路开拓:
1.计算一个十进制数的二进制表示中1的个数呢?
很明显上面的程序就是答案。
2.计算一个十进制数的二进制表示中0的个数呢?
可以仿照求十进制数的个数,通过除2进行计算。
另外,向右位移的效果和除法类似:
int count_zero(int x){  int count = 0; int count_one = 0; while(x){   count_one += x&1;  count++;  x = x>>1; } return count - count_one;}

 

 
3.
#include
int main(){ int b = 3; int arr[] = {
6,7,8,9,10}; int * ptr = arr; *(ptr++) += 123; printf("%d,%d\n",*ptr,*(++ptr)); return 0;}

 

结果与分析:
主要考察,1、函数参数入栈的顺序
              2、*(ptr++)+=123;分解为:*ptr = *ptr + 123;ptr++;

衡量参数在栈上的位置,就是离开确切的 函数调用点(call f)有多远。已经确定的参数,它在栈上的位置,

不应该依 赖参数的具体数量,因为参数的数量是未知的!

所以,选择只能是,已经确定的参 数,离开函数调用点有确定的距离(较近)。满足这

个条件,只有参数入栈遵从自右向左规则。 也就是说,左边确定的参数后入栈,离函数
调用点有确定的距离(最左边的参数最后入栈,离函 数调用点最近)。

这样,当函数开始执行后,它能找到 所有已经确定的参数。根据函数自己的逻辑,它负

责寻找和解释后面可变的参数(在离开调用点 较远的地方),通常这依赖于已经确定的
参数的值(典型的如prinf()函 数的格式解释,遗憾的是这样的方式具有脆弱性)。

详情请看:
 
4.
#include
using namespace std;int main(){ float a = 1.0f; cout << (int)a << endl; cout << (int&)a << endl; cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么? float b = 0.0f; cout << (int)b << endl; cout << (int&)b << endl; cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么? return 0;}

 

结果与分析:
考察点一:

(int &)a 就表示 不管 a 是什么,我都当他是一个int变量。

从机器码的角度来说,变量a会被翻译成一个内存地址,(int &)a 就是说,这个内存地址里的内容它是一个整数。

(int)a 呢不同:如果 a 不是整数,就会按规则转换成整数,存入另一个地址(或临时变量)中去。

浮点数的 1.0f 在内存里是这样表示的:

0011 1111 1000 0000 00000000 00000000

这个32位二进制数被当作整数输出就是:

2^29+2^28+2^27+2^26+2^25+2^24+2^23=1065353216

而整数的 1 在内存里是这样表示的:

0000 0000 0000 0000 00000000 00000001

(int&)a 相当于*(int*)&a ; *(int*)(&a) ; *((int*)&a)

所以 (int)a != (int&)a

浮点的0和整数的0 在内存里都是:

0000 0000 0000 0000 00000000 00000000

所以 (int)b == (int&)b

参考:http://blog.csdn.net/cszdhhz/article/details/6877333#

考察点二:

另外,boolalpha的作用是使bool型变量按照false、true的格式输出。如不使用该标识符,那么结果会按照1、0的格式输出。

 
 
5.
#include
int main(){ unsigned int a = 0xFFFFFFF7; unsigned char i = (unsigned char)a; char* b = (char *)&a; printf("%08x,%08x",i,*b);//8位16进制数 return 0;}

 

结果与分析:
&a指的是a的地址,a是unsigned int类型。
所以char* b = (char *)&a;相当于
unsigned int* p = &a;
char* b = (char *) p;
 
6.
int f(int x,int y){    return (x&y) + ((x^y)>>1);}
(729,271) = 500
解析:
好精妙的题目。真的是应该好好掌握位运算。融会贯通。
x&y : x、y位与运算,相当于是相同的位只取了一次。
(x^y)>>1 : x、y异或相当于是不同的位全取。再右移>>相当于除2了。
所以两个运算都是取一半,综合起来就是取x、y的均值了。
扩展:用位运算求两个数的和?
int sum(int x,int y){ return ((x&y<<1) + (x^y));}
 
7.
判断两个数的大小?不用if、?:、switch等判断语句。
#include
#include
using namespace std; int main(){ int a =0,b = 0; cin>>a>>b; int c = a - b; char*strs[2] = {
"a Large","b Large"}; c = unsigned(c) >> (sizeof(int) * 8 - 1); cout<
<

 

结果与分析:
第一种是通过比较符号位是0还是1还确定的。
第二种是通过简单的计算。
 

8.
题目:不用sort,整数操作尽可能少。求三个数的中间数。
#include
using namespace std; inline int max(int a,int b){ return a>=b?a:b;}inline int min(int a,int b){ return a<=b?a:b;}inline int medium(int a,int b,int c){ int t1 = max(a,b); int t2 = max(b,c); int t3 = max(a,c); return min(t1,min(t2,t3));}int main(){ cout<

 

结果与分析:
假设结果是T,先max操作,确保一定有1个数字比T小,然后min操作,确保一定有1个数字比T大。
一共就3个数字,所以一定是中间数。
 
9.
不使用中间变量,交换a、b的值。
#include
using namespace std;int main(){ int a = 0,b = 0; cin>>a>>b; a = a + b;//可能会越界,如果a、b都比较大的话! b = a - b; a = a - b; cout<
<<" "<<

 

结果与分析:
我只想到第一种方法。更好的方法是用异或操作来做。
 
10.
一些概念性的问题:
switch中如果default放在开头,而下面可以匹配,则会跳过default。
如果default放在最后,不管咋样,都会default。
#include
using namespace std; int main(){ int n = 'c'; switch(n++){ default:printf("error");break; case 'a':case 'A':case 'b':case 'B':printf("ab");break; case 'c':case 'C':printf("c"); case 'd':case 'D':printf("d"); } return 0;}

 

 
题目:c++调用c编译器编译后的函数,要加extern "C"
 
因为c++ 支持重载,所以编译后在库中的名字与C中的不一样,比如void foo(int x,int y)在c中是_foo,而在C++中
可能是_foo_int_int这种名字。
 
编程题目的细节!!!!!!!!!!!!!!!double还是int?除0?取整?考虑全面!
 

 
 

 

转载于:https://www.cnblogs.com/aiqin/p/4371813.html

你可能感兴趣的文章
AS3优化性能笔记二
查看>>
ElasticSearch(站内搜索)
查看>>
4----COM:a Generative Model for group recommendation(组推荐的一种生成模型)
查看>>
UVA 11137 - Ingenuous Cubrency
查看>>
js阻止事件冒泡的两种方法
查看>>
Java异常抛出
查看>>
[SQL Server 系] T-SQL数据库的创建与修改
查看>>
74HC164应用
查看>>
变量声明和定义的关系
查看>>
Wpf 之Canvas介绍
查看>>
linux history
查看>>
jQuery on(),live(),trigger()
查看>>
Python2.7 urlparse
查看>>
sencha touch在华为emotion ui 2.0自带浏览器中圆角溢出的bug
查看>>
【架构】Linux的架构(architecture)
查看>>
ASM 图解
查看>>
Date Picker控件:
查看>>
你的第一个Django程序
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>