突破编程_C++_面试(变量与常量)

面试题 1 : C++ 中的变量存储类别有哪些,并简要描述它们的特点?

在C++中,变量的存储类别决定了变量的生命周期和可见性。以下是C++中的几种变量存储类别及其特点:

自动存储期

  • 也称为局部存储类别。
  • 这类变量在函数或代码块内部声明,并且在函数或代码块执行时创建,在函数或代码块退出时销毁。
  • 它们的生命周期是局部的,只存在于声明它们的函数或代码块执行期间。
  • 每次进入函数或代码块时,都会为这些变量分配新的存储空间,退出时释放这些空间。

静态存储期

  • 这类变量在程序开始执行时就创建,并在程序结束时销毁。
  • 它们可以在全局作用域、命名空间作用域或函数作用域中声明。
  • 在全局或命名空间作用域中声明的静态变量在整个程序执行期间都存在。
  • 在函数作用域中声明的静态变量(也称为静态局部变量)只在该函数被调用的期间存在,但其生命周期跨越了函数调用,即它们的值在函数调用之间是保持的。

线程存储期

  • 这类变量在线程开始执行时创建,并在线程结束时销毁。
  • 它们通常用于多线程编程,以确保每个线程都有自己的变量副本。
  • 在 C++11 及以后的版本中,可以使用 thread_local 关键字来声明线程局部存储期的变量。

动态存储期

  • 这类变量由 new 运算符创建,并由 delete 运算符销毁。
  • 它们的生命周期由程序员控制,直到显式删除它们,否则它们会一直存在。
  • 动态分配的变量在堆上分配空间,不受函数或代码块生命周期的限制。

每种存储类别都有其特定的用途和优势。例如,自动存储期的变量适用于需要临时存储数据的场景,而静态存储期的变量则适用于需要在程序执行期间持续存在的数据。线程存储期的变量则适用于多线程环境中,每个线程需要独立的数据副本时。动态存储期的变量则提供了更大的灵活性和控制力,但也需要程序员手动管理内存。

面试题 2 : const 和 constexpr 的区别是什么?它们各自在哪些场景下更有用?

在 C++ 中, const 和 constexpr 都是用于定义常量的关键字,但它们在用途和语义上存在一些区别。
const 关键字:
(1)可以用于声明一个变量为常量,这意味着一旦变量被初始化,其值就不能被修改。
(2)可以在运行时被赋值,并且可以在程序的不同部分共享相同的内存地址。
(3)可以在任何函数内部或全局作用域中定义。
(4)主要用于确保变量在程序执行期间保持不变,提高代码的可读性和可维护性。
constexpr 关键字:
(1)用于声明一个常量表达式,该表达式必须在编译时就能计算出其值。
(2)必须在编译时初始化,并且其值必须是常量表达式。
(3)该关键字在编译时被存储在程序的只读数据段中,因此它们的地址可以在程序的多个实例之间共享。
(4)主要用于编译时常量、数组大小、模板参数等需要在编译时知道值的情况。
const 和 constexpr 各自的使用场景:
const 的使用场景:
(1)当需要定义一个在程序执行期间保持不变的值时,可以使用 const 。
(2)当需要在函数内部定义一个只在该函数内部有效的常量时,可以使用 const 。
(3)当需要防止变量被意外修改时,可以使用 const 。
constexpr 的使用场景:
(1)当需要定义一个编译时常量时,可以使用 constexpr 。
(2)当需要定义一个作为数组大小的常量时,可以使用 constexpr 。
(3)当需要定义一个作为模板参数的常量时,可以使用 constexpr 。
(4)当需要优化性能,避免在运行时计算常量表达式的值时,可以使用 constexpr 。
总结来说, const 用于在运行时定义不可变的变量,而 constexpr 用于在编译时定义常量表达式。选择使用哪个关键字取决于你的具体需求,以及是否需要在编译时还是运行时确定常量的值。

面试题 3 :什么是内部链接和外部链接?如何在 C++ 中使用 static 和 extern 关键字来控制链接?

