c++ 经典面试问题及答案_完成C面试问题答案

本文汇总了C++面试中常见的经典问题及详细答案,帮助应聘者准备C++相关的技术面试,涵盖语言特性、算法应用等多个方面。

c++ 经典面试问题及答案

The article cover’s most commonly asked interview questions in c++ and a brief explanation of each question.

本文介绍了c ++中最常问到的面试问题,并简要解释了每个问题。

1. What is OOPS?

1.什么是OOPS?

Object-oriented programming is a programming paradigm based on the concept of “objects” of the classes, Objects may contain data in the form of fields and associated code in the form of methods. The objects can access their own procedures and can modify their data fields.

面向对象编程是基于类的“对象”概念的编程范例,对象可以包含字段形式的数据和方法形式的关联代码。 对象可以访问自己的过程,并可以修改其数据字段。

2. What is function overloading, how did it make the lives of C++ programmer better than C programmer?

2.什么是函数重载,它如何使C ++程序员的生活比C程序员更好?

In C++ it’s allowed to make functions with the same name in the same scope. The functions with the same name are called overloaded functions. The difference that must exist between the two functions with the same name is the parameters that are being passed. Function overloading can be done by using different parameter types and changing the number of arguments. C, on the other hand, doesn’t support function overloading which reduces the code quality and readability.

在C ++中,允许在相同范围内使用相同名称创建函数。 具有相同名称的函数称为重载函数。 具有相同名称的两个函数之间必须存在的区别是要传递的参数。 函数重载可以通过使用不同的参数类型并更改参数数量来完成。 另一方面,C不支持函数重载,这会降低代码质量和可读性。

3. How is function overloading achieved?

3.如何实现函数重载?

The program below has “add” function with two different implementations. One for double data type numbers and another for integers. The function has the same name but different parameters so it’s a clear example of function overloading.

下面的程序具有“添加”功能,具有两种不同的实现方式。 一个用于双精度数据类型数字,另一个用于整数。 该函数具有相同的名称,但参数不同,因此是函数重载的一个清晰示例。

#include<bits/stdc++.h>
using namespace std;
int add(int a, int b){//Add Integers
return a+b;
}
double add(double a, double b){//Add Double
return a+b;
}
int main(){
cout<<"Integer Type Numbers after addition : "<<add(1,2)<<"\n";
cout<<"Double Type Numbers after addition : "<<add(1.1,2.2);
}Output:
Integer Type Numbers after addition : 3
Double Type Numbers after addition : 3.3

4. what is dynamic binding?

4.什么是动态绑定?

To Understand Dynamic binding let’s see what are virtual functions and what binding means.

要了解动态绑定,让我们看看什么是虚函数以及绑定的含义。

Binding refers to the process of converting identifiers such as variable and function calls into addresses by the compiler.

绑定是指编译器将诸如变量和函数调用之类的标识符转换为地址的过程。

Virtual Function in c++ is a function which is defined in“Base” class and overridden in “Derived” class. It is made by adding “virtual” keyword in the function definition.Dynamic Binding: In C++ when the compiler is not able to decide which function to call at compile time but computes the same at runtime then this type of binding is known as dynamic binding.An example of Dynamic Binding is when a virtual function is defined in “Base” class and overridden in “Derived” class, and this function is called with the help of pointer of the base class that stores the address of the object of “Derived Class”.

c ++中的虚函数是在“基础”类中定义并在“派生”类中覆盖的函数。 它是通过在函数定义中添加“ virtual”关键字来实现的。 动态绑定:在C ++中,当编译器无法决定在编译时调用哪个函数,但在运行时对其进行计算时,这种绑定称为动态绑定。 动态绑定的一个示例是在“基础”类中定义虚拟函数并在“派生”类中重写虚拟函数,然后在存储“派生类”对象地址的基类的指针的帮助下调用此函数”。

#include<bits/stdc++.h>
using namespace std;
class Base{
public:
virtual void print(){
cout<<"Base Class";
}
};
class Derived : public Base{
public:
void print(){
cout<<"Derived Class";
}
};
int main(){
Base *ptr;
Derived d;
ptr=&d;
ptr->print();
}Output : Derived Class

In the above program when the compiler compiles the program a pointer named “ptr” is made which is initialized by the address of an object of a derived class and this address is only available at compile time. With this information, the compiler is able to know which print function is being referenced by the programmer so as a result derived class “print” function is called.

