笔试题汇总心得

一语句实现x是否为2的若干次幂的判断

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Tommy_wxie/article/details/7355857
收起

#define is2*n(x)  ((x & (x - 1))? 0 : 1)

int main(void)

{

        int m = 512;

        cout << ((m & (m - 1)) ? false : true) << endl;

        //即当m中只有一位为1时,才为若干次幂值

//若有两个及以上1,则(m & (m - 1))不为0,输出0,表示不为2的若干次幂

        return(0);

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010518621/article/details/82468330
收起
一句话判断x是否为2的n次幂,这个题很简单。

2的1次幂 二进制 10

2的2次幂4 二进制 100

2的3次幂8 二进制 1000

而2的3次幂8 -1=7 二进制 0111

有没有发现规律 8和7二进制相与&的结果就是 0 ,那么答案就是出来啦 x&(x-1) 结果为0,则是2的n次幂

输入两个int,求这两个数的二进制数的不同的位的个数。

原文链接:https://segmentfault.com/a/1190000010200547
收起
/*
The Hamming distance between two integers is the number of positions at which the corresponding bits are different.

Given two integers x and y, calculate the Hamming distance.

Note:
0 ≤ x, y < 231.

Example:

Input: x = 1, y = 4

Output: 2

Explanation:

1 (0 0 0 1)

4 (0 1 0 0)

The above arrows point to positions where the corresponding bits are different.
*/
int hammingDistance(int x, int y) {

}

题意: 输入两个int,求这两个数的二进制数的不同的位的个数。

办法一:

  • 可以利用异或的特性:相同为0,不同为1。把两数异或,再判断结果有几个1。

* 怎么判断int中有几个1?

* 可以对这个数除2运算,并记录模2为1的个数,直至此数变到0。也就是模拟了转二进制数的过程。

办法二:

  • 先异或。

  • 如何判断有几个1?

* 右移一位,再左移一位,如果不等于原数,就是有一个1。同样模拟了转二进制数的过程。

* 除2即右移一位。

办法三:

  • 先异或。

  • 如何判断有几个1?

while(n) {
c++;
n=n&(n-1);
}
n&(n-1)就是把n的最未的1变成0。

#include <stdio.h>
 
int hammingDistance(int x, int y) {
    int r = x ^ y;
    int cnt = 0;
    while (r > 0) {
        if (r%2 == 1) {
            cnt ++;
        }
        r = r/2;
    }
    return cnt;
}
 
int hammingDistance2(int x, int y) {
    int r=x^y;
    int cnt = 0;
    while (r) {
        if ((r>>1)<<1 != r) {
            cnt ++;
        }    
        r >>= 1;
    }
    return cnt;
}
 
int hammingDistance3(int x, int y) {
    int r=x^y;
    int cnt=0;
    while (r) {
        cnt ++;
        r=r&(r-1);
    }
    return cnt;
}
 
int main(int argc, char *argv[])
{
    printf("%d\n", hammingDistance3(1,4));
    return 0;
}

确定一个变量是有符号数还是无符号数?

读《C专家编程》,其中一段讲面试,说是微软曾经有一道面试题:
写一段代码,确定一个变量是有符号数还是无符号数?

书上给出了两个宏:
#define ISUNSIGNED(a) (a>=0 && ~a>=0)
#define ISUNSIGNED(type) ((type)0-1 > 0)

第二个从类型来判断,没有问题。

而第一个只能用在K&R C里,在ANSI C里就不行了。
当这个宏被用在int/unsigned int时,没有任何问题。
但是当使用在char和short上就会出错。

ANSI C中的整型升级:
char,short int或者int型位段(bit-field),包括它们的有符号或无符号变型,
以及枚举类型,可以使用在需要int或unsigned int的表达式中,
如果int可以完整地表示源类型的所有值,那么该类型的值就转换为int,否则转换为unsigned int。

ANSI C中的寻常算术转换:
当执行算术运算时,操作数的类型如果不同,就会发生转换。
数据类型一般朝着浮点精度更高、长度更长的方向转换,
整型数如果转换为signed不会丢失信息,就转换为signed,否则就转换为unsigned。
这个称为值保留(value preserving)原则。

所以,无论原先是否有符号,char和short都被转换成了signed int(整型升级)。
原先unsigned的东西变成了signed,然后再进行取反。
同时,常数0被认为是signed int类型,所以一律被判为有符号数了。

问题是一旦char或者short参与了运算,它们将被首先转换成int,
在这以后,任何操作都变成徒劳的了,int永远都是signed。
那么能否在整型升级之前让signed char/short变成负数呢?至少我现在还没想到办法。

偶使用了赖皮方法,无耻地定义了全局变量,还用了变态的逗号表达式……

于是第一个宏就变成下面这个样子了:
int r, t;
#define ISUNSIGNED(a) (t = a, r = (a>=0 && (a=~a)>=0), a = t, r)
再一想,既然用了全局变量保存a的值,还讨论干啥?于是……

int r, t;
#define ISUNSIGNED(a) (t = a, r = ((a=-1) >= 0), a = t, r)

而且这样做的前提是,假设int是最长的整型类型,并且是有符号的。
Peter Van Der Linden看到,保证要吐死了.

得到一个数组元素的大小。

1在这里插入图片描述

WINDOWS下有一个函数 _countof()

/* _countof helper */

#if !defined(_countof)

#if !defined(__cplusplus)

#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))

#else

extern "C++"

{

template <typename _CountofType, size_t _SizeOfArray>

char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];

#define _countof(_Array) sizeof(*__countof_helper(_Array))

}

#endif

#endif

面向对象的程序设计方法有哪些优点?