在C++中,链接( Linking )是编译器将不同的编译单元(通常是源文件)组合成一个可执行程序或库文件的过程。在这个过程中,编译器需要解决函数或变量的引用和定义之间的关联。
内部链接和外部链接是 C++ 中符号链接性的两种类型,它们决定了符号的作用域和可见性。
内部链接
当一个函数或变量被声明为 static 时,它具有内部链接。这意味着该符号只在定义它的编译单元内可见,其他编译单元无法访问它。在 C++ 中,静态成员变量和静态成员函数具有内部链接。
外部链接
默认情况下,函数或变量具有外部链接。这意味着函数或变量可以在多个编译单元之间共享,只要它在链接时是可访问的。使用 extern 关键字可以声明一个函数或变量,而不在当前编译单元中定义它,从而在其他编译单元中定义该符号。
使用 static 和 extern 关键字来控制链接:
使用 static 关键字:
在函数或变量声明前加上 static 关键字,可以使其具有内部链接。这样,该函数或变量只在其定义的编译单元内可见。
例如,在头文件中声明一个静态变量:

// header.h
static int s_val = 0;

这样, s_val 只会在包含该头文件的源文件中可见,而不会在其他源文件中共享。
使用 extern 关键字:
extern 关键字用于声明一个在其他编译单元中定义的符号。它告诉编译器该符号在链接时将被解析,而不是在当前编译单元中定义。
例如,在一个源文件中定义一个函数,并在另一个源文件中声明并使用该函数:

// file1.cpp
#include "header.h"void func() 
{// ... 函数实现 ...
}// file2.cpp
#include "header.h"extern void func(); // 声明在其他编译单元中定义的函数int main() {func(); // 调用在其他编译单元中定义的函数return 0;
}

在这个例子中, func 在 file1.cpp 中定义,并在 file2.cpp 中通过 extern 关键字声明。这样, main 函数可以调用 func ,即使它没有在 file2.cpp 中定义。
注意:在 C++ 中,通常建议将变量声明为 extern ,并在一个源文件中定义它,以避免多重定义错误。对于函数,可以在头文件中声明原型,并在一个源文件中定义实现。这样,其他源文件可以通过包含该头文件来使用该函数。

面试题 4 :什么是 mutable 关键字,它有什么用处?

在 C++ 中, mutable 关键字用于在类的 const 成员函数中修改类的某个成员变量。通常, const 成员函数是不能修改它所属对象的任何成员变量的,但是,如果需要某些成员变量能够在 const 成员函数中被修改,就可以将这些成员变量声明为 mutable 。
mutable 关键字允许在 const 成员函数中修改这些成员变量,而不会影响对象的常量性。这对于某些需要在逻辑上保持常量性,但实际上需要修改内部状态的场景非常有用。
如下为样例代码:

#include <iostream>class Counter
{
public:Counter() : m_count(0), m_mutableVal(0) {}// 增加计数void increment(){m_count++;}// 在const成员函数中修改 m_mutableValvoid setMutableVal(int val) const{m_mutableVal = val;}// 获取MutableVal的值int getMutableVal() const{return m_mutableVal;}// 获取计数int getCount() const{return m_count;}private:int m_count; // 普通成员变量mutable int m_mutableVal; // mutable成员变量
};int main()
{const Counter counter; // 创建一个const对象// 调用const成员函数设置 m_mutableVal 的值counter.setMutableVal(1);printf("counter.getMutableVal() : %d\n",counter.getMutableVal());// 尝试调用非const成员函数会编译失败,因为 counter 是 const 对象// counter.increment(); // 错误:不能在const对象上调用非const成员函数return 0;
}

上面代码的输出为

counter.getMutableVal() : 1

在上面代码中, Counter 类有一个普通的成员变量 m_count 和一个被声明为 mutable 的成员变量 m_mutableVal 。在 const 成员函数 setMutableVal 中,可以修改 m_mutableVal 的值,而不会影响 m_count 的值或对象的常量性。当尝试在 const 对象 counter 上调用非 const 成员函数 increment 时,编译器会报错,因为这样做会违反 const 对象的常量性保证。

面试题 5 : volatile 关键字的作用是什么?