在上述程序中,当编译器编译程序时,将创建一个名为“ ptr”的指针,该指针由派生类的对象的地址初始化,并且该地址仅在编译时可用。 有了这些信息,编译器便能够知道程序员正在引用哪个打印功能,从而可以调用结果派生类“ print”功能。

5. What is an abstract class?

5.什么是抽象类?

Abstract class in c++ is a Class that has no object and that Class consists of at least one pure virtual function. We are not allowed to make instances of Abstract classes. This class as its name suggests provides us with a level of abstraction about the functionalities we are going to encounter in a program like the print functionality explained below.Example:

c ++中的抽象类是一个没有对象的类,并且该类至少包含一个纯虚函数。 我们不允许创建Abstract类的实例。 顾名思义,该类为我们提供了有关程序中将要遇到的功能(如下面说明的打印功能)的抽象级别。 例:

#include<bits/stdc++.h>
using namespace std;
class Base{
public:
virtual void print()=0;
};
class Derived : public Base{
public:
void print(){
cout<<"Abstract Class print method defination.";
}
};
int main(){
ptr=&d;
d.print();
}

The pure virtual “print” function is declared in the Abstract class named “Base” and defined in “Derived” class, in this way the abstract class provided us with the abstraction to what we are going to encounter. If the Derived class inherits the abstract class and does not define the pure virtual functions of Base class then it also becomes an Abstract class.

纯虚拟“ print”函数在名为“ Base”的Abstract类中声明,并在“ Derived”类中定义,以这种方式,abstract类为我们提供了将要遇到的内容的抽象。 如果Derived类继承了Abstract类并且未定义Base类的纯虚函数,则它也将成为Abstract类。

6. What happens under the hood for virtual functions? (vPointer, vTable etc)

6.虚拟功能的幕后发生了什么? (vPointer,vTable等)

For understanding this part let’s go on to the example we considered while learning Dynamic Binding.

为了理解这一部分,让我们继续学习动态绑定时考虑的示例。

#include<bits/stdc++.h>
using namespace std;
class Base{
public:
virtual void print(){
cout<<"Base Class";
}
};
class Derived : public Base{
public:
void print(){
cout<<"Derived Class";
}
};
int main(){
Base *ptr;
Derived d;
ptr=&d;
ptr->print();
}Output : Derived Class

As in the above program, ptr is a pointer to Base class but still ptr->print() calls the “print” function of Derived class.Let’s understand what internally happens here:

与上面的程序一样,ptr是指向基类的指针,但是ptr-> print()仍然调用Derived类的“ print”函数。让我们了解内部发生的事情:

  1. For every class that has a virtual function, compiler maintains a vTable that contains information about all virtual functions inside the class.

    对于每个具有虚拟功能的类,编译器都会维护一个vTable,该表包含有关该类内部所有虚拟功能的信息。
  2. For every object of the class, the first 4 bytes contain the pointer to vTable of the class it belongs to, and this pointer is called vPointer.

    对于该类的每个对象,前4个字节包含指向其所属类的vTable的指针,该指针称为vPointer。

The above two points are the reason that ptr in the above program even being the pointer of Base class calls the print function of the derived class, as ptr=&d where d is an object of the derived class and it’s first 4 bytes contain vPointer that point to vTable of Derived class which contains the print function.

以上两点是上述程序中的ptr甚至是基类的指针都调用派生类的打印函数的原因,因为ptr =&d其中d是派生类的对象,并且它的前4个字节包含vPointer指向包含打印功能的派生类的vTable。

7. What is the diamond problem?

7.什么是钻石问题?

The problem when two classes inherit a base class and those two classes are inherited by another class then the class that inherits both the classes has two copies of the methods and properties of the base class.

问题是当两个类继承一个基类,而这两个类又被另一个类继承时,则同时继承这两个类的类具有该基类的方法和属性的两个副本。

  A
/ \
B C // B and C inherit A
\ /
D // D inherit both B and C so has A two times

The below program will give an error:

下面的程序将给出一个错误:

