C++常见面试问题

目录

    • C和C++的区别是什么?
    • 什么是面向对象编程?类的三大特性是什么?
    • STL库用过吗?常见的STL容器有哪些?算法用过哪几个?
      • C++STL里面7个常用容器的比较
      • 常用STL容器总结
      • STL常见算法
    • 什么是多态?虚函数和虚函数表理解吗?
    • 当用父类指针去初始化一个子类对象时,当使用该指针去调用父类中被复写的虚函数时,是怎么动态绑定到子类的虚函数上的?
      • c++中动态绑定的技术实现
    • 类对象在内存中的布局情况是怎样的,当发生继承时,子类对象和父类对象的布局又是怎样的?
    • static、const,分别修饰类成员、类函数分别有怎样的表现?修饰普通变量呢?
    • extern关键字的作用了解吗?
    • 函数参数const传值知道吗?为什么要用const修饰函数参数?
    • 解释下野指针与悬空指针。
    • 什么是内存泄漏?怎么有效检查程序的内存泄漏?
    • New 和malloc的区别是什么?
    • 系统调用

C和C++的区别是什么?

设计思想上:

C++是面向对象的语言,而C是面向过程的结构化编程语言

语法上:

C++具有封装、继承和多态三种特性

C++相比C,增加多许多类型安全的功能,比如强制类型转换、

C++支持范式编程,比如模板类、函数模板等

什么是面向对象编程?类的三大特性是什么?

面向过程 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
面向对象 是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

面向过程

优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
缺点:没有面向对象易维护、易复用、易扩展

面向对象

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护
缺点:性能比面向过程低

类的三大特性是什么

STL库用过吗?常见的STL容器有哪些?算法用过哪几个?

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。这种现象有些类似于Microsoft Visual C++中的MFC(Microsoft Foundation Class Library),或者是Borland C++ Builder中的VCL(Visual Component Library),对于此二者,大家一定不会陌生吧。

从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术。

从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,这种方式基于一个在早先C++标准中没有出现的语言特性–模板(template)。如果查阅任何一个版本的STL源代码,你就会发现,模板作为构成整个STL的基石是一件千真万确的事情。除此之外,还有许多C++的新特性为STL的实现提供了方便。

C++STL里面7个常用容器的比较

常用STL容器总结

STL常见算法

什么是多态?虚函数和虚函数表理解吗?

当用父类指针去初始化一个子类对象时,当使用该指针去调用父类中被复写的虚函数时,是怎么动态绑定到子类的虚函数上的?

c++中动态绑定的技术实现

类对象在内存中的布局情况是怎样的,当发生继承时,子类对象和父类对象的布局又是怎样的?

类对象在内存中的布局

static、const,分别修饰类成员、类函数分别有怎样的表现?修饰普通变量呢?

static的作业:

  1. 全局静态变量
    在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.

静态存储区,在整个程序运行期间一直存在。

初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);

作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。

  1. 局部静态变量

在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。

内存中的位置:静态存储区

初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化);

作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变;

  1. 静态函数

在函数返回类型前加static,函数就定义为静态函数。函数的定义和声明在默认情况下都是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。

函数的实现使用static修饰,那么这个函数只可在本cpp内使用,不会同其他cpp中的同名函数引起冲突;

warning:不要再头文件中声明static的全局函数,不要在cpp内声明非static的全局函数,如果你要在多个cpp中复用该函数,就把它的声明提到头文件里去,否则cpp内部声明需加上static修饰;

  1. 类的静态成员

在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。对多个对象来说,静态数据成员只存储一处,供所有对象共用

  1. 类的静态函数

静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。

在静态成员函数的实现中不能直接引用类中说明的非静态成员,可以引用类中说明的静态成员(这点非常重要)。如果静态成员函数中要引用非静态成员时,可通过对象来引用。从中可看出,调用静态成员函数使用如下格式:<类名>::<静态成员函数名>(<参数表>);

const是一个修饰符,被修饰的对象或者变量是不可修改的,也就是说const可读不可改,const在谁的后面const就修饰谁,如果const在最前面,那么将const后移一位即可,二者是等效的。

