C++面试题汇总

C++面试题汇总

1. new/delete和malloc/free:

delete会调用对象的析构函数,和new对应。
free只会释放内存。
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。
它们都可用于申请动态内存和释放内存。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

2. delete和delete[]:

delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。delete与new配套,delete []与new []配套

3. 常引用:

如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。

const int &a;

4. overload、override、overwrite的介绍

(1)overload(重载),即函数重载:
①在同一个类中;
②函数名字相同;
③函数参数不同(类型不同、数量不同,两者满足其一即可);
④不以返回值类型不同作为函数重载的条件。
(2)override(覆盖,子类改写父类的虚函数),用于实现C++中多态:
①分别位于父类和子类中;
②子类改写父类中的virtual方法;
③与父类中的函数原型相同。
(3)overwrite(重写或叫隐藏,子类改写父类的非虚函数,从而屏蔽父类函数):
①与overload类似,但是范围不同,是子类改写父类;
②与override类似,但是父类中的方法不是虚函数。

5. C++是不是类型安全的?

不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。C#是类型安全的。

6. main 函数执行以前,还会执行什么代码?

全局对象的构造函数会在main 函数之前执行。

7. 数组与指针的区别:

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。

8. 引用与指针有什么区别?

引用必须被初始化,指针不必。

引用初始化以后不能被改变,指针可以改变所指的对象。

不存在指向空值的引用,但是存在指向空值的指针。

9. 基类的析构函数不是虚函数,会带来什么问题?

派生类的析构函数用不上,会造成资源的泄漏。

10. 为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?

当数组名作为参数时,传递的实际上是地址。

11. 为什么需要使用堆,使用堆空间的原因?

直到运行时才知道一个对象需要多少内存空间;不知道对象的生存期到底有多长。

12. const关键字有哪些作用?

(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

13. 面向对象的三个基本特征,并简单叙述之?

  1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected, public)
  2. 继承:广义的继承有三种实现形式:
    实现继承(指使用基类的属性和方法而无需额外编码的能力)、
    可视继承(子窗体使用父窗体的外观和实现代码)、
    接口继承(仅使用属性和方法,实现滞后到子类实现)。
    前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。
  3. 多态:是将父对象设置成为和一个或更多的与他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

14. 多态的作用?

  1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
  2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。

15. 当一个类A 中没有声命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。

sizeof(A) = 1;编译器不允许一个类的大小为0,会为它分配1字节的内存。若不这样做,那2个类A的实例在内存中将会无法区分。

16. 在C++中有没有纯虚构造函数?

构造函数不能是虚的。只能有虚的析构函数。

17. 在C++的一个类中声明一个 static 成员变量有没有用?

在C++类的成员变量被声明为 static(称为静态成员变量),意味着它为该类的所有实例所共享。类的静态成员函数也只能访问静态成员(变量或函数)。static是加了访问控制的全局变量,不被继承。

18. 函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以?

只能靠参数而不能靠返回值类型的不同来区分重载函数。

19. 所有的运算符都能重载吗?

