C++面试题和笔试题(一)

今天面试了一家100人以上的小公司,做QT上位机开发,个人感觉凉凉。以下是笔试题和我能回忆起的面试题

目录

一、笔试题

1. 什么是C++中的指针

官方解释:

 自己的理解:

2.什么是引用,它与指针有什么不同

官方解释:

自己的理解:

3.什么是多态?

4.什么是异常处理?如何在C++中实现?

5.请解释C++的const关键字,它在哪些情况下使用

5. 类成员

6.请解释C++中的static关键字,它在哪些情况下使用

1. 静态局部变量

2. 静态全局变量 

3. 静态类成员

4. 静态函数

7.请解释C++中的sizeof运算符,它返回什么?


一、笔试题

1. 什么是C++中的指针

官方解释:

C++中的指针是一个变量,其值为另一个变量的地址,即内存位置的地址。指针变量简称指针,它专用于存放变量在内存中的起始地址。指针是C/C++中的精髓所在,其特殊性在于它存放的是内存地址。 

在C++中,每定义一个变量,系统就会给变量分配一块内存,且内存是有地址的。指针变量通过存储这些地址,使得我们可以间接地访问和操作这些内存中的数据。因此,指针是实现动态内存分配、函数调用、数据结构等高级功能的重要工具。

声明指针的语法:数据类型 *变量名。例如,int *p; 就声明了一个指向整数的指针p。

 自己的理解:

 你有一个好朋友住在你家附近。你知道他家的地址,所以你可以根据这个地址找到他家,然后和他一起玩。

在这个例子里,地址就像是C++中的指针,而你的朋友家则是那个地址所指向的变量或者数据。

2.什么是引用,它与指针有什么不同

官方解释

 引用是C++中的一个概念,它是变量的一个别名,与原来的变量实质上指向同一块内存地址。当我们给一个变量起一个引用时,我们可以使用这个引用来代替原来的变量名,对引用的操作就是对原变量的操作。例如,如果我们有int a = 5;,然后定义int& ref = a;,那么ref就是a的一个引用,它们实际上都是指向同一个内存地址的。

自己的理解:

引用:你有一个很喜欢的玩具熊,你给这个玩具熊起了一个特别的名字,叫做“熊熊”。这个名字就是玩具熊的一个引用,每次你叫“熊熊”的时候,其实就是在说那个玩具熊。

指针:指针就像是一个小纸条,上面写着你朋友的家的地址。有了这个小纸条,你就可以找到你朋友的家,和他一起玩。

引用指针
定义与性质引用则是变量的别名,它和原变量实际上是同一个变量。指针是一个变量,它存储的是另一个变量的地址
存储空间引用则不占用额外的存储空间,它只是原变量的一个别名。指针有自己的存储空间,它的大小通常是固定的
初始化引用必须在定义时初始化,且一旦初始化后就不能再绑定到另一个变量上指针可以不初始化
可变性而引用的值(即它所代表的变量)在初始化后则不能改变。指针的值(即它所指向的地址)可以在初始化后改变,使其指向另一个对象
空值不能为空
多级引用与指针引用只能是一级可以有多级指针(例如int** p;
安全性好(因为引用在初始化后不能改变所指向的对象,这减少了出错的可能性。)
内存管理内存泄漏返回动态内存分配的对象或内存,必须使用指针

3.什么是多态?

简单来说,就是“一个接口,多种方法”。多态的实现方式主要依赖于继承和虚函数。

举几个代码例子

1).运行时多态(通过虚函数)

#include <iostream>  
#include <string>  // 基类 Animal  
class Animal {  
public:  virtual void speak() const {  std::cout << "The animal speaks." << std::endl;  }  virtual ~Animal() {} // 虚析构函数确保正确释放派生类资源  
};  // 派生类 Dog  
class Dog : public Animal {  
public:  void speak() const override {  std::cout << "The dog barks." << std::endl;  }  
};  // 派生类 Cat  
class Cat : public Animal {  
public:  void speak() const override {  std::cout << "The cat meows." << std::endl;  }  
};  // 使用多态的函数  
void letAnimalSpeak(const Animal& animal) {  animal.speak(); // 在运行时确定调用哪个 speak()  
}  int main() {  Dog dog;  Cat cat;  Animal* animalPtr;  animalPtr = &dog;  letAnimalSpeak(*animalPtr); // 输出: The dog barks.  animalPtr = &cat;  letAnimalSpeak(*animalPtr); // 输出: The cat meows.  return 0;  
}