#include<bits/stdc++.h>
using namespace std;
class Base{
public:
int a=10;
};
class Derived1 : public Base{
public:
int b=20;
};
class Derived2 : public Base{
public:
int c=30;
};
class Derived3 : public Derived1, public Derived2{
public:
int d=40;
};
int main(){
Derived3 d;
cout<<d.a;
}

The error is that a comes twice in Derived3 class and compiler finds ambiguity in data member a.To solve this problem we inherit Base class virtually in Derived1 & Derived2 which makes only one instance of data member a and thus solves the diamond problem.The right code will be:

错误是a在Derived3类中出现两次,并且编译器发现数据成员a中存在歧义。为解决此问题,我们实际上在Derived1和Derived2中继承了基类,该基类仅使数据成员a成为一个实例,从而解决了菱形问题。代码将是:

#include<bits/stdc++.h>
using namespace std;
class Base{
public:
int a=10;
};
class Derived1 : public virtual Base{
public:
int b=20;
};
class Derived2 : public virtual Base{
public:
int c=30;
};
class Derived3 : public Derived1, public Derived2{
public:
int d=40;
};
int main(){
Derived3 d;
cout<<d.a;
}

8. What is operator overloading?

8.什么是操作员超载?

Normally a “+” operator would be used to add two numbers, but if we want to add objects of two classes then it is also possible, for that operator overloading as a concept is used.

通常,将使用“ +”运算符将两个数相加,但是如果我们要添加两个类的对象,则也有可能,因为该运算符使用了概念重载。

Consider the below program:

考虑下面的程序:

#include<bits/stdc++.h>
using namespace std;
class A{
public:
int a=10;
};class B{
public:
int a=20;
};
int operator+(A obj1,B obj2){
return obj1.a+obj2.a;
}
int main(){
A obj1;
B obj2;
cout<<obj1+obj2;
}
Output: 30

In the above program, as we see the two objects get added, this is because we overloaded the + operator. For overloading, we defined int as the return value of “operator+” function which takes two arguments that are objects of the two classes. So with this way, we were able to add two objects using the + operator. Operator overloading works similarly for all overloadable operators.Non Overloadable operators are:

在上面的程序中,我们看到添加了两个对象,这是因为我们重载了+运算符。 对于重载,我们将int定义为“ operator +”函数的返回值,该函数采用两个参数作为两个类的对象。 因此,通过这种方式,我们能够使用+运算符添加两个对象。 运算符重载对于所有可重载运算符的工作方式都相似。

::
.
*.
?:

9. What is a namespace?

9.什么是名称空间?

A namespace is a declarative region that provides a scope to identifiers inside it. A Namespace helps to group elements in groups to provide collisions when multiple libraries are being used. Identifiers in one namespace are visible to each other without qualification, but for variables outside the same namespace needs to be specified with a fully qualified name for example: “std:: string”.

命名空间是一个声明性区域,它为其中的标识符提供范围。 命名空间有助于将元素分组,以在使用多个库时提供冲突。 一个命名空间中的标识符无需限定即可彼此可见,但是对于同一命名空间之外的变量,则需要使用完全限定的名称来指定,例如:“ std :: string”。

10. When and why will you use static functions in a class?

10.什么时候以及为什么要在类中使用静态函数?

A static function is used in a class when the objects of the class share a common function that doesn’t need to have a new copy for each object of that class.

当类的对象共享一个不需要为该类的每个对象创建新副本的通用函数时,该类中将使用静态函数。

#include<bits/stdc++.h>
using namespace std;
class A{
public:
static printName(){
cout<<"I am object of class A\n";
}
int a;
};
int main(){
A obj1;
A obj2;
obj1.printName();
obj2.printName();
}Output:
I am object of class A
I am object of class A

In the above program for each object “printName ”function will remain the same, so putting static keyword before the function definition makes only one shared function for each object of class A.

在上面的程序中,每个对象的“ printName”功能将保持不变,因此将static关键字放在函数定义之前,只会为A类的每个对象提供一个共享功能。

11. Do you have an idea about Standard Template Library In C++?

11.您对C ++中的标准模板库有想法吗?

Standard Template Library in c++ is a set of template classes that provides a direct implementation of common data structures like a stack, queue, list, set etc. STL has four major categories that are:

c ++中的标准模板库是一组模板类,它们提供对常见数据结构(如堆栈,队列,列表,集合等)的直接实现。STL具有四个主要类别:

  • Algorithms

    演算法
  • Containers

    货柜
  • Functions

    功能
  • Iterators

    迭代器