在 C++运算符集合中,有一些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。
(1)不能改变 C++内部数据类型(如 int,float 等)的运算符。
(2)不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。
(3)不能重载目前 C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。
(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。

20. extern关键字的作用:

extern置于变量或函数前,用于标示变量或函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

21. static关键字的作用:

21.1 修饰局部变量

static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。(无论是局部静态还是全局静态)

21.2 修饰全局变量

全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被该包含该定义的文件访问(即改变了作用域)。

21.3 修饰函数

static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,声明和定义需要放在同一个文件夹中。

21.4 修饰成员变量

用static修饰类的数据成员使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象,所有的对象都只维持同一个实例。 因此,static成员必须在类外进行初始化(初始化格式:int base::var=10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化。

21.5 修饰成员函数

用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量。静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。例如可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);还可以实现某些特殊的设计模式:如Singleton;

21.6 最重要的特性:隐藏

当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏。

22. 常用的设计模式:

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点;
工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。

22.1 单例模式:

22.1.1 饿汉式:

class CSingleton{
private:
    CSingleton(){}
public:
    static CSingleton * getinstance(){
        static CSingleton instance;
        return &instance;
    }
};

22.1.2 懒汉式:

class CSingleton  
{  
public:  
	static CSingleton* GetInstance()  
	{  
	     if(m_pInstance == NULL)    
	         m_pInstance = new CSingleton();  
	     return m_pInstance;  
	}  
private:  
    CSingleton(){};  
    static CSingleton * m_pInstance;  
};

23. i++是否为原子操作?

不是。
i++分为三个阶段:
内存到寄存器
寄存器自增
写回内存
这三个阶段中间都可以被中断分离开。

24.什么情况下需要将析构函数定义为虚函数?

当基类指针指向派生类的对象(多态性)时。如果定义为虚函数,则就会先调用该指针指向的派生类析构函数,然后派生类的析构函数再又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要的。

25. explicit关键字的作用?

在构造器前面加上explicit修饰, 指定这个构造器只能被明确的调用/使用, 不能作为类型转换操作符被隐含的使用。
注意:只有一个参数的构造函数,或者构造函数有n个参数,但有n-1个参数提供了默认值,这样的情况才能进行类型转换。

26. 内存溢出,内存泄漏的原因?

26.1 内存溢出:

内存溢出是指程序在申请内存时,没有足够的内存空间供其使用。原因可能如下:
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
代码中存在死循环或循环产生过多重复的对象实体;
递归调用太深,导致堆栈溢出等;
内存泄漏最终导致内存溢出。

26.2 内存泄漏:

内存泄漏是指向系统申请分配内存进行使用(new),但是用完后不归还(delete),导致占用有效内存。常见的几种情况:
(1) 在类的构造函数和析构函数中没有匹配的调用new和delete函数;
(2) 在释放对象数组时在delete中没有使用方括号;
(3)没有将基类的析构函数定义为虚函数。

27. 模板的特例化:

是对单一模板提供的一个特殊实例,它将一个或多个模板参数绑定到特定的类型或值上。

template <typename T>  
void fun(T a)  
{  
	cout << "The main template fun(): " << a << endl;  
}  

template <>   // 对int型特例化  
void fun(int a)  
{  
	cout << "Specialized template for int type: " << a << endl;  
}  

int main()  
{  
	fun<char>('a');  
	fun<int>(10);  
	fun<float>(9.15);  
	return 0;  
}  

对于除int型外的其他数据类型,都会调用通用版本的函数模板fun(T a);对于int型,则会调用特例化版本的fun(int a)。注意,一个特例化版本的本质是一个实例,而非函数的重载。

28. C++11新特性:

28.1 可变参数模板(Variadic Template):(?)

template<typename… Types>

28.2 右尖括号(Right Angle Brackets):

在C++11之前,两个右尖括号之间必须加个空格。
C++ 11中,加或者不加空格,都可以识别了。

28.3 空指针(nullptr):

C++11之前没有关键字nullptr(其对应的类型为std::nullptr_t)。
nullptr用于替换0或者NULL,因为NULL本身是定义为0的,有时候使用会产生歧义。

28.4 auto关键字:

在C++11中,可以auto定义变量,而不指定变量的类型。
编译器会从等号右边的表达式或变量来推断auto变量的类型。
auto 一般用于替代变量类型名字太长,或表达式类型太复杂的场景。

28.5 统一初始化(Uniform Initialization):

C++11之前,有三种为变量或对象初始化的方式,大括号,小括号, 赋值符号。
C++11引入统一的初始化方式 ————统一使用大括号。
C++11也兼容之前的小括号和赋值符号的初始化方式。

28.6 关键字explicit:

见25条。

28.7 基于范围的for循环(range-based for statement):

    for(int i : {1,2,3,4})
    {
        std::cout<<i<<std::endl;
    
    }
    
    std::vector<int> vec{4,5,6};
    for(auto& j : vec)
    {
        std::cout<<j<<std::endl;
        std::cout<<"j的地址:"<<&j<<",vec[0]的地址"<<&vec[0]<<std::endl;
    
    }

28.8 =default/=delete:(?)

29. 稳定和不稳定排序:

29.1 稳定排序:

冒泡排序、插入排序、归并排序 、基数排序。

29.2 不稳定排序:

选择排序、快速排序、希尔排序(shell) 、堆排序。

30. static_cast:

static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。
static_cast不能转换掉expression的const、volatile、或者__unaligned属性。

char a = 'a';
int b = static_cast<char>(a);//正确,将char型数据转换成int型数据

double *c = new double;
void *d = static_cast<void*>(c);//正确,将double指针转换成void指针

int e = 10;
const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据

const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

31. 大小端:

大端指的就是把字节序的尾端(0xcd)放在高内存地址,而小端指的就是把字节序的尾端(0xcd)放在低内存地址。

32. VC 中,编译工具条内的 Debug 与 Release 选项是什么含义?

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 带有大量的调试代码,运行时需要相应的运行库,发布模式程序紧凑不含有调试代码和信息,直接可以运行(如果不需要运行库)

33. 函数 assert 的用法?

断言assert是仅在debug版本起作用的宏,用于检查“不应该“发生的情况。
程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。

34. const 与 #define 的比较 ,const有什么优点?

(1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。
而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应) 。
(2)有些集成化的调试工具可以对 const 常量进行调试,但是不能对宏常量进行调试。

35. 引用和指针的区别:

(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化) 。
(2)不能有 NULL 引用,引用必须与合法的存储单元关联(指针则可以是 NULL) 。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象) 。

