提示:文章
文章目录
前言
前期疑问:
本文目标:
一、背景
记录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不建议使用
个人理解:
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异常
总结
未完待续