在上面的例子中,Animal 类有一个虚函数 speak()Dog 和 Cat 类分别重写了这个函数。在 letAnimalSpeak 函数中,我们传入了一个 Animal 类型的引用,但实际上可以传入任何 Animal 的派生类对象。在运行时,程序会根据实际对象的类型调用相应的 speak() 函数。 

2).编译时多态(通过函数重载)

#include <iostream>  // 函数重载示例  
void print(int value) {  std::cout << "Integer: " << value << std::endl;  
}  void print(double value) {  std::cout << "Double: " << value << std::endl;  
}  void print(const std::string& text) {  std::cout << "String: " << text << std::endl;  
}  int main() {  print(42); // 输出: Integer: 42  print(3.14); // 输出: Double: 3.14  print("Hello, World!"); // 输出: String: Hello, World!  return 0;  
}

在这个例子中,我们重载了 print 函数,使其可以接受 intdouble 和 std::string 类型的参数。编译器根据传递给 print 函数的参数类型在编译时决定调用哪个版本的函数。这就是编译时多态的一个例子。

4.什么是异常处理?如何在C++中实现?

异常处理:是我们在生活中遇到问题时,找到合适的方法来解决它。在C++编程中,异常处理可以帮助我们找到并修复代码中的错误。

在C++中,这个过程可以这样实现:

1). throw:相当于你发现锅里的油着火了,你决定要采取行动,于是你“抛出”了一个问题,即火需要被扑灭

if (oil_is_on_fire) {  throw "Fire!"; // 抛出异常,表示发生了火灾  
}

2).try:你在厨房里做饭的时候(try块里的代码),一直在注意火的情况

try {  // 在这里做饭,可能会遇到油着火的情况  
}

 3).catch:当你发现火情(捕获到异常)时,你立即采取行动(执行catch块里的代码)来灭火。

catch (const char* message) {  // 灭火操作,比如用锅盖盖住锅  std::cout << "Caught an exception: " << message << ". Using the lid to put out the fire." << std::endl;  
}
catch (...) {  // 对于未知或无法处理的异常,我们可以做进一步的处理,比如发出警报  std::cout << "Unknown exception caught! Calling the firefighters!" << std::endl;  
}

5.请解释C++的const关键字,它在哪些情况下使用

在C++中,const关键字用于声明一个常量,即一个值在程序执行期间不能被修改的对象。

  • 保护数据不被意外修改:当你有一个不应该在程序执行期间改变的值时,使用const可以确保这个值不会被意外修改。
  • 提高代码可读性const变量提供了关于其用途的额外信息,使得代码更易读。
  • 优化:编译器可能会对const变量进行额外的优化,因为它们不会在运行时改变。
  • 作为函数参数和返回值的保证const可以用于函数参数和返回值,以表明参数或返回值在函数内部不会被修改。

下面是一些使用const的常见情况:

1. 声明常量值 

const int MAX_SIZE = 100;

2. 指针和const 

指向常量的指针:该指针不能用来修改它所指向的值。

const int* ptr = &some_integer; // ptr指向一个常量,不能通过ptr修改some_integer的值

常量指针:该指针自身不能被修改(即不能指向其他地址),但它所指向的值可以被修改(如果它不是指向一个常量的话)。

int value = 10;  
int* const ptr = &value; // ptr是一个常量指针,不能改变ptr指向的地址,但可以修改value的值

指向常量的常量指针:该指针自身不能被修改,同时它也不能用来修改它所指向的值。

const int value = 10;  
const int* const ptr = &value; // ptr是常量,value也是常量,两者都不能通过ptr被修改

3. 函数参数 

void func(const int& param) {  // 在func内部,param不能被修改  
}

4. 函数返回值 

const int* getPointer() {  static int value = 42;  return &value;  
}  
// 调用者不能通过返回的指针修改value的值

5. 类成员

class MyClass {  
public:  const int constantMember;  MyClass(int value) : constantMember(value) {}  
};  
// MyClass的实例一旦初始化后,constantMember的值就不能再被修改

 6. 类成员函数

class MyClass {  
public:  int getValue() const {  // 这个函数不会修改类的任何成员变量  return someMember;  }  
private:  int someMember;  
};  
// const成员函数保证不会修改类的状态

