c/c++面试题

来源:互联网 发布:网络建设实施方案 编辑:程序博客网 时间:2024/06/13 07:23

还有 http://blog.csdn.net/jingxuewang110/article/details/6789557

http://www.cppblog.com/Cunch/archive/2011/04/12/144038.html

近期面试,下面这些是经常被问到的C/C++基础的内容。

1. 一般问const、static、extern、mutable、volatile的用法和注意点?

 

2.new失败和malloc失败

答:

  C++中new失败会抛异常,默认不会返回NULL,

int* p = new (std::nothrow) int,这样new失败后才返回NULL。对于C++服务端程序来说无时无刻都在处理内存,只要出现内存申请失败必须查找原因,是内存泄漏造成资源耗尽还是其他原因。

  C中malloc失败只会返回NULL

3.多态是怎么实现的?

答:

  虚函数表

  虚函数表指针

4.linux内存适配器,malloc 的实现

答:

  malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。

5.友元的作用

答:

  友元函数是可以直接访问类的私有成员的非成员函数, 友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。

6.深拷贝和浅拷贝

答:

我在这篇文章中有过描述,《C++的深拷贝和浅拷贝》:

  http://www.cnblogs.com/ahuner/archive/2012/06/23/3151716.html

7.vector释放内存方式

答:

   我们在使用list/map等stl容器时候都知道clear()或者遍历erase()能释放容器占的内存,可由于vector的实现机制问题,clear()和erase()都不能够释放容器内存。

这个问题在《Effective STL》条款17:使用“交换技巧”来修整过剩容量中给过解决方法:

int main() {     std::vector<int> vecint;vecint.push_back(1);vecint.push_back(2);vecint.push_back(3);printf("capacity:%d\n", vecint.capacity());vecint.clear();printf("capacity:%d\n", vecint.capacity());std::vector<int>(vecint).swap(vecint); printf("capacity:%d\n", vecint.capacity());return 0; }

输出结果为:

3

3

0

8.strcpy实现

答:

char *strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) && (strSrc != NULL) );char *address = strDest;while( (*strDest++ = * strSrc++) != '\0') ;    return address; }

9.memcpy实现

答:

void *memcpy(void *dest, const void *src, size_t count){if (count<0)return (void*)0;if(src==NULL||dest==NULL)return (void*)0 ;char *tmp = (char *)dest;const char *s = (const char *)src;while (count--)*tmp++ = *s++;return dest;}

10.string类的普通构造函数、拷贝构造函数、赋值函数的实现

答:

class string{public:string(const char *str = NULL);string(const string &other);   ~string(void);    string &operate =(const string &other);private:char *m_data;};string::string(const char *str){if(str==NULL){m_data = new char[1]; *m_data = '/0';}    else{int length = strlen(str);m_data = new char[length+1]; strcpy(m_data, str);}} string::~string(void){delete []m_data; }string::string(const string &other) {     int length = strlen(other.m_data);m_data = new char[length+1]; strcpy(m_data, other.m_data);    } string &string::operate =(const string &other) //不是很好,见effective c++{     if(this == &other)                 return *this;   delete [] m_data;            int length = strlen( other.m_data );      m_data = new char[length+1]; strcpy( m_data, other.m_data );   return *this;    }

11. extern的作用

答:

(1).修饰变量或者函数:extern可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义

(2). extern“C”:告诉C++编译器里面的函数结构采用C语言函数,这段代码就是让C和C++编译器都能兼容调用这些函数接口。

#ifdef __cplusplusextern "C" {#endifvoid interface_test();#ifdef __cplusplus}#endif

12.float变量与"0"比较的代码

答:

const float EPSINON = 0.00001;

if ((x >= - EPSINON) && (x <= EPSINON)

13.类成员函数的重载、覆盖和隐藏区别

答:

成员函数被重载的特征:

(1)相同的范围(在同一个类中);

(2)函数名字相同;

(3)参数不同;

(4)virtual 关键字可有可无。

覆盖是指派生类函数覆盖基类函数,特征是:

(1)不同的范围(分别位于派生类与基类);

(2)函数名字相同;

(3)参数相同;

(4)基类函数必须有virtual 关键字。

“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。

(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

http://blog.csdn.net/liuzhanchen1987/article/details/7990756

14.判断大小端

答:

bool checkCPU(){union w{int a;char b;}c;c.a = 1;return(c.b ==1); // (小端模式: c.a为ox000000001 c.b为ox01)// &c.a 4字节的内存中存储的数据分别是01 00 00 00// 所以true为小端,false为大端}

15.static的作用

答:

(1).static可以用作函数和变量的前缀,都有隐藏的作用;
如果函数和变量都加上static前缀,就能使的该函数和变量只能在这个源文件中可见,对其他文件隐藏,利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
(2).static可以保持变量内容的持久。

(3).static可以默认初始化为0。

16.const的作用

(1).const修饰指针:

int arr[5] = {1,2,3,4,5}; 
int oth[6] = {5,6,7,8,9,0}; 
const int *p = arr; // 一个指向常整型数的指针
// p[0] = 9; // error:不能修改指向的内容
p = oth; // ok:能重新指向其他对象

int* const pp = arr; // 一个指向整型数的常指针
pp[0] = 9; // ok:能修改指向的内容
// pp = oth; // error:不能重新指向其他对象

int const* const ppp = arr; // 一个指向常整型数的常指针
// ppp[0] = 9; // error:不能修改指向的内容
// ppp = oth; // error:不能重新指向其他对象

(2).const修饰函数返回值:说明函数返回值内容不能修改。

(3).const放在函数后面:说明在该函数内部不能修改类的成员变量,但可以修改mutable修饰的成员变量。

17.只能在栈上分配空间的类 http://blog.csdn.net/jia_xiaoxin/article/details/2972981

class teststackclass {     private:         void *operator new(size_t size); };   int main() {     teststackclass s; // okteststackclass * ps = new teststackclass (); //error: “teststackclass::operator new”: 无法访问teststackclass声明的private 成员 return 0; }

18.只能在堆上分配内存的类

class testheapclass  {     public:         testheapclass(){};         void destroy(){/*delete this */}     private:            ~testheapclass(){} };   int main() {     testheapclass h ;      //error    testheapclass *ph = new testheapclass(); //ok,但释放这个对象时候需要显示调用destroy}

19.小端存储

long long a=0x1;

long long b=0x2;

long long c=0x3;       

printf("%d%d%d",a,b,c); 

输出结果为:102

原因:

a地址的存储:0x01000000 00000000

b地址的存储:0x02000000 00000000

c地址的存储:0x03000000 00000000

printf截断4字节输出

原创粉丝点击