在 C++ 中, volatile 关键字用于告诉编译器对象的值可能会在编译器无法检测到的情况下被改变。通常有如下几种应用场景:
硬件访问
当程序直接与硬件通信时,硬件的状态可能会在任何时候改变,而这些改变不是通过 C++ 代码直接进行的。例如,一个嵌入式系统中的某个寄存器可能在外部中断或 DMA 传输完成后被更新。
多线程编程
在多线程环境中,一个线程可能会修改一个变量,而另一个线程正在读取或写入同一个变量。即使使用了互斥锁或其他同步机制, volatile 也可能被用来确保编译器不会对这个变量的访问进行优化,从而导致不正确的行为。然而,需要注意的是, volatile 本身并不提供线程间的同步或互斥;它仅仅防止编译器优化。
信号处理
在信号处理程序中,如果一个变量可能在信号处理程序之外被异步地修改,那么这个变量应该被声明为 volatile 。
编译器优化
编译器通常会对代码进行优化,假设变量的值在没有被显式修改的情况下是不会改变的。但是,如果变量可能被外部因素(如上面提到的情况)修改,那么这种优化可能是错误的。 volatile 关键字告诉编译器不要做出这样的假设。
注意: volatile 并不保证原子性。即使在 volatile 修饰的变量上执行的操作也可能不是原子的,特别是当操作涉及多个步骤(如递增一个值)时。在多线程环境中确保数据的一致性和同步通常需要使用更高级的同步原语,如互斥锁或原子操作。
此外,过度使用 volatile 可能会导致性能下降,因为编译器无法对涉及 volatile 变量的代码进行有效优化。因此,应该只在确实需要的情况下使用它。

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

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

相关文章

正大国际期货:日内交易

日内交易是一种交易模式&#xff0c;英文名字是daytrade,主要是指持仓时间短&#xff0c;不留过夜持仓的交易方式。日内交易捕捉入市后能够马上脱离入市成本的交易机会&#xff0c;入市之后如果不能马上获利&#xff0c;就准备迅速离场

程序员可以做一辈子吗?大龄程序员出路在哪?

前言 随着2023年AI的出现&#xff0c;大家对待程序员工作有了一丝丝危机感&#xff0c;特别是今年整个IT行业进入了前所未有的寒冬期&#xff0c;让程序员不得不思考未来的职业发展。 甚至很多程序员一想到自己接近35岁&#xff0c;焦虑感油然而生&#xff0c;这也是大部分程…

基于YOLOv7算法的高精度实时雾天车辆行人目标检测系统(PyTorch+Pyside6+YOLOv7)

摘要&#xff1a;基于YOLOv7算法的高精度实时雾天车辆行人目标检测系统可用于日常生活中检测与定位bicycle、bus、car、motorbike和person&#xff0c;此系统可完成对输入图片、视频、文件夹以及摄像头方式的目标检测与识别&#xff0c;同时本系统还支持检测结果可视化与导出。…

数据采集新纪元:Linux边缘计算技术在智慧工厂的应用解析

在当今全球智能制造的大潮下&#xff0c;Linux边缘计算网关正扮演着愈发重要的角色。它位于数据产生源头与云计算中心之间&#xff0c;为智慧工厂提供了关键的实时决策能力和高效的预测性维护解决方案。 以一家领先汽车零部件生产商为例&#xff0c;其高度自动化的生产线上的每…

C/C++数据结构——剖析排序算法

1. 排序的概念及其运用 1.1 排序的概念 https://en.wikipedia.org/wiki/Insertion_sorthttps://en.wikipedia.org/wiki/Insertion_sort 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的…

力扣hot2--哈希

推荐博客&#xff1a; for(auto i : v)遍历容器元素_for auto 遍历-CSDN博客 字母异位词都有一个特点&#xff1a;也就是对这个词排序之后结果会相同。所以将排序之后的string作为key&#xff0c;将排序之后能变成key的单词组vector<string>作为value。 class Solution …

探索未来科技前沿:深度学习的进展与应用

深度学习的进展 摘要&#xff1a;深度学习作为人工智能领域的重要分支&#xff0c;近年来取得了巨大的进展&#xff0c;并在各个领域展现出惊人的应用潜力。本文将介绍深度学习的发展历程、技术原理以及在图像识别、自然语言处理等领域的应用&#xff0c;展望深度学习在未来的…

SQL29 计算用户的平均次日留存率(lead函数的用法)

