牛客c++专项训练5.13 类模版+函数模版+预处理+野指针+默认实参

本文详细探讨了C++中的类模板、函数模板、预处理指令,包括DLL动态链接库的DllMain函数调用、函数模板实例化、类内存占用、C与Objective-C混合编程的注意事项、字符串数组的区别以及默认实参、内存操作函数的选择等核心概念。同时,讲解了空指针和未初始化指针的区别、预处理指令的作用和常见类型,以及循环和指针操作在C++中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.下列哪些代码会调用一个DLL的 DllMain 函数

正确答案: A B D   你的答案: 空

A   LoadLibraray("A.dll")

B   GetModuleHandle(0,"A.dll",&hDLL)

C   LoadLibraryEx("A.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);

D   FreeLibrary(hDLL)

DLL动态链接库,DllMain是DLL的入口函数

 

2.关于函数模板,描述错误的是()。

正确答案: A C D   你的答案: B D

A 函数模板必须由程序员实例化为可执行的函数模板      函数模板必须由编译器根据程序员的调用类型实例化为可执行的函数

B 函数模板的实例化由编译器实现

C 一个类定义中,只要有一个函数模板,这个类就是类模板     类模板的成员函数都是函数模板

D 类模板的成员函数都是函数模板,类模板实例化后,成员函数也随之实例化         没使用过的成员函数(即函数模板)不会被实例化

编译器使用模板为特定类型生成函数定义时,得到的是模板实例(instantiation)

 

 

3.以下关于类占用内存空间的说法正确的是

正确答案: A B C D   你的答案: B C

A 类所占内存的大小是由成员变量(静态变量除外)决定的

B 空类的内存大小是1个字节

C 类中无论有多少个虚函数,只会多占一个虚表指针空间

D 子类的内存大小等于父类的内存大小加上子类独有成员变量的内存大小

 

4.C和Objective-C的混合使用,以下描述错误的是()

正确答案: B   你的答案: 空

A   cpp文件只能使用C/C++代码

B   cpp文件include的头文件中,可以出现objective-C的代码

C   mm文件中混用cpp直接使用即可

D   cpp使用objective-C的关键是使用接口,而不能直接使用代码

 

5.给出以下定义:

Char x[]=”abcdefg”;

Char y[]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’};

正确答案: C   你的答案: A

A数组X和数组Y等价

B数组X和数组Y的长度相同

C数组X的sizeof运算值大于数组Y的sizeof运算值

D数组X的sizeof运算值小于数组Y的sizeof运算值

x定义会在后面添加 ‘\0’ ,所以x比y多一个结束符号

 

7.有以下程序
#include<iostream>
using namespace std;
____________________
int main()
{int a=1,b=2,c=3;
cout<<add(a,b,c);
return 0;}
int add(int x,int y,int z)
{ return x+y+z; }
程序运行的结果是6,请为横线处选择合适的程序(      )

正确答案: A D   你的答案: 空

A   int add(int x,int y=5,int z=6);

B   int add(int x=1,int y=5,int z);            声明时,必须从右往左初始化,且中间不能跳

C   int add(int x=1,int y,int z=6);

D   int add(int x=1,int y=5,int z=6);

默认实参作为形参的初始值出现在形参列表中。我们可以为一个或多个形参定义默认值,不过需要注意一点的是,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值;

 

8.以下哪个函数可以在源地址和目的地址的位置任意的情况下,在源地址和目的地址的空间大小任意的情况下实现二进制代码块的复制?

正确答案: B   你的答案: A

A   memcpy()

B   memmove()

C   memset()

D   strcpy()

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

char *strcpy(char* dest, const char *src)   把从src地址开始且含有NULL结束符的字符串复制到以dest开始的 地址空间

void *memcpy(void *dest, const void *src, size_t n);    从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 

void *memmove( void* dest, const void* src, size_t count );   由src所指内存区域复制count个字节到dest所指内存区域。

void *memset(void *s, int ch,  size_t  n);   将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s

 