 7. 在数组中使用

const int arraySize = 5;  
int const arr[arraySize]; // 或者 int arr[arraySize] const;  
// arr的内容在初始化后不能被修改

6.请解释C++中的static关键字,它在哪些情况下使用

 在C++中,static是一个多功能的关键字,它可以用于多种上下文,包括变量、函数、类成员等。

以下是static关键字的主要用途和它们的使用场景:

1. 静态局部变量

当在函数内部声明一个静态局部变量时,这个变量只在程序执行到该变量的声明代码时初始化一次,并且在程序的整个生命周期内保持其值。即使函数返回后,静态局部变量的值也不会丢失。

自己的理解:想象你在家里有一个存钱罐,每次你得到零花钱,你都会放进这个存钱罐里。这个存钱罐就像是一个静态局部变量,因为它只在家里(函数内部)存在,并且每次你往存钱罐里放钱(函数调用),里面的钱(变量的值)都会累积起来,不会消失。即使你离开房间去做其他事情(函数返回),存钱罐里的钱还是会在那里

使用场景:当你想在函数调用之间保持某些状态或数据时,可以使用静态局部变量。

void addMoneyToPiggyBank() {  static int moneyInPiggyBank = 0; // 静态局部变量,初始化为0  int moneyToAdd = 5; // 假设每次添加5块钱  moneyInPiggyBank += moneyToAdd; // 往存钱罐里加钱  std::cout << "存钱罐里现在有 " << moneyInPiggyBank << " 块钱。\n";  
}

2. 静态全局变量 

静态全局变量只在其定义的文件中可见,而在其他文件中不可见。这提供了封装性,允许程序员隐藏不应在其他文件中使用的变量。

自己的理解:静态全局变量就像是你家里的一个秘密宝藏,只有你和你的家人知道它的存在。其他来你家做客的小朋友是看不到这个宝藏的。在C++中,如果一个全局变量被声明为static,那么它就只能在其所在的源文件中被访问,其他文件是看不到的。

使用场景:当你想限制全局变量的作用域到单个源文件时。

// 在你的房间的文件(file1.h)里  
static int secretTreasure = 10; // 静态全局变量,只有这个文件能看到  //另外一个文件(file1.cpp) 
void showTreasure() {  std::cout << "秘密宝藏里有 " << secretTreasure << " 颗糖果!\n";  
}

其他小朋友的文件(file2.cpp)里是不能访问secretTreasure的。

3. 静态类成员

静态类成员是类的所有对象共享的成员。它们不属于类的任何特定对象实例。静态成员变量必须在类外部定义和初始化。

自己的理解:静态类成员就像是全班同学共享的一个东西,比如班级的图书角。每个同学都可以从图书角借书,也可以放回书。图书角里的书不属于任何一个同学,而是属于整个班级。

使用场景:当你想存储与类本身相关而不是与类的任何特定对象实例相关的信息时。

class Classroom {  
public:  static int booksInLibrary; // 静态类成员,表示图书角里的书的数量  // ... 其他成员 ...  
};  // 在类外部定义和初始化静态成员变量  
int Classroom::booksInLibrary = 50; // 图书角初始有50本书

每个同学都可以改变booksInLibrary的值,来表示借书或还书的行为。

4. 静态函数

在函数外部(通常在命名空间或全局范围内),static用于声明函数的作用域为文件内部。这与静态全局变量的效果相似,它使得函数只在其定义的文件中可见。

自己的理解:你有一个秘密的食谱,只有你和你的家人知道怎么做。这个食谱就像static函数一样,只有在其定义的文件中才能使用。

使用场景

