C++ K2

提示:文章

文章目录

前言

前期疑问:

本文目标:


一、背景

记录c++相关题目

二、知识点:

析构函数一定是虚函数吗

不一定

‌析构函数不一定是虚函数。析构函数的主要作用是在对象生命周期结束时进行清理工作,例如释放分配的内存。析构函数通常与类名相同,并且在对象生命周期结束时自动调用。‌

二、题目

以下题目来自喂饭宝典中的题目

1、题目

(单选)以下代码中符合编程规范的是

A. A. int sum = num++ + num++;

B. int sum = (num++)+(num++):

C. int sum = Func(num++,num);

D. num++; int sum = num + num;

正确答案:D

解析:

在程序中调试,定义sum为6。

选项A中num为8,sum为13。后置++是先运算后++,int sum = num++ + num++中,num先是6,然后++后变成7,sum= 6+7=13;num最后变成8;

选项B同选项A。

选项C,Func函数第一个参数为7,第二个参数为6,sum为13。

2、题目

(单选)下面语句是声明的是

A. extern int Errno = 0;

B. int Errno;

C. extern void Reset() { /* ... */ };

D. extern int Errno;

正确答案D。

声明可以出现多次,定义有且只能出现一次。

变量的声明和定义:

int i; // 同时声明和定义变量i,未初始化

int i = 1; // 同时声明和定义变量i,并且初始化

extern int i; // 仅仅声明变量i,表明变量i的定义在其它位置

extern int i = 1; // 同时声明和定义变量i,并且初始化,忽略extern

c++声明与定义区别

摘要:关于函数与变量声明与定义 1.定义也是声明,extern声明不是定义,即不分配存储空间。extern告诉编译器变量在其他地方定义了。 例如:extern int i; //声明,不是定义 int i; //声明,也是定义 2.如果声明有初始化式,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化。 例如:extern double pi=3.1416; //定义 3.函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明。 例如:extern do

关于函数与变量声明与定义

1.定义也是声明,extern声明不是定义,即不分配存储空间。extern告诉编译器变量在其他地方定义了。

例如:extern int i; //声明,不是定义

​ int i; //声明,也是定义

2.如果声明有初始化式,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化。

例如:extern double pi=3.1416; //定义

3.函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明。

例如:extern double max(double d1,double d2); //声明

4.除非有extern关键字,否则都是变量的定义。

例如:extern int i; //声明

​ int i; //定义

关于头文件的变量

注意头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量,C++不允许多次定义变量,一个程序中对指定变量的定义只有一次,声明可以无数次。

不过有三个例外,一下三中实体的定义也可放到头文件中。

1.值在编译时就已知的const 变量的定义可以放到头文件中

如:const int num(10);

2.类的定义可以放到头文件中

3.inline 函数

这三个实体可以定义在多个源文件中,只要在每个源文件中的定义相同。

3、题目

(单选)函数Print的功能是对自定义类型MyClass中的值进行调试打印,不会对MyClass对象进行任何修改,则下列函数声明中符合华为C++语言编程规范的是

A. void Print(std::unique_ptr obj);

B. void Print(const std::unique_ptr& obj);

C. void Print(std::shared_ptr obj);

D. void Print(const MyClass& obj);

正确答案:D

unique_ptr不可复制,shared_ptr不建议使用

从设计的角度来看,通常不推荐将 unique_ptr 作为常量引用传递给函数,因为 unique_ptr 的设计初衷是表示对其所管理对象的唯一所有权。如果一个函数只需要访问 unique_ptr 所指向的对象,而不需要对 unique_ptr 本身进行操作,那么更好的做法是直接传递指向对象的指针或引用

个人理解:

A选项没有体现不能内函数修改。

B选项是不推荐将unique_ptr作用常量传递给函数。

C选项是share_ptr不建议使用。

尽管shared_ptr在很多情况下是推荐的,但在某些特定场景下,使用unique_ptr可能更为合适。unique_ptr不允许复制,但允许移动,适用于拥有权明确且不需要共享的场景。此外,对于局部作用域内的对象,使用unique_ptr可以避免不必要的引用计数开销‌。

遗留问题,为什么shared_ptr不推荐。

4、题目

(单选)符合规范的是(A)

A.

cpp 复制代码
char letter{'a'}
unsigned char num{0}

B.