9.已知:print( )函数是一个类的常成员函数,它无返回值,下列表示中,( )是正确的

正确答案: A   你的答案: C

A  void print( ) const;

B  const void print( );

C  void const print( );

D  void print(const);

const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰。

 

10.使用printf函数打印一个double类型的数据,要求:输出为10进制,输出左对齐30个字符,4位精度。以下哪个选项是正确的?

正确答案: C   你的答案: D

A  %-30.4e

B  %4.30e

C  %-30.4f

D  %-4.30f

-: 左对齐

30: 最小字段宽度

.4: 精确度保留小数4位

f: double精度浮点数

e: 科学计数法

 

11.下面有关空指针和未初始化指针,说法错误的是?

正确答案: D   你的答案: A

A  对0x0这个地址取值是非法的                                                    无法为内存为0的地址取地址

B  空指针可以确保不指向任何对象或函数; 而未初始化指针则可能指向任何地方。

C  空指针与任何对象或函数的指针值都不相等

D  malloc在其内存分配失败时返回的是一个未初始化的指针                  在分配内存失败时会返回“NULL Pointer”空指针

空指针与野指针的区别,空指针也就是通常指向为NULL的指针,野指针就是指向一块未知的内存区域(可以是通过malloc或new申请空间后,释放后没有将指针置为空),也有可能定义了一个指针没有初始化,由于内存空间中的值在未赋值之前是随机数,所以也有可能诞生野指针。

 

12.源程序中凡是行首以#标识的控制行都是预处理指令。以上描述是否正确?

正确答案: A   你的答案: B

A正确

B错误

编译预处理有如下几种:
1、头文件包含 #include
2、宏定义 #define
3、条件编译 #ifdef #endif

综上所述,C语言有效的预处理命令总是以"#"开头

程序设计语言的预处理的概念:在编译之前进行的处理。

 

13.以下关于函数模板叙述正确的是(    )。

正确答案: C   你的答案: C

A函数模板也是一个具体类型的函数

B函数模板的类型参数与函数的参数是同一个概念

C通过使用不同的类型参数,函数模板可以生成不同类型的函数

D用函数模板定义的函数没有类型

函数模板是一种特殊的函数,可以使用不同的类型进行调用,对于功能相同的函数,不需要重复编写代码,并且函数模板与普通函数看起来很类似,区别就是类型可以被参数化,函数模板通过template与typename两个关键字来定义

 

14.以下叙述中正确的是()

正确答案: B   你的答案: D

A  循环发生嵌套时,最多只能两层              没有限制

B  三种循环for,while,do-while可以互相嵌套

C  循环嵌套时,如果不进行缩进形式书写代码,则会有编译错误        C++不必要求缩进

D for语句的圆括号中的表达式不能都省略掉             可以

 

15.下列程序的输出结果是()

    int n[][3] = {10, 20, 30, 40, 50, 60};

    // p为指针类型,指向的类型是int[3]
    int(*p)[3];
    p = n;

    std::cout << p[0][0] << ", " << *(p[0] + 1) << ", " << (*p)[2] << endl;
  

正确答案: C   你的答案: A

A 10,30,60

B 20,40,60

C 10,20,30

D 10,30,50

p为一个数组指针,指向了一个大小为3的数组,在这里就指向了n的首地址

p[0][0]=n[0][0]     *(p[0]+1)=n[0][1]    (*p)[2]=n[0][2]

看第一个p[0][0],没啥好说的就是10。

第二个*(p[0]+1),这里注意p[0],它实际上就是n[0],那么我们n[0]存的是什么呢,实际上是n[0][0]这个地址,然后我们+1,那么指针就偏移为指向类型的大小既int,4个字节,所以到了n[0][1]的地址然后取值即为20.

第三个(*p)[2],这里需要注意括号,我们需要先计算*p,既p首地址存的是啥,实际上就是存的n[0],所以(*p)[2]等价于n[0][2],所以结果为30.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值