  • 当你需要保持某个变量的值在函数调用之间时,可以使用静态局部变量。
  • 当你需要在多个文件中共享某个变量,但又不想让它被其他所有文件访问时,可以使用静态全局变量。
  • 当你需要在不创建类实例的情况下访问某个变量或函数时,可以使用静态类成员。
  • 当你想要限制函数或变量的可见性,使它们仅在其定义的文件中可见时,可以使用静态函数或静态全局变量。
// file1.cpp  
static void myFunction() { // 静态函数  // ...  
}  // file2.cpp  
extern void myFunction(); // 错误!file2中不能访问file1中的静态函数

7.请解释C++中的sizeof运算符,它返回什么?

在 C++ 中,sizeof 是一个运算符,用于获取一个对象或类型的字节大小。它可以用于获取各种数据类型的大小,包括内置类型、类、结构体等。

自己的理解sizeof是一个运算符,用于获取一个对象或类型的字节大小。就像你在生活中会问“这个苹果有多大?”来了解苹果的大小一样,sizeof可以帮你了解一个对象或类型在计算机内存中占用了多少空间。

使用场景:

1.用于数据类型:你可以直接使用sizeof运算符获取基本数据类型(如intchardouble等)或复合数据类型(如数组、结构体、类等)的大小。例如:

std::cout << sizeof(int) << std::endl;  // 输出int类型在内存中的大小(以字节为单位)

2.用于变量:你也可以对变量使用sizeof运算符,这将返回该变量类型的大小,而不是变量本身所占用的内存空间大小。例如:

int x;  
std::cout << sizeof(x) << std::endl;  // 输出int类型在内存中的大小(以字节为单位)

3.用于数组:当用于数组时,sizeof返回的是整个数组所占用的内存空间大小,而不是数组中单个元素的大小。例如:

int arr[10];  
std::cout << sizeof(arr) << std::endl;  // 输出10个int类型在内存中的总大小(以字节为单位)

4.用于指针:当用于指针时,sizeof返回的是指针本身的大小,而不是指针所指向的内存空间大小。例如:

int *ptr;  
std::cout << sizeof(ptr) << std::endl;  // 输出指针类型在内存中的大小(以字节为单位)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud-Alibaba-Nacos教程

SpringCloud-Alibaba-Nacos教程 下载地址 https://github.com/alibaba/nacos/releases/tag/2.2.3 直接进入bin包 运行cmd命令 startup.cmd -m standalone 运行成功后 进入nacos可视化页面 账号密码默认都是nacos http://localhost:8848/nacos 微服务入驻Nacos服务注册…

阿尔巴尼亚借助ChatGPT加快欧盟入会进程

原文&#xff1a;https://www.euractiv.com/section/politics/news/albania-to-speed-up-eu-accession-using-chatgpt/ 来源&#xff1a;https://weibo.com/1727858283/O3ZoWp6oO?refer_flag1001030103_ 阿尔巴尼亚政府计划利用ChatGPT技术&#xff0c;将成千上万页的欧盟法律…

【Python】成功解决IndexError: list index out of range

【Python】成功解决IndexError: list index out of range &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

首次实现Go调用C的dll文件

首先&#xff0c;要使用Go调用C的DLL文件&#xff0c;你需要遵循以下步骤&#xff1a; 编写C代码&#xff1a; 首先&#xff0c;编写你的C代码&#xff0c;并将其编译成DLL文件。假设你有一个名为example.c的C源文件&#xff0c;其中包含你要调用的函数。 // example.c #includ…

探索stable diffusion的奇妙世界--01

目录 1. 理解prompt提示词&#xff1a; 2. Prompt中的技术参数&#xff1a; 3. Prompt中的Negative提示词&#xff1a; 4. Prompt中的特殊元素&#xff1a; 5. Prompt在stable diffusion中的应用&#xff1a; 6. 作品展示&#xff1a; 在AI艺术领域&#xff0c;stable di…

Mysql 表逻辑分区原理和应用

MySQL的表逻辑分区是一种数据库设计技术&#xff0c;它允许将一个表的数据分布在多个物理分区中&#xff0c;但在逻辑上仍然表现为一个单一的表。这种方式可以提高查询性能、简化数据管理&#xff0c;并有助于高效地进行大数据量的存储和访问。逻辑分区基于特定的规则&#xff…

机器学习——PPO补充

On-policy vs Off-policy 今天跟环境互动&#xff0c;并学习是on-policy 只是在旁边看&#xff0c;就是Off-policy 从p中选q个重要的&#xff0c;需要加一个weight p(x)/q(x) p和q不能相差太多 采样数太少导致分布差很多&#xff0c;导致weight发生变化 On-Policy -&g…

我的NeRF学习——初步认识

NeRF NeRF&#xff0c;全名为 Neural Radiance Fields&#xff0c;是一种基于深度学习的三维场景隐式表示和渲染方法 1 NeRF的基本概念 1.1 辐射场表示场景 NeRF的核心思想是通过神经网络训练出来的辐射场对场景进行隐式表示。这种表示方式与传统的使用体素、网格或点云的显…

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分&#xff0c;通过数据库管理系统&#xff08;DBMS&#xff09;存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例&a…

全栈的自我修养 ———— vue中子组件使用父组件的方法

子组件取得父组件的方法 一、通过props&#xff08;比较推荐&#xff09;二、通过$emit (小编很推荐)3、provide/inject (不建议)4、 $parent (不建议) 一、通过props&#xff08;比较推荐&#xff09; 在父组件页面给子组件绑定方法,左边是子组件接收的方法名&#xff0c;内容…

【软件开发环境】搭建足够优雅的开发环境进行时

关于 该文档用于记录开发历程中使用的软件开发环境。该文档应当保证每年更新一次&#xff0c;希望它能够成为一个长大了的开发环境&#xff0c;会自己帮我开发需求&#xff0c;嗯&#xff1a;) 【文档结果】 作为软件开发者&#xff0c;知道自己当前使用了哪些环境与工具作为…

openmesh 学习笔记

目录 讲解资料&#xff1a; 安装&#xff1a; 入门例子&#xff1a; 读取off文件示例&#xff1a; 操作bunny.ply&#xff1a; 格式转换vertex vertex_to_mesh mesh_to_vertex 它具有以下特征&#xff1a;既可以表示任意多边形网格&#xff0c;也可以表示纯三角形网格&…

6 种 卷积神经网络压缩方法

文章目录 前言 1、低秩近似 2、剪枝与稀疏约束 3、参数量化 4、二值化网络 &#xff08;1&#xff09;二值网络的梯度下降 &#xff08;2&#xff09;两个问题 &#xff08;3&#xff09;二值连接算法改进 &#xff08;4&#xff09;二值网络设计注意事项 5、知识蒸馏 6、浅层 …

SpringBoot基础入门

SpringBoot2讲义链接 源码链接 springboot中文网 由于讲义中有代码的详细实现步骤&#xff0c;故此笔记只记录理论部分&#xff0c;项目具体构建细节需搭配 讲义 食用 csdn比较好的博客 第一章 JavaConfig 项目见讲义第1章&#xff0c;项目名为 001-springboot-pre Xml 配置容…

13 pymysql模块

pymysql模块 pymysql是一个第三方库&#xff0c;如果自己的计算机上没有可以在终端使用命令进行安装。 sudo pip3 install pymysqlpymysql使用流程 建立数据库连接&#xff1a;db pymysql.connect(…)创建游标对象&#xff1a;cur db.cursor()游标方法: cur.execute(“ins…

亲测:腾讯云8核16G服务器价格1668元一年送3个月,购买需谨慎

腾讯云8核16G轻量服务器CPU性能如何&#xff1f;18M带宽支持多少人在线&#xff1f;轻量应用服务器具有100%CPU性能&#xff0c;18M带宽下载速度2304KB/秒&#xff0c;折合2.25M/s&#xff0c;系统盘为270GB SSD盘&#xff0c;月流量3500GB&#xff0c;折合每天116.6GB流量&…

【c++11线程库的使用】

#include<iostream> #include<thread> #include<string> using namespace std; void hello(string msg) { for (int i 0; i < 1000; i) { cout << i; cout << endl; } } int main() { //1.创建线程 thread …

STM32---通用定时器(一)理论基础

写在前面&#xff1a;在STM32F103中有众多的定时器&#xff0c;其中包括两个基本定时器&#xff0c;基本定时器的内容已经在上节进行了介绍&#xff0c;基本定时器的功能、结构、使用都较为简单。而STM32F1中还含有4个通用定时器&#xff08;TIM2\3\4\5&#xff09;,这些定时器…

GEE案例——如何对矢量集合(面状)提取中心点并返回给矢量(添加经纬度属性信息)

简介 很多时候我们会遇到一个需求,就是将我们已经获取的矢量集合进行一个中心点经纬度的获取,这个过程,最简单的方式就是通过我们一个个通过交互式的地图去点击,查看获取,但是这样的工作量有点大,而很多时候我们分解出的矢量是超级多的,比如说上百个成千个,这对于我们…

探讨系统测试的最佳实践与思维模式!

这是测试活动过程详解系列的最后一篇文章。之前的想法&#xff0c;是对测试过程各重要环节进行拆解&#xff0c;然后介绍这个环节重点要做的事情&#xff0c;为什么要做这些事&#xff0c;以及注意事项。 前面几篇文章分别介绍了单元测试、集成测试、回归测试阶段要解决的问题…