12. How are errors handled in C++?

12.如何用C ++处理错误?

In C++ exceptions are handled with the help “try ”and “catch ” blocks. The block of code that may throw an exception is kept under try block.Example:

在C ++中,异常通过帮助“ try”和“ catch”块进行处理。 可能引发异常的代码块位于try块下。示例:

#include<bits/stdc++.h>
using namespace std;
float divide(float a,float b){
try{
if(b!=0){
return a/b;
}
else{
throw "Divide By Zero Exception\n";
}
}
catch(const char* err){
cout<<err;
}
}
int main(){
cout<<divide(1.2,0);
}Output: Divide By Zero Exception

Some other must know Questions are:

其他一些必须知道的问题是:

  1. Difference Between C & C++?

    C和C ++之间的区别?

  2. Do you have an idea what metaprogramming is? How is it achieved in C++?

    您知道什么是元编程吗? 如何在C ++中实现?

  3. How many kinds of castings are available in C++, how is it better than C?

    C ++提供了几种类型的转换,它比C好吗?

翻译自: https://medium.com/analytics-vidhya/complete-c-interview-questions-answers-8dc1fbe5b06b

c++ 经典面试问题及答案

doc格式,60多页吧,几百道题吧,都有答案吧,看好在下!部分:1.求下面函数的返回值(微软)int func(x) { int countx = 0; while(x) { countx ++; x = x&(x-1); } return countx; } 假定x = 9999。 答案:8思路:将x转化为2进制,看含有的1的个数。2. 什么是“引用”?申明和使用“引用”要注意哪些问题?答:引用就是某个目标变量的“别名”(alias),对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候,切记要对其进行初始化。引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表示该引用名是目标变量名的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元,系统也不给引用分配存储单元。不能建立数组的引用。3. 将“引用”作为函数参数有哪些特点?(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。4. 在什么时候需要使用“常引用”? 如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标识符 &引用名=目标变量名;例1int a ;const int &ra=a;ra=1; //错误a=1; //正确 例2string foo( );void bar(string & s); 那么下面的表达式将是非法的:bar(foo( ));bar("hello world"); 原因在于foo( )和"hello world"串都会产生一个临时对象,而在C++中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。引用型参数应该在能被定义为const的情况下,尽量定义为const 。5. 将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?格式:类型标识符 &函数名(形参列表及类型说明){ //函数体 }好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束,相应的引用也会失效,产生runtime error!注意事项:(1)不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。 (2)不能返回函数内部new分配的内存的引用。这条可以参照Effective C++[1]的Item 31。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。(3)可以返回类成员的引用,但最好是const。这条原则可以参照Effective C++[1]的Item 30。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。(4)流操作符重载返回值申明为“引用”的作用:流操作符<>,这两个操作符常常希望被连续使用,例如:cout << "hello" << endl; 因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个<<操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用<<操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是C++语言中引入引用这个概念的原因吧。 赋值操作符=。这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。例3#i nclude int &put(int n);int vals[10];int error=-1;void main(){put(0)=10; //以put(0)函数值作为左值,等价于vals[0]=10; put(9)=20; //以put(9)函数值作为左值,等价于vals[9]=20; cout<<vals[0]; cout<<vals[9];} int &put(int n){if (n>=0 && n<=9 ) return vals[n]; else { cout<<"subscript error"; return error; }} (5)在另外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。它们不能返回引用,Effective C++[1]的Item23详细的讨论了这个问题。主要原因是这四个操作符没有side effect,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回一个对象、返回一个局部变量的引用,返回一个new分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第2、3两个方案都被否决了。静态对象的引用又因为((a+b) == (c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。6. “引用”与多态的关系?引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。例4Class A; Class B : Class A{...}; B b; A& ref = b;7. “引用”与指针的区别是什么?指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。此外,就是上面提到的对函数传ref和pointer的区别。8. 什么时候需要“引用”?流操作符<>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。以上 2-8 参考:http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx9. 结构与联合有和区别?1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。 2. 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。10. 下面关于“联合”的题目的输出?a)#i nclude union{int i;char x[2];}a;void main(){a.x[0] = 10; a.x[1] = 1;printf("%d",a.i);}答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)………………
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值