面试准备 -- 程序员面试宝典 -- 重要知识点整理

第5章  程序设计基础概念

5.2 i++

    C中printf(计算参数时是从右到左压栈的)

5.5 运算符问题

面试例题2:用一个表达式,判断一个数X是否是2^N次方(2,4,8,16,...), 不可用循环语句。

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

面试例题3:下面代码

int f(int x, int y)
{
    return (x&y) + ((x^y)>>1)
}
(729, 271) = 500

解析:x&y是取相同的位与,这个的结果是x和y相同位的和的一半,x^y是取x和y的不同位,右移相当于除以2,所以这个函数的功能是取两个数的平均值。

面试例题4:利用位运算实现两个整数的加法运算,请用代码实现

答案:代码如下

int Add(int a, int b)
{
    if(0 == b) return a;  //没有进位的时候完成运算
    int sum, carry;
    sum = a^b;  //完成第一步没有进位的加法运算
    carry = (a&b) << 1;  //完成第二步进位并且左移运算
    return Add(sum, carry);  //进行递归,相加
}
5.6 a、b交换与比较

面试例题1:There are two int variables: a and b, don't use "if', "? :", "switch" or other judgement statements, find out the biggest one of the two numbers.

答案:方案一:

int max = ((a+b) + abs(a-b)) / 2  //如果求两者中较小的数呢
方案二:

int c = a - b;
char *strs[2] = {"a Large ", "b Large "};
c = unsigned(c) >> (sizeof(int) * 8 - 1);

面试例题2:两个整型数,不准用while, if, for, switch, ? : 等判断语句求出两者最大值。

答案:代码如下,可以采用bool值

bool fun(int a, int b)
{
    return a>b;
}
int max(int a, int b)
{
    bool flag = fun(a, b);
    return flag*a + (1-flag)*b;
}
面试例题3:有2数据,写一个交换数据的宏?

答案:

#include <stdio.h>
#include <string.h>

#define swap(a,b)\
{ char tempBuf[10]; memcpy(tempBuf, &a, sizeof(a));
	memcpy(&a, &b, sizeof(b)); memcpy(&b, tempBuf, sizeof(b));}	
int main()
{
	double a=2, b=3;
	swap(a,b);
	printf("%lf %lf \n", a, b);
	return 0;
}
5.8 程序设计的其他问题

面试例题1:下面的switch语句输出什么。

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"); 
}
A. cdd    B. cd    C. abcd    D. cderror

补充:switch语句的判断条件可以接受int,byte,char,short,不能接受其他类型.简单地说就是能够自动转换程int类型的数据类型才行default就是如果没有符合的case就执行它,default并不是必须的.

答案:B

第6章  预处理、const与sizeof

6.1 宏定义

面试例题2:用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)。

解析:通过这道题面试官想考以下几个知识点:

> #define 语法的基本知识(例如,不能以分号结束、括号的使用,等等)

> 要懂得预处理器将为你计算常数表达式的值,因此,写出你是如何计算一年中有多少秒而不是计算出实际的值,会更有意义。

>意识到这个表达式将使一个16位机的整型数溢出,因此要用到长整型符号L,告诉编译器这个常数是长整型数。

如果在表达式中用到UL(表示无符号长整型),那么你就有了一个好的起点。记住,第一印象很重要。

答案:# define SECONDS_PER_YEAR (60*60*24*365)UL

面试例题3:写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

解析:懂得在宏中小心地把参数用括号括起来。

答案:#define MIN(A,B) ((A) <= (B) ? (A) : (B))

6.2 const

面试例题1:Which "const" modifier should be removed. (代码P47)

解析:关于const修饰指针的情况,一般分为如下4种情况:

int b = 500;
const int* a = &b    //情况1
int const *a = &b    //情况2
int* const a = &b    //情况3
const int* const a = &b    //情况4
如何区别呢?

1)先看情况1.

如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身就是常量。因此,1和2的情况相同,都是指针所指向的内容为常量(与const放在变量声明符中的位置无关),这种情况不允许对内容进行更改操作。

换句话说,,如果a是一名仓库管理员的话,他所进入的仓库,里面的货物(*a)是他没权限允许动的,仓库里面的东西原来是什么就是什么;所以

int b = 500;
const int* a = &b;
*a = 600;  //错误
但是也有别的方法去改变*a的值,一个是通过改变b的值;

int b = 500;
const int* a = &b
b = 600;
cout << *a << endl;  //得到600
还有一种改变*a办法就是a指向别处(管理员换个仓库):

int b = 500, c = 600
const int* a = &b;
a = &c;
cout << *a << endl;  //得到600
对于情况1,可以先不进行初始化。因为虽然指针内容是常量,但指针本身不是常量。

const int* a;  //正确
2)情况2与情况1相同。

3)情况3为指针本身是常量,这种情况下不能对指针本身进行更改操作,而指针所指向的内容不是常量。

举例来说:如果a是一名仓库管理员的话,他只能进入指定的某仓库,而不能去别的仓库(所以a++是错误的);但这个仓库里面的货物(*a)是可以随便动的,(*a=600是正确的)。

此外,对于情况3:定义时必须同时初始化。

int b = 500, c = 600;
int* const a;  //错误,没有初始化
int* const a = &b;  //正确,必须初始化
*a = 600;  //正确,允许改值
cout << a++ << endl;  //错误
4)对于情况4位指针本身和指定的内容均为常量。那么这个仓库管理员只能去特定的仓库,并且仓库里面所有的货物他都没有权限去改变。

下面再说一下const成员函数是什么?

我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是“只读”函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。

一些成员函数改变对象,例如:

void Point::SetPt(int x, int y)
{
    xVal = x;
    yVal = y;
}
一些成员函数不改变对象。

int Point::GetY()
{
  return yVal;
}
为了使成员函数的意义更加清楚,我们可在不改变对象的成员函数的函数原型中加上const,下面是定义const成员函数的一个实例:

class Point
{
	int xVal, yVal;
	public:
		int GetY() const;
};
//关键字const必须用同样的方式重复出现在函数实现里,否则编译器会把它看成一个不同的函数;
int Point::GetY() const
{
	return yVal;
}
如果GetY()试图用任何方式改变yVal或调用另一个非const成员函数,编译器将给出错误信息。任何不修改成员数据的函数都应该声明为const函数,这样有利于提高程序的可读性和可靠性。

如果把const放在函数声明前呢?因为这样做意味着函数的返回值是常量,意义就完全不同了。
面试例题2:const与#define相比有什么不同

答案:C++语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点:

> const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,而且在字符替换中可能会产生意料不到的错误(边际效应)。

> 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只能使用const常量而不使用宏常量,即const常量完全取代宏常量。

未完,待续。。。

章节:粗体 大 

章节小标题:粗体 中

题目:粗体 小









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值