代码 with t1 as(select distinct device_id,date --去重防止单日多次答题的情况from question_practice_detail ) select avg(if(datediff(date2,date1)1,1,0)) as avg_ret from (selectdistinct device_id,date as date1,lead(date) over(partition by device_id order by d…

Effective Objective-C 学习(三)

理解引用计数 Objective-C 使用引用计数来管理内存&#xff1a;每个对象都有个可以递增或递减的计数器。如果想使某个对象继续存活&#xff0c;那就递增其引用计数&#xff1a;用完了之后&#xff0c;就递减其计数。计数变为 0时&#xff0c;就可以把它销毁。 在ARC中&#xf…

C++入门学习(二十八)跳转语句—continue语句

当在循环中遇到continue语句时&#xff0c;它会跳过当前迭代剩余的代码块&#xff0c;并立即开始下一次迭代。这意味着continue语句用于跳过循环中特定的执行步骤&#xff0c;而不是完全终止循环。 直接看一下下面的代码更清晰&#xff1a; 与上一节的break语句可以做一下对比…

什么是软件测试?软件测试的目的与原则是什么?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

原创详解OpenAI Sora是什么?技术先进在哪里?能够带来什么影响?附中英文技术文档

一&#xff1a;Sora是什么 Sora是一个文本到视频的模型&#xff0c;由美国的人工智能研究机构OpenAI开发。Sora可以根据描述性的文本提示&#xff0c;生成高质量的视频&#xff0c;也可以根据已有的视频&#xff0c;向前或向后延伸&#xff0c;生成更长的视频。 Sora的主要功…

UPC训练赛二十/20240217

A:无穷力量 题目描述 2022年重庆突发山火让世界看到了中国一个又一个的感人事迹&#xff1a;战士们第一时间奔赴火场&#xff0c;志愿者们自发组成团队&#xff0c;为救火提供一切的可能的服务&#xff0c;人们自发输送物资&#xff0c;有的志愿者甚至几天几夜没有睡觉。每个…

反射的作用

获取一个类里面所有的信息&#xff0c;获取到了之后&#xff0c;再执行其他的业务逻辑结合配置文件&#xff0c;动态的创建对象并调用方法 练习1&#xff1a; public class MyTest {public static void main(String[] args) throws IllegalAccessException, IOException {Stude…

Swift 5.9 新 @Observable 对象在 SwiftUI 使用中的陷阱与解决

概览 在 Swift 5.9 中&#xff0c;苹果为我们带来了全新的可观察框架 Observation&#xff0c;它是观察者开发模式在 Swift 中的一个全新实现。 除了自身本领过硬以外&#xff0c;Observation 框架和 SwiftUI 搭配起来也能相得益彰&#xff0c;事倍功半。不过 Observable 对象…

C++学习Day06之继承方式

目录 一、程序及输出1.1 公共继承1.1.1 父类中公共成员&#xff0c;子类可以正常访问1.1.2 父类中保护成员&#xff0c;子类类外不可以访问1.1.3 父类中私有成员&#xff0c;子类无法访问 1.2 保护继承1.2.1 父类中公共权限 子类中变为 保护权限1.2.2 父类中保护权限 子类中变为…

自定义Linux登录自动提示语

设置提示语的方式 在Linux系统中&#xff0c;可以通过修改几个特定的文件来实现在用户登录时自动弹出提示语。以下是几个常用的方法&#xff1a; 1. 修改/etc/issue文件&#xff1a; 这个文件用于显示本地登录前的提示信息 sudo vi /etc/issue在项目合作的时候&#xff0c;…

平衡二叉树(AVL树)

定义&#xff1a; 左右子树高度之差不超过1左右子树都是平衡二叉树 平衡二叉树的增删操作都离不开二叉树的调整 二叉树调整 LL型&#xff1a;右旋 LR型&#xff1a;左旋右旋 RR型&#xff1a;左旋 RL型&#xff1a;右旋左旋

从小红书笔记详情API看电商如何提升品牌影响力

从小红书笔记详情API来看&#xff0c;电商如何提升品牌影响力是一个复杂但至关重要的过程。首先&#xff0c;理解小红书平台和其用户群体的特点是关键。小红书是一个以用户分享和消费体验为主的社交媒体平台&#xff0c;用户群体主要是年轻、有购买力的女性。因此&#xff0c;电…

Python 遍历结构复杂的多层嵌套字典,收集特定键值对

可以使用递归函数来遍历整个嵌套层次不同的字典&#xff0c;收集所有感兴趣的键值对&#xff0c;最终得到一个非嵌套结构的字典&#xff1a; &#xff08;一般用于处理爬取的json数据&#xff0c;因为有些结构真的蛮怪的(&#xff92;3[____] def extract_key_value_pairs(ne…