前段时间有不少同学在后台问是否有C/C++相关面试题,本人近半年基本上都是在C/C++开发,我也在不断学习和总结着,C/C++有一些非常有意思的点,不同于Java及C#。尤其是C++11,C++14,C++17越来越丰富了C++语言。C++修炼要比Java及C#要长。一步一步来吧。总结的答案不一定都对,一定自己去使用VS实践一把,才能领会。 1、C++里面如何声明const void f(void)函数为C程序中的库函数? 2、c++中类和c语言中struct的区别(至少两点) 3、变量的声明和定义有什么区别? 4、memset ,memcpy 的区别 5、程序什么时候应该使用线程,什么时候单线程效率高。 6、介绍一下模板和容器。如何实现?(也许会让你当场举例实现) 【参考答案】: 模板可以说比较古老了,但是当前的泛型编程实质上就是模板编程。 它体现了一种通用和泛化的思想。 STL有7种主要容器:vector,list,deque,map,multimap,set,multiset.
7、以下为WindowsNT下的32位C++程序,请计算sizeof的值 8、C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?inta=5,b=7,c;c=a+++b; 【参考答案】: 这个问题将做为这个测验的一个愉快的结尾。不管你相不相信,上面的例子是完全合乎语法的。问题是编译器如何处理它?水平不高的编译作者实际上会争论这个问题,根据最处理原则,编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成: c = a++ + b; 因此, 这段代码持行后a = 6, b = 7, c = 12。 如果你知道答案,或猜出正确答案,做得好。如果你不知道答案,我也不把这个当作问题。我发现这个问题的最大好处是:这是一个关于代码编写风格,代码的可读性,代码的可修改性的好的话题
9、#include与#include“file.h”的区别? 10、如何在C中初始化一个字符数组。 【参考答案】: 这个问题看似很简单,但是我们要将最简单的问题用最严谨的态度来对待。关键的地方:初始化、字符型、数组。最简单的方法是char array[];。这个问题看似解决了,但是在初始化上好像还欠缺点什么,个人认为:char array[5]={’1′,’2′,’3′,’4′,’5′};或者char array[5]={“12345″};或者char array[2][10]={“China”,”Beijing”};也许更符合“初始化”的意思。
11、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”? 12、内存的分配方式的分配方式有几种? 【参考答案】: 1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。 2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
13、在C++程序中调用被C编译器编译后的函数,为什么要加extern'C'? 14、如何让局部变量具有全局生命期。 15、解释堆和栈的区别。 16、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明? 17、strtok函数在使用上要注意什么问题。 【参考答案】: 这个问题我不知道能不能回答全面,因为实在是用的很少。这个函数的作用是分割字符串,但是要分割的字符串不能是常量,这是要注意的。比如先定义一个字符串:char array[]=”part1,part2″;,strtok的原形是char *strtok(char *string, char *delim);,我们将”,”作为分隔符,先用pt=strtok(array,”,”);,得到的结果print出来就是”part1″,那后面的呢,要写成pt=strtok(NULL,”,”);,注意,要用NULL,如果被分割的字符串会被分成N段,那从第二次开始就一直要用NULL。总结起来,需要注意的是:被分割的字符串和分隔符都要使用变量;除第一次使用指向字符串的指针外,之后的都要使用NULL;注意使用这个函数的时候千万别把指针跟丢了,不然就全乱了。
18、用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题) 【参考答案】:#define SECONDSPERYEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。 3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。 4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。
19、说一说C与C++的内存分配方式? 【参考答案】: 1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,如全局变量,static变量。 2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 3)从堆上分配(动态内存分配)程序在运行的时候用malloc或new申请任意多少的内存,程序员负责在何时用free或delete释放内存。动态内存的生存期自己决定,使用非常灵活。
20、头文件中的 ifndef/define/endif 干什么用?预处理 21、new、delete、malloc、free关系 【参考答案】: delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
22、虚函数的作用是什么? 【参考答案】: 多态:调用同一个函数名,可以根据需要但实现不同的功能。 主要是运行时多态。 若要访问派生类中相同名字的函数,必须将基类中同名函数定义为虚函数,这样,将不同的派生类对象的地址赋值给基类指针变量后,就可以动态的调用不同类中的函数。 在派生类中重新定义基类中的虚函数时,可以不用关键字virtual来修饰这个成员函数。 在程序执行过程中,依据指针具体指向哪个对象,或依据引用哪个类对象,才能确定激活哪个版本,实现动态聚束。
23、虚析构的作用是什么? 24、什么是预编译,何时需要预编译: 25、char * const p char const * p const char *p 上述三个有什么区别? 【参考答案】: char * const p; //常量指针,p的值不可以修改 char const * p;//指向常量的指针,指向的常量值不可以改 const char *p; //和char const *p
26、C++ 标准库智能指针uniqueptr,sharedptr,weak_ptr介绍 【参考答案】: uniqueptr 只允许基础指针的一个所有者。 除非你确信需要 sharedptr,否则请将该指针用作 POCO 的默认选项。 可以移到新所有者,但不会复制或共享。 替换已弃用的auto_ptr。 sharedptr 采用引用计数的智能指针。 如果你想要将一个原始指针分配给多个所有者(例如,从容器返回了指针副本又想保留原始指针时),请使用该指针。 直至所有sharedptr 所有者超出了范围或放弃所有权,才会删除原始指针。 weakptr 结合 sharedptr 使用的特例智能指针。 weakptr 提供对一个或多个 sharedptr 实例拥有的对象的访问,但不参与引用计数。 如果你想要观察某个对象但不需要其保持活动状态,请使用该实例。
27、介绍下右值引用和移动语义及完美转发,在那些场景中用到 此题留给大家一个思考
|