cpp 复制代码
singed char letter{'a'}
unsigned char num{0}

C.

cpp 复制代码
unsigned char letter{'a'}
unsigned char num{0}

D.

cpp 复制代码
char letter{'a'}
char num{0}

解释:

signed char 和 unsigned char 类型只能用于数值的存储和使用。

普通的 char 类型,在不同系统中可以实现为signed char或unsigned char,因此不要使用char类型来表示整数,它只能用于表示字符数据。

5、题目

(多选)ADD是宏,可能存在问题的宏()

A、ADD(a,b)

B、ADD(Foo(), Bar())

C、ADD(100,200)

D、ADD(a++, b++)

正确答案BD。

禁止把带副作用的表达式作为参数传递给函数式宏

6、题目

(多选)下面代码段声明或定义了一些标识符,请选出所有违反了公司C++通用编程关于标识符命名规则的行号:

cpp 复制代码
typedef struct {
    int boardId; // 告警所在的板ID
    int faultId; // 告警ID
    unsigned char *pPara; // 告警定位参数
    unsigned char state; // 告警的当前状态
} INH_ALM_INFO;

A. 第4行 unsigned char *pPara; // 告警定位参数

B. 第2行 int boardId; // 告警所在的板ID

C. 第5行 unsigned char state; // 告警的当前状态

D. 第6行 } INH_ALM_INFO;

正确答案[A D]

pPara为匈牙利命名法;INH_ALM_INFO为类型名应当用大驼峰。

匈牙利风格 在"大驼峰"的基础上,加上类型或用途前缀 如:'uiSavedCount',

'bTested'

驼峰风格(CamelCase) 大小写字母混用,单词连在一起,不同单词间通过单词

首字母大写来分开。 按连接后的首字母是否大写,又分: 大驼峰

(UpperCamelCase)和小驼峰(lowerCamelCase)

内核风格(unix_like) 又称蛇形风格(snake_case)。单词全小写,用下划线分

割。 如:'test_result'。

7、题目

执行下面程序,会产生什么后果

cpp 复制代码
#define MAX 255

int main(void)
{
    unsigned char A[MAX], i;                                                              
    for (i = 0; i <= MAX; ++i) {
    	A[i] = i;
    }
	return 0;
}

A. 数组越界

B. 死循环

C. 堆溢出

D. 内存泄漏

正确答案AB

8、题目

下列函数可以安全的在重叠内存地址之间复制数据的是:(B)

A、strcpy_s()

B、memmove_s()

C、memcpy_s()

D、sprintf_s()

9、题目

【vector】v是std::vector类型变量,以下代码片段中,符合华为C++语言编程规范中的原则、要求与建议的是

A、