36. 如何判断一个操作系统是16位还是32位的?

定义一个指针p,打印出sizeof(p),如果结果是4,则表示该操作系统是32位,打印结果是2,表示是16位。

37. 多态类中的虚函数表是 Compile-Time,还是 Run-Time 时建立的?

虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员–虚拟函数表指针是在运行期–也就是构造函数被调用时进行初始化的,这是实现多态的关键。

38. 多态的作用?

  1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
  2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。

39. 函数模板与类模板有什么区别?

函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。

40. 如何打印出当前源文件的文件名以及源文件的当前行号?

cout << __FILE__ ;
cout<<__LINE__ ;

__FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。(C也有)

41. 重入和不可重入

这种情况出现在多任务系统当中,在任务执行期间捕捉到 信号 并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时 中断 。如果从信号处理程序返回,则继续执行进程断点处的正常指令序列,从重新恢复到断点重新执行的过程中,函数所依赖的环境没有发生改变,就说这个函数是 可重入 的,反之就是 不可重入 的。
满足下面条件之一的多数是不可重入函数:
(1)使用了静态数据结构;
(2)调用了malloc或free;
(3)调用了标准I/O函数;标准io库很多实现都以不可重入的方式使用全局数据结构。
(4)进行了浮点运算.许多的处理器/编译器中,浮点一般都是不可重入的 (浮点运算大多使用协处理器或者软件模拟来实现)。

42. c++11 最简单的线程安全的单例模式

https://blog.csdn.net/lgfun/article/details/105810039

43. 在c++中,运算符和函数有什么区别?

语法形式上有区别;
运算符只能重载,不能自定义;
任何函数都可以重载或者覆盖,但通常你不能改变运算符作用于内置类型的行为。

44. c++和c的不兼容性

44.1 const修饰符

const 变量是否可以用作常量表达式呢? C不行,C++ 可以。

44.2 void *指针

作为通用指针, void * 可以和其他任意类型的指针相互转换, 但 C 语言中这种类型转换是隐式的(implicit conversion), 而在 C++ 中必须有显式的类型转换(explicit conversion)。

44.3 auto 关键字

auto 关键字在 C 语言中早就存在, 它用来修饰变量, 表示变量拥有自动存储 (automatic storage), 和静态存储相反。 但是呢, 在函数内, 静态存储的变量需要用 static关键字修饰, 其他变量默认都是自动存储的, 所以 auto 这个关键字不用也可以.

