【C++】专项练习(牛客)
- 1、变量在内存中的存储位置
- 2、内联函数
- 3、数组指针
- 4、C++模板 template
- 5、重载运算符参数(!!!×--------------×)
- 6、抽象类
- 7、continue和break
- 8、二维数组(×--------------×)
- 9、指针偏移(!!!×--------------×)
- 10、for'双重循环(!!!×--------------×)
- 11、类与对象
- 12、错误类型
- 13、变量初始化
- 14、三目运算符(×--------------×)
- 15、常成员函数
- 16、 (!!!×--------------×)---------
- 17、大端和小端、union
- 18、枚举 enum
- 19、C++使用类模板的原因
1、变量在内存中的存储位置
(1)栈
函数返回地址、相关参数、局部变量和寄存器内容等。
(2)堆
由new分配的内存块。程序员分配和释放,动态分配。
new,malloc,calloc,realloc等分配内存函数得到的变量
(3)自由存储区
由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
(4)全局/静态存储区
全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。
(5)常量存储区
这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改.
2、内联函数
1)类内定义的函数都是内联函数,不管是否有inline修饰符
2)函数声明在类内,但定义在类外的看是否有inline修饰符,如果有就是内联函数,否则不是
(1)好处
省去了调用的过程,加快程序运行速度。
(2)适用场景
适用于功能简单、代码很短(1~5条)、但使用频率很高(不要存在while
、switch
)
(3)先定义再使用
当你定义一个内联函数时,在函数定义前加上 inline
关键字,并且将定义放入头文件,先定义再使用。
(4)内联函数和宏定义的区别
1、内联函数是在编译时展开,而宏在预编译时展开
2、在编译的时候,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换
3、宏定义不检查函数参数,返回值什么的,只是展开,相对来说,内联函数会检查参数类型,所以更安全
4、内联函数可以访问类的成员变量,宏定义则不能
5、内联函数在运行时可调试,而宏定义不可以
3、数组指针
(1)题目
假设函数原型和变量说明如下:
void f3(int(*p)[4]);
int a[4]={
1,2,3,4},
int b[3][4]={
{
1,2,3,4},{
5,6,7,8},{
9,10,11,12}};
下面调用非法的是()
A: f3(&a);
B:f3(b[1]);
C:f3(&b[1]);
D:f3(b);
(2)知识点
int (*p)[4]
表示p是一个指针变量,指向一个存放4个整型元素的一维数组
int *p[4]
指针数组,本质是一个数组,元素类型为指针(地址1)。
(3)解析
void f3(int(*p)[4]);
函数参数为一个指针变量,指向一个存放4个整型元素的一维数组。
所以参数需为地址。选项B不符合。
4、C++模板 template
(1)函数模板
格式
template < 模板形参表>
返回值类型 函数名(模板函数形参表){
//函数定义体
}
(2)类模板
(3)关键字
5、重载运算符参数(!!!×--------------×)
(1)格式
函数类型 operator 运算符(参数表);
(2)题目
在重载某运算符时,若运算符函数的形参表中没有参数,则可能的情况有( )
- 该运算符是一个单目运算符。
- 该运算符函数有一个隐含的参数this。
- 该运算符函数是类的成员函数。
- 该运算符函数是类的友元函数。
(3)解析
如果运算符被重载为全局函数,那么只有一个参数的运算符叫做一元运算符,有两个参数的运算符叫做二元运算符。
如果运算符被重载为类的成员函数,那么一元运算符没有参数(但是++和–运算符的后置版本除外),二元运算符只有右侧参数,因为对象自己成了左侧参数。
下图可知,前置单目运算符没有参数。所以A对。
友元函数的参数:
因为友元函数没有this指针,则参数要有三种情况:
1、 要访问非static成员时,需要对象做参数;–常用(友元函数常含有参数)
2、 要访问static成员或全局变量时,则不需要对象做参数
3、 如果做参数的对象是全局对象,则不需要对象做参数,所以D错
6、抽象类
(1)题目
关于抽象类说法以下哪些是正确的?
抽象类中可以不存在任何抽象方法
抽象类可以为final的
抽象类可以被抽象类所继承
如果一个非抽象类从抽象类中派生,不一定要通过覆盖来实现继承的抽象成员
(2)知识点
抽象类
一个类中至少有一个纯虚函数
抽象类不能创建对象,派生类需要定义此函数
final
C++11的关键字final有两个用途。第一,它阻止了从类继承;第二,阻止一个虚函数的重载。
覆盖
覆盖是指派生类函数覆盖基类函数,特征是:
( 1 )不同的范围(分别位于派生类与基类);
( 2 )函数名字相同;
( 3 )参数相同;
( 4 )基类函数必须有 virtual 关键字。
(3)解析
抽象类就是必须要被覆盖的
正确答案: A C 你的答案: A C D (错误)
7、continue和break
continue是结束本次循环,开始下次循环
break是跳出循环体,结束整个循环。