cpp 复制代码
for (int i = 0; i < v.size(); ++i) {

B、

cpp 复制代码
for (auto i = 0; i < v.size(); ++i) {

C、

cpp 复制代码
for (auto i(0); i < v.size(); ++i) {

D、

cpp 复制代码
for (std::size_t i = 0; i < v.size(); ++i) {

根据华为C++语言编程规范,推荐使用 std::size_t 类型来表示容器的大小和索引,因为它是无符号类型,能够正确处理大多数情况下的索引操作。因此,符合华为C++语言编程规范的代码片段是:

D. for (std::size_t i = 0; i < v.size(); ++i)

这种方式不仅符合规范,还能避免潜在的类型转换问题和警告。

10、题目

(单选)关于using的使用,下列哪种做法是错误的(A)

A 在.h中使用using namespace

B 在.cpp文件中使用using namespace

C 在.h文件中使用using定义类型

D 在.cpp文件中使用using定义类型

解释:G.INC.09-CPP 头文件中禁止向全局命名空间中导入符号

对于上述解释的理解一开始是不太清楚的。导入符号的理解应该是导入库,比如using namespace std;std就是符号,不能在头文件中使用std库,应为这样等于是向全局命名空间中导入了std库。所以上述表达的应该就是这个意思。

c++代码规范中还有更具体的解释,如下

G.INC.09-CPP 头文件中禁止向全局命名空间中导入符号

禁止在头文件中的全局命名空间中使用using-directive导入命名空间、使用using-declaration导入单个符号。但是可以在模块

自定义命名空间中以及类、函数等局部作用域中使用它们。

反例

cpp 复制代码
// Foo.h
#include <mylib/string>
using namespace mylib; // 不符合:禁止向全局命名空间导入
using mylib::string; // 不符合:禁止向全局命名空间导入符号

正例

cpp 复制代码
// Foo.h
namespace Foo {
using mylib::string; // 符合:可以在模块自定义命名空间中导入符号
void Foo()
{
    using namespace mylib; // 符合:在函数作用域内使用using-directive
    ...
}
}

11、题目

(单选)关于全局常量,下列哪种是不推荐的做法(D)

A 使用命名空间管理全局常量

B 全局常量作为类静态成员

C 使用匿名namespace管理.cpp文件中才使用的全局常量

D 不让全局常量属于任何命名空间

解释:优先使用命名空间来管理全局常量,如果和某个class有直接关系的,可以使用静态成员常量

12、题目

(多选)using 使用,华为c++编程规范允许的是(CD)

A .h中使用 using namespace

B .h文件的全局空间中使用 using 声明

C .h文件的自定义空间中使用 using 声明

D .cpp文件中头文件后使用 using 声明

G.INC.09-CPP 头文件中禁止向全局命名空间中导入符号

C++14,哪些符合《华为C++语言编程规范》中关于std::unique_ptr的使用的原则、要求和建议? (BC)

A. Func(unique_ptr(new Foo()), Bar());

B. auto ptr = std::make_unique(0, 1);

C. Func(make_unique(), Bar());

D. std::unique_ptr ptr(new MyClass(0, 1));

G.RES.09-CPP 使用std::make_unique 而不是new 创建std::unique_ptr

【级别】 要求

【描述】

本条款适用于C++14及之后的版本。C++14开始增加了std::make_unique ,提供与std::make_shared 类似的方式构造

unique_ptr 。

相对于先 new 出裸指针再构造 unique_ptr ,直接使用 make_unique 的优点有:

make_unique 可以更明确的避免裸指针和智能指针混用。

使用 make_unique 更简洁。

C++ 使用std::make_unique、std::make_shared替换new

类型转换与整数运算

(单选)根据华为C++语言编程规范,当代码中必须将指针转换为整数时,可以使用什么类型存放转换后的指针值(D)

A. int

B. long

C. short

D. uintptr_t

(单选)类型转换,错误的是(B)

A. reinterpret_cast用于转换不相关指针类型,不同指针类型之间应尽量避免转换。

B. static_cast可将void指针转换为任意其他类型指针。

C. dynamic_cast的出现一般说明基类和派生类设计出现了问题,派生类破坏了基类的契约。

D.const_cast用于移除对象的const性质,保留volatile性质。

B说反了,是把任何类型的表达式转换成void类型。

(多选)以下说法正确的有(BD)

A、dynamic_cast 只会在编译期间检测有效性

B、static_cast 只会在编译期间检测有效性

C、dynamic_cast 不会抛出异常

D、static_cast 不会抛出异常

A dynamic_cast 程序运行时期,主要用来父类和子类直接的转换

老资料有选BCD,但dynamic_cast会抛bad_cast异常


总结

未完待续

相关推荐
爱吃涮毛肚的肥肥(暂时吃不了版)16 分钟前
Leetcode——链表:143.重排链表
数据结构·c++·后端·算法·leetcode·链表·职场和发展
Eiceblue1 小时前
在.NET用C#将Word文档转换为HTML格式
开发语言·vscode·c#·html·word·.net
步、步、为营1 小时前
C#局部函数 VS Lambda表达式
开发语言·windows·c#
Kevinyu_1 小时前
Java ArrayList
java·开发语言·windows
忆源1 小时前
Linux高级--3.3.1 C++ spdlog 开源异步日志方案
java·c++·开源
stormjun1 小时前
基于 Python 的深度学习的车俩特征分析系统,附源码
开发语言·python·深度学习·车辆特征分析·python 车辆特征分析
BinaryBardC1 小时前
Dart语言的字符串处理
开发语言·后端·golang
数据的世界012 小时前
C#表达式和运算符
开发语言·c#
一只小菜鸡2 小时前
python+django+Nacos实现配置动态更新-集中管理配置(实现mysql配置动态读取及动态更新)
开发语言·python·django
有梦想的咕噜2 小时前
Qt Quick 和 Qt Designer
开发语言·qt