44.4 。。。。。。

45.

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: "C面试题集锦pdf"是一本包含了一系列与C语言相关的面试题的PDF文件集合。面试题集锦通常包含了不同难度和类型的问题,旨在帮助求职者准备并提升他们在C语言面试中的竞争力。 这本PDF文件对于正在寻求C语言相关职位的求职者来说可能非常有用。使用这本面试题集锦,求职者可以在面试前评估和发展自己的C语言技能,并了解他们在这个领域的优势和不足。这些问题涵盖了C语言的各个方面,包括基本语法、数据类型、指针、数组、字符串、函数、结构体、文件处理等。 解答这些问题,求职者需要对C语言的基本概念、语法和常见问题有深入的理解。这本面试题集锦可以帮助求职者巩固他们在C语言方面的知识和技能,提高他们的编码和解决问题的能力。 此外,这个面试题集锦也适用于想要测试自己在C语言方面知识的学生、程序员或其他对C语言感兴趣的人。无论是自学还是参与编程竞赛,这个PDF文件都可以作为一个很好的练习和自测资源。 总之,"C面试题集锦pdf"是一个有助于求职者准备C语言面试的资源。它涵盖了C语言的各个方面,提供了丰富的问题和答案,对于想要提高他们的C语言知识和技能的人们来说是一个非常有价值的资源。 ### 回答2: "C面试题集锦 PDF" 是一本汇集了不同公司常见的C语言面试题的PDF文档。对于寻求C语言开发职位的求职者来说,这本面试题集锦是一个非常有用的资源。 该面试题集锦通常包含了C语言的基础知识和常见的面试问题。它可以帮助求职者准备面试,了解可能会被问到的问题,并提供答案示例。这些问题可能涉及概念(如指针、数据类型等)、语法、算法和数据结构等方面。 这本面试题集锦通常被分为不同的章节或主题。每个主题都会列出一系列相关的问题。对于每个问题,通常会提供一个解答和解释。这样的设计有助于求职者理解和掌握C语言的基本知识,并在面试中能够准确地回答问题。此外,该面试题集锦还可能包含一些示例代码,供求职者参考。 求职者可以通过阅读和练习这本面试题集锦,提前熟悉和理解可能出现的面试问题。他们可以针对每个问题尝试编写自己的答案,并确保对关键概念和算法有深入的理解。这样,在实际面试中,他们就能够更加自信地回答问题,并展示自己的技能和知识。 综上所述,"C面试题集锦PDF" 对于想要在C语言开发领域找工作的求职者来说,是一个非常有价值的资源。它可以帮助他们准备面试,提升他们的技能水平,并在求职过程中取得成功。 ### 回答3: 《面试题集锦 PDF》是一本收集了各种类型面试题的电子书,旨在帮助求职者更好地准备面试。此书包含了常见的面试题目,涵盖了各个行业和职位。读者可以通过阅读这本书,了解不同类型的面试题目及其答题技巧,提升自己的面试表现。 这本电子书的特点之一是提供了详细的解答和解析。每个面试题目都会给出参考答案,并解释为什么这样的答案是最佳选择。这对于读者来说非常有帮助,可以加深他们对问题的理解,学会如何结合自己的经验和能力给出合适的回答。 《面试题集锦 PDF》还在每个面试题目后提供了一些额外的建议和提示。这些建议包括面试前的准备工作、面试时的表现技巧以及面试后的反思与总结。通过阅读这些额外的建议,读者可以更全面地了解整个面试过程,并针对性地提升自己的能力。 总而言之,《面试题集锦 PDF》是一本非常有价值的求职辅助资料。无论是初次求职还是已经有一定工作经验的人,都可以从中获得宝贵的经验和知识。通过认真阅读并实践其中的内容,读者可以提高自己的面试能力,增加成功通过面试的机会,从而更好地获得理想的工作机会。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值