const有以下这几个作用:(1)如果我们想要阻止一个变量被改变,那么我们就可以使用const关键字来修饰它,由于被const修饰的对象或者变量是可读不可写的,因此我们在使用const的使用要对所修饰的对象或者变量进行初始化,否则以后没有机会再改变他的值。(2)对于指针来说,const可以修饰指针本身,也可以修饰指针所指的数据,也可以修饰两者。(3)在对一个函数进行声明的时候,可以使用const对形参进行修饰,表明它是一个输入参数,在函数的内部不可写。(4)对于类的成员函数,如果被const修饰,表明它是一个常函数,不能修改类的成员变量。(5)对于类的成员函数,有时候必须指定其返回值类型是const,这样使得该函数的返回值不是“左值”。

extern关键字的作用了解吗?

extern关键字有两个作用

一、告知编译器:当extern与“c”一起使用的时候,就是告诉编译器,下面的函数或者变量以C语言的方式编译。这里主要是因为一方面我们可以使用C语言写成的项目运用到C++中,另一方面由于C++支持重载而C不支持,这就导致了C++在编译的时候,C++的函数名会和参数一起被编成函数名,而C只是函数名。所以在链接的时候,找不到我们定义的那个函数。

二、就是共享:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。

函数参数const传值知道吗?为什么要用const修饰函数参数?

const 修饰函数的参数和作为返回值

解释下野指针与悬空指针。

空悬指针是这样一种指针:指针正常初始化,曾指向过一个正常的对象,但是对象销毁了,该指针未置空,就成了悬空指针。

野指针是这样一种指针:未初始化的指针,其指针内容为一个垃圾数。 (一般我们定义一个指针时会初始化为NULL或者直接指向所要指向的变量地址,但是如果我们没有指向NULL或者变量地址就对指针进行使用,则指针指向的内存地址是随机的)。存在野指针是一个严重的错误。

什么是内存泄漏?怎么有效检查程序的内存泄漏?

什么是内存泄露?怎么检测

New 和malloc的区别是什么?

浅谈malloc和new及他们的区别

系统调用

1)概念:
在计算机中,系统调用(英语:system call),又称为系统呼叫,指运行在使用者空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供了用户程序与操作系统之间的接口(即系统调用是用户程序和内核交互的接口)。

操作系统中的状态分为管态(核心态)和目态(用户态)。大多数系统交互式操作需求在内核态执行。如设备IO操作或者进程间通信。特权指令:一类只能在核心态下运行而不能在用户态下运行的特殊指令。不同的操作系统特权指令会有所差异,但是一般来说主要是和硬件相关的一些指令。用户程序只在用户态下运行,有时需要访问系统核心功能,这时通过系统调用接口使用系统调用。

应用程序有时会需要一些危险的、权限很高的指令,如果把这些权限放心地交给用户程序是很危险的(比如一个进程可能修改另一个进程的内存区,导致其不能运行),但是又不能完全不给这些权限。于是有了系统调用,危险的指令被包装成系统调用,用户程序只能调用而无权自己运行那些危险的指令。另外,计算机硬件的资源是有限的,为了更好的管理这些资源,所有的资源都由操作系统控制,进程只能向操作系统请求这些资源。操作系统是这些资源的唯一入口,这个入口就是系统调用。

2)系统调用举例:

对文件进行写操作,程序向打开的文件写入字符串“hello world”,open和write都是系统调用。如下:

#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
    if (argc<2)
        return 0;
    //用读写追加方式打开一个已经存在的文件
    int fd = open(argv[1], O_RDWR | O_APPEND);
    if (fd == -1)
    {
        printf("error is %s\n", strerror(errno));
    }
    else
    {
        //打印文件描述符号
        printf("success fd = %d\n", fd);
        char buf[100];
        memset(buf, 0, sizeof(buf));
        strcpy(buf, "hello world\n");
        write(fd, buf, strlen(buf));
        close(fd);
    }
    return 0;
}

还有写数据write,创建进程fork,vfork等都是系统调用。

你可能感兴趣的:(C++面试题目,c++)