牛客C++基础习题收纳

1.在32位小端的机器上,如下代码输出是什么:

char array[12] = {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08};     
short *pshort = (short *)array;     
int *pint = (int *)array;     
int64 *pint64 = (int64 *)array;     
printf("0x%x , 0x%x , 0x%llx , 0x%llx", *pshort , *(pshort+2) , *pint64 , *(pint+2));

A、0x201 , 0x403 , 0x807060504030201 , 0x0

B、0x201 , 0x605 , 0x807060504030201 , 0x0

C、0x201 , 0x605 , 0x4030201 , 0x8070605

D、0x102 , 0x506 , 0x102030405060708 , 0x0

解答:小端存储规则:数据的高位存放在高地址,数据的低位存放在低地址。

① char——一个字节

存储形式:

数据0x010x020x030x040x050x060x070x08
下标01234567

② short——两个字节

存储形式:

数据0x02010x04030x06050x0807
下标0123

*pshort从下标0开始,所以为0x201;

*(pshort+2)从下标2开始,所以为0x605;

③ int64——八个字节

存储形式:

数据0x0807060504030201
下标0

*pint64从下标0开始,所以为0x807060504030201;

④ int——四个字节

存储形式:

数据0x040302010x08070605
下标01

*(pint+2)从下标2开始,下标最大为1,后面默认补零,所以为0x0.

2.下面描述中,表达错误的是:

A、公有继承时基类中的private成员在派生类中仍是private

B、公有继承时基类中的public成员在派生类中仍是public

C、公有继承时基类中的protected成员在派生类中仍是protected

D、私有继承时基类中的public成员在派生类中是private

解答:

  • 公有继承是指派生类继承基类的 public、protected 成员,而基类的 private 成员在派生类中是不可访问的。公有继承关系中,基类的 public 成员可以在任何地方被访问,派生类的成员函数也可以访问基类的 protected 成员,但不能访问基类的 private 成员。

  • 私有继承是指派生类继承基类的 public、protected 成员,但它们都变成了派生类的 private 成员,而基类的 private 成员在派生类中仍然是不可访问的。私有继承关系中,基类的成员在外界都无法访问,只有派生类的成员可以访问,但这些成员通过派生类对象也无法访问基类的成员。

  • 保护继承是指派生类继承基类的 public、protected 成员,但它们都变成了派生类的 protected 成员,而基类的 private 成员在派生类中仍然是不可访问的。保护继承关系中,基类的 public 成员只能在派生类的成员函数和友元函数中被访问,基类的 protected 成员可以在派生类的成员函数和友元函数中被访问,但不能在外界被访问,基类的 private 成员在派生类中仍然是不可访问的。

3.关于引用以下说法错误的是: 

A、引用必须初始化,指针可以不初始化

B、引用初始化以后不能被改变,而指针可以改变指向

C、不存在指向空值的引用,但是存在指向空值的指针

D、一个引用可以看作是某个变量的一个“别名”

E、引用传值,指针传地址

F、函数参数可以声明为引用或指针类型

解答:

指针和引用区别指针和引用联系
指针是一个变量,它存储另一个变量的内存地址。通过指针,我们可以访问或修改存储在特定内存位置的数据。指针和引用都可以用来操作内存地址,但它们的本质是不同的:指针是一个独立的对象,而引用是原对象的别名。
引用是变量的一个别名,它在声明时必须初始化,并且一旦与某个变量绑定后,就不能再改变其引用的对象。

4、下列关于new delete 与malloc free 的联系与区别描述正确的有:

A、都是在栈上进行动态的内存操作

B、用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数

C、delete 会调用对象的destructor,而free 不会调用对象的destructor

D、以上说法都不正确

 解答:

A:new/delete 和 malloc/free 都是用于在堆(heap)上进行动态内存操作,而不是栈(stack)上。

(1)栈(stack)是由编译器自动管理的一块内存区域,用于存储函数调用时的局部变量、函数参数和返回地址等。栈上的内存分配和释放是自动完成的,无需手动管理。

(2)堆(heap)是由程序员手动进行内存分配和释放的一块内存区域,用于存储动态分配的对象、数组等。在堆上分配内存需要使用 new(C++)或 malloc(C)等操作符/函数,而释放内存则需要使用 delete(C++)或 free(C)操作符/函数。

5、 定义宏

则DECLARE(val, int)替换结果为:

A、int val_int_type

B、int val_int_int

C、int name_int_int

D、int name_int_name

解答:

在C++中,可以使用预处理指令#define来定义宏。宏是一种文本替换机制,它允许在代码中定义一个标识符,当编译器遇到该标识符(标识符可以是任何有效的标识符名称)时,会将其替换为预定义的文本(替换文本可以是任何合法的C++代码片段)

宏的基本语法:

#define 标识符 替换文本
#define PI 3.14159  // 定义常量宏
#define MAX(a, b) ((a) > (b) ? (a) : (b))  // 定义带参数的宏函数
#define SQUARE(x) ((x) * (x))  // 定义带参数的宏表达式

##是一种分隔连接方式,它的作用是先分隔,然后进行强制连接,宏定义中使用##时,预处理器会将宏定义中的##替换为相应的标识符。

#define CONCAT(a, b) a##b

int main() {
    int var12 = 42;
    int result = CONCAT(var, 12);  // 将var和12连接成一个标识符var12
    cout << result << endl;  // 输出42
}

“name”和第一个“_”之间被分隔了,所以预处理器会把name##_##type##_type解释成4段:“name”、“_”、“type”以及“_type”,name和type会被替换,而_type不会被替换。

有任何问题欢迎留言!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值