2.面向对象的程序设计方法有哪些优点?
优点:
1、易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
2.高质量
在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
4、易扩展
由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
3、效率高、
在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
缺点
(1)运行效率较低。
类的大量加载会牺牲系统性能,降低运行速度。虽然CPU速度在提高,内存容量在增加,但这一问题仍会随着系统规模变大而逐渐显示出来,变得越发严重。
(2)类库庞大。
由于类库都过于庞大,程序员对它们的掌握需要一段时间,从普及、推广的角度来看,类库应在保证其功能完备的基础上进行相应的缩减。
(3)类库可靠性。
越庞大的系统必会存在我们无法预知的问题隐患,程序员无法完全保证类库中的每个类在各种环境中百分之百的正确,当使用的类发生了问题,就会影响后续工作,程序员也有可能推翻原来的全部工作。 [4]

C++基础问题 分别写出BOOL,int,float,指针类型的变量a 与“零”的比较语句

BOOL  : if ( !a ) or if(a)
 
int   : if ( a == 0)
 
float : const float EXP = 0.000001
         if ( a < EXP && a >-EXP)
 
pointer : if ( a != NULL) or if(a == NULL)

class 和结构体的关系

struct X {
    X(){std: cout<<"1";}
X(const X&){ std: cout <<"3";}
~X(){std: cout<<"2";}
void f(){ std: cout<<"4";}
} object;


int main()//主函数
{
    int b;
    int &a = b;
    //X c(object);//输出13422
    X(object);//输出11422
    object.f();

}

while条件先找出正向的,然后再把正向条件逆反然后填入while参数表

避免犯迷糊的时候,毫无头绪

求最大公约数和最小公倍数

辗转相减法 求最大公约数

int removeGCD(int a, int b) {
	while (a != b) {
		if (a > b)a = a - b;
		if (a < b)b = b - a;
	}
	return a;
}

最小公倍数:a*b/gcd(a,b)

算出最大公约数以后直接用两数乘积除以最大公约数即是最小公倍数

多个数的最大公约数和最小公倍数

拿三个举例子,先把两个算出来,用两个数的最大公约数和另外一个数来进行计算即可

最小公倍数也是同理

用变量a给出下面的定义:

a) 一个整型数(An integer)
b) 一个指向整型数的指针( A pointer to an integer)
c) 一个指向指针的指针,它指向的指针是指向一个整型数
( A pointer to a pointer to an intege)
d) 一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数
(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
( An array of ten pointers to functions that take an integer argument and return an integer )

答一:
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
人们经常声称这里有几个问题是那种要翻一下书才能回答的问题,我同意这种说法。当我写这篇文章时,为了确定语法的正确性,的确查了一下书。但是当我被面试的时候,我期望被问到这个问题(或者相近的问题)。因为在被面试的这段时间里,我确定我知道这个问题的答案。应试者如果不知道所有的答案(或至少大部分答案),那么也就没有为这次面试做准备,如果该面试者没有为这次面试做准备,那么他又能为什么做准备呢?

让程序跳转到绝对地址是0x100000去执行 ,应该怎么做?

要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行 ,应该怎么做? 【标准答案】((void ()( void))0x100000 ) ( ); 首先要将0x100000强制转换成函数指针,即: (void ()(void))0x100000 然后再调用它: (((void (*)(void))0x100000))();

编写类string 的构造函数、析构函数和赋值函数

#include<iostream>
using namespace std;
class String
{
public:
	String(const char *str=NULL);            //普通构造函数
	String(const String &other);             //复制构造函数
	~String(void);                           //析构函数
	String & operator=(const String &other);//赋值函数
private:
	char *m_String;                        //私有成员,保存字符串
};
String::String(const char *str)
{
	cout<<"普通构造函数"<<endl;
	if(str==NULL)                         //如果str为空,存空字符串
	{
		m_String=new char[1];             //分配一个字节
		*m_String='\0';                  //将之赋值为字符串结束符
	}
	else
	{
		m_String=new char[strlen(str)+1]; //分配空间容纳str内容
		strcpy(m_String,str);             //赋值str到私有成员 
	}
}
String::String(const String &other)
{
	cout<<"复制构造函数"<<endl;
	m_String=new char[strlen(other.m_String)+1];
	strcpy(m_String,other.m_String);
}
String::~String(void)
{
	cout<<"析构函数"<<endl;
	if(m_String!=NULL)                    //如果m_String 不为NULL,释放堆内存
	{
		delete [] m_String;              //释放后置为NULL
		m_String=NULL;
	}
}
String & String::operator =(const String &other)
{
	cout<<"赋值函数"<<endl;
	if(this==&other)                   //如果对象与other是同一个对象
	{
		return *this;                  //直接返回本身
	}
	delete [] m_String;
	m_String=new char[strlen(other.m_String)+1];
	strcpy(m_String,other.m_String);
	return *this;
}
int main()
{
	String a("hello");           //调用普通构造函数
	String b("word");            //调用普通构造函数
	String c(a);                 //调用复制构造函数
	c=b;                         //调用赋值函数
	return 0;
}

strcpy的实现代码

assert 宏的原型定义在 assert.h 中,其作用是如果它的条件返回错误,则终止程序执行。

#include "assert.h" 
void assert( int expression );

assert 的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。

使用 assert 的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。

在调试结束后,可以通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 调用,示例代码如下:

#include 
#define NDEBUG 
#include
char * strcpy(char *dst,const char *src)   //[1]
{
    assert(dst != NULL && src != NULL);    //[2]

    char *ret = dst;  //[3]

    while ((*dst++=*src++)!='\0'); //[4]

    return ret;
}

声明:本文主要是转载备份教程,防止教程网址数据丢失。在每个章节的后面加有博主的个人理解以进行技术交流,本博文仅用于技术交流,如有侵权请联系博主进行删除,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值