C++面试题和笔试题(四)

一、intx[6][4],(*p)[4];p=x;则*(p+2)指向哪里?

  • A  X[0][1]
  • B X[0][2]
  • C X[1][0]
  • D X[2][0]

官方解释: D

int x[6][4], (*p)[4];  
p = x;

在这里,x 是一个二维数组,它有6行和4列。p 是一个指向具有4个整数的数组的指针。

当你执行 p = x; 时,p 指向 x 的第一行。

接下来,我们要考虑 *(p + 2)

在C语言中,数组名(如 x)代表其首地址。对于二维数组,它实际上是指向第一行的指针。当你对这样的指针进行加法操作时,你会跳过整行,而不是单个元素。

因此,p + 2 会跳过前两行,指向 x 的第三行。

*(p + 2) 会解引用这个指针,所以它实际上就是 x 的第三行。所以,*(p + 2) 指向 x 的第三行的首地址。

为了更直观地理解,你可以这样想象:

  • p 指向 x[0](第一行)
  • p + 1 指向 x[1](第二行)
  • p + 2 指向 x[2](第三行)

所以,*(p + 2) 就是 x[2],它指向 x 的第三行的首地址。 

自己的理解: 

假设我们有一个叫做x的大表格,这个表格有6行和4列。就像你在纸上画格子一样,每个格子可以放一个数字。

然后,我们有一个指针p,它就像一个小箭头,可以指向这个大表格的某一行。

当我们说p = x;的时候,就是把小箭头指向这个大表格的第一行。

接下来,我们要看*(p + 2)是什么意思。

想象一下,这个小箭头每次移动,不是一格一格地移动,而是整行整行地移动。所以,当箭头移动两次时,它就跳过了两行,指向了第三行。

*(p + 2)的意思就是,箭头移动两次后指向的那一行。所以,*(p + 2)指向的就是大表格的第三行。

简单说,就像你在纸上画了一个大表格,然后有一个小箭头指向第一行,当你让箭头跳两下,它就指向了第三行。这就是*(p + 2)的意思啦!

考点

这道题的考点是C语言中的指针和数组的理解

它主要考察了以下几个方面:

  1. 指针与数组的关系:在C语言中,数组名可以视为指向数组首元素的指针。对于二维数组,数组名实际上是指向第一行的指针。

  2. 指针的加法运算:对于指向数组的指针,进行加法运算时,不是按单个元素的大小来移动,而是按指针指向的整个数组或数据块的大小来移动。例如,对于指向int数组的指针,加1意味着跳过整个int大小的空间;对于指向二维数组(即数组的数组)的指针,加1意味着跳过整个一行的空间。

  3. 指针的解引用:使用*操作符可以解引用指针,即获取指针指向的值。对于指向数组的指针,解引用得到的是数组的首元素或首行的地址。

二、有关C++中为什么用模板类的原因,描述错误的是? 

  • A.可用来创建动态增长和减小数据结构
  • B.它是类型无关的,因此具有很高的复用性
  • C.它运行时检查数据类型,保证了类型安全
  • D.它与平台无关,可移值性

官方解释: C

关于C++中模板类的使用原因,我们可以逐项分析这四个选项:

A. 可用来创建动态增长和减小数据结构


这个描述并不准确。模板类主要是用于实现泛型编程,它允许程序员定义与类型无关的函数或类,然后在实例化时指定具体的类型。动态增长和减小的数据结构通常是通过使用如std::vector这样的容器类来实现的,而这些容器类内部可能会使用模板,但模板本身并不直接用于创建这样的数据结构。

B. 它是类型无关的,因此具有很高的复用性


这是正确的。模板类的主要优势之一就是它们的类型无关性。你可以为任何数据类型(包括用户自定义类型)定义模板,并在需要时实例化它们。这大大提高了代码的复用性。

C. 它运行时检查数据类型,保证了类型安全


这是错误的。模板的类型检查是在编译时进行的,而不是运行时。当你在代码中实例化一个模板时,编译器会检查你提供的类型是否满足模板的要求,并在编译阶段报告任何类型不匹配的错误。因此,模板确实保证了类型安全,但这种检查是在编译时进行的。

D. 它与平台无关,可移值性


这也是正确的。模板类在编译时被实例化为具体的类型,生成的代码与平台相关,但模板本身与平台无关。你可以在不同的编译器和平台上使用相同的模板代码,只要这些平台支持C++模板即可。这增加了代码的可移植性。

综上所述,描述错误的是选项C:它运行时检查数据类型,保证了类型安全。

自己的理解:

A. 可用来创建动态增长和减小数据结构


这个选项的意思是说,模板类可以用来创建一种特殊的数据结构,这种数据结构可以变大也可以变小,就像我们的书包一样,可以装很多东西,也可以只装一点点。但是,模板类并不是专门用来做这个的,它更多的是用来帮助我们写一些可以重复使用的代码。

B. 它是类型无关的,因此具有很高的复用性


这个选项是说,模板类就像是一个万能的工具,不管我们要处理的是数字、文字还是其他什么东西,它都可以帮忙。因为它不关心具体是什么类型,所以我们可以把同一个模板类用在很多地方,这就是它的复用性很高。

C. 它运行时检查数据类型,保证了类型安全


这个选项其实是错的。模板类是在我们写代码的时候就检查数据类型,而不是等到程序运行的时候。如果数据类型不对,它会在我们写代码的时候就告诉我们,而不是等到程序运行时才报错。

D. 它与平台无关,可移值性


这个选项是说,不管我们是在什么样的电脑或手机上使用模板类,它都可以正常工作。就像我们玩的游戏,不管是用电脑还是手机,只要游戏支持,我们都可以玩。这就是模板类的可移植性。

所以,描述错误的是选项C,它其实是在我们写代码的时候就检查数据类型,而不是运行时

考点:

  1. 模板类的定义和用途:模板类是C++中实现泛型编程的基础工具,它允许程序员定义与类型无关的代码,从而增加代码的复用性。 

  2. 模板的类型检查时机:模板的类型检查是在编译时进行的,而不是运行时。这是模板的一个重要特性,它确保了在实例化模板时,提供的类型参数符合模板的要求。

  3. 模板的可移植性:模板代码本身与平台无关,只要目标平台支持C++模板,就可以使用相同的模板代码。这体现了模板的可移植性。

  4. 模板与动态数据结构的区别:模板类虽然可以用于定义数据结构,但它本身并不直接创建动态增长和减小的数据结构。这种数据结构的实现通常依赖于特定的容器类,如std::vector等。

 三、在32位机器上用gcc编译以上代码,sizeof(),sizeof()分别是多少

Class A
{
int a;
short b;
int c;
char d;
};
class B
{
double a;
short b;
int c;
char d;
};
  •  A 12,16
  •  B 12,12
  •  C 16,24
  •  D 16,20

官方解释:C

以下是对每个数据成员的大小和可能的对齐要求的简要说明:

  • int 通常大小为4字节,并且通常需要4字节对齐。
  • short 通常大小为2字节,并且通常需要2字节对齐。
  • double 通常大小为8字节,并且通常需要8字节对齐。
  • char 通常大小为1字节,对齐要求通常最小。

现在,让我们考虑类AB的内存布局:

 对于类A

class A  
{  int a;   // 4字节,可能需要对齐到4字节边界  short b; // 2字节,可能需要对齐到2字节边界(但因为前面是int,所以这里可能不需要额外的填充)  int c;   // 4字节,需要对齐到4字节边界(这里可能需要填充)  char d;  // 1字节,通常不需要额外的对齐或填充  
};
int a (4 bytes)  
short b (2 bytes)  
填充 (2 bytes) // 为了使下一个int c对齐到4字节边界  
int c (4 bytes)  
char d (1 byte)  
填充 (3 bytes) // 为了使整个结构体的大小是4的倍数(取决于编译器是否这样做)

 总大小可能是 4 + 2 + 2 + 4 + 1 + 3 = 16 字节。

由于int之后紧跟着short,并且int已经满足了short的2字节对齐要求,所以这里可能不需要填充。但是,short之后是另一个int,这通常要求4字节对齐。如果short之后没有足够的空间来满足下一个int的4字节对齐要求,编译器可能会在shortint之间插入填充字节。

对于类B

class B  
{  double a; // 8字节,需要对齐到8字节边界  short b;  // 2字节,可能需要对齐到2字节边界(但因为前面是double,所以这里可能需要填充)  int c;    // 4字节,需要对齐到4字节边界(这里可能需要填充)  char d;   // 1字节,通常不需要额外的对齐或填充  
};
double a (8 bytes)  
填充 (6 bytes) // 为了使short b对齐到下一个合适的地址(可能是2字节边界)  
short b (2 bytes)  
填充 (2 bytes) // 为了使int c对齐到4字节边界  
int c (4 bytes)  
char d (1 byte)  
填充 (1 bytes) // 为了使整个结构体的大小是合适的对齐值(取决于编译器)

B的大小可能是 8(double) + 6(填充) + 2(short) + 4(int) + 1(char) + x(填充),其中x取决于编译器是否添加额外的填充以及添加多少。如果编译器决定让整个结构体的大小是8的倍数(以匹配double的对齐要求),那么总大小可能是24字节。

自己的理解: 

你有一个大盒子(这就是我们的结构体或类),你要把一些不同大小的东西放进去。但是,你不能随便放,有些东西需要放在特定的位置,这样拿起来才会更方便(这就是对齐的意思)。

对于类A

  1. 你首先放了一个大玩具(int a),它占了4个格子的空间。
  2. 然后你放了一个小玩具(short b),它占了2个格子的空间。因为它紧挨着大玩具,所以不需要额外的格子。
  3. 接下来,你想再放一个大玩具(int c),但是你需要确保这个大玩具从新的4个格子的位置开始放,这样拿起来更方便。所以,你在小玩具和大玩具之间放了2个空格子。
  4. 最后,你放了一个非常小的玩具(char d),只占了1个格子。
  5. 但是,为了让整个盒子的大小是4的倍数(这样放起来更整齐),你又在盒子的最后面放了几个空格子。

对于类B

  1. 你首先放了一个非常大的玩具(double a),它占了8个格子的空间,并且从8个格子的位置开始放。
  2. 接着你想放一个小玩具(short b),但是因为这个大玩具占了8个格子,你需要在大玩具和小玩具之间放6个空格子,这样小玩具才能从合适的位置开始。
  3. 然后你又放了一个大玩具(int c),它占了4个格子。这次不需要额外的空格子,因为小玩具后面已经有足够的空间了。
  4. 最后,你放了一个非常小的玩具(char d),只占了1个格子。
  5. 和类A一样,为了让整个盒子的大小是8的倍数,你又在盒子的最后面放了几个空格子。

 四、下面对静态数据成员的描述中,正确的是

  • A.静态数据成员可以在类体内进行初始化
  • B.静态数据成员不可以被类的对象调用 
  • C.静态数据成员不受private控制符号的作用
  • D.静态数据成员可以直接用类名调用

官方解释:AD

  • 选项 A:静态数据成员可以在类体内进行初始化,使用static关键字声明后,可以在类声明中直接初始化静态数据成员,例如static int val = 42;。所以选项 A 是正确的。
  • 选项 B:静态数据成员可以被类的对象调用,静态数据成员是类的所有对象共享的成员,可以通过类的对象来访问静态数据成员,例如MyClass obj; obj.val = 24;。所以选项 B 是错误的。
  • 选项 C:静态数据成员受private控制符号的作用,即使是静态数据成员,如果被声明为private,也只能在类的内部访问,例如private static int val;。所以选项 C 是错误的。
  • 选项 D:静态数据成员可以直接用类名调用,这是静态数据成员的一个重要特性,可以使用类名和点运算符来访问静态数据成员,例如MyClass.val = 64;。所以选项 D 是正确的。

 自己的理解:

  • 选项 A:静态数据成员可以在类体内进行初始化。

     

    生活例子:假设有一个人类类Person,其中有一个静态数据成员totalPopulation表示全球总人口。我们可以在类声明中初始化这个静态数据成员,例如:

    class Person {
    public:static int totalPopulation;
    };
    int Person::totalPopulation = 7000000000; // 初始化静态数据成员
  • 选项 D:静态数据成员可以直接用类名调用。

     

    生活例子:继续上面的人类类Person的例子,我们可以直接使用类名和点运算符来访问静态数据成员totalPopulation,例如:

    cout << Person::totalPopulation << endl; // 输出静态数据成员的值
     在这个例子中,我们直接使用类名Person和点运算符来访问静态数据成员totalPopulation,并将其值输出到标准输出流中。这样可以方便地获取全球总人口的信息,而不需要创建Person对象。

 考点:考察了 C++ 中类的静态数据成员的特性和使用方法,包括静态数据成员的初始化方式、访问方式以及与类对象的关系。

五、填空题(一)

#include<iostream>  
using namespace std;  class A {  
public:  A() { cout << "1" << endl; }  // 构造函数  A(const A& a) { cout << "2" << endl; }  // 拷贝构造函数  A& operator=(const A& a) { cout << "3" << endl; return *this; }  
};  int main() {  A a;   A b = a;   return 0;  
}

运行结果为( 1 ,2);

  1. 当你在 main 函数中创建 A 类的实例 a 时,会调用其构造函数,因此会输出 1
  2. 接下来,当你创建 b 并用 a 初始化它时,会调用拷贝构造函数,因此会输出 2
  • 1 对应构造函数 A()
  • 2 对应拷贝构造函数 A(const A& a)

自己的理解: 

假设我们有一个玩具工厂,这个工厂可以生产一种叫做“A”的玩具。

当我们告诉工厂开始生产一个“A”玩具时,工厂就会按照“A”的模板来制作,这就像是在代码中调用构造函数,输出“1”表示玩具制作完成了。

现在,我们已经有了一个“A”玩具,叫做“a”。如果我们想再要一个和“a”完全一样的玩具,我们不需要再让工厂从头开始制作,因为那样太麻烦了。我们可以直接让工厂复制一个“a”玩具,这样我们就得到了一个新的玩具,叫做“b”。这个过程就像是代码中的拷贝构造函数,输出“2”表示我们已经通过复制得到了一个新的玩具。

所以,整个过程的步骤和输出就是:

  1. 工厂按照模板制作了一个“A”玩具(输出“1”)。
  2. 工厂复制了一个已有的“A”玩具,得到了一个新的玩具(输出“2”)。

六、填空题(二) 

 

#include <iostream>
using namespace std
#define M(A,B,C) A*B+C
int main()
{
int a=1;
int b=2;
int c=3;
cout<<M(a+b,b+c,c+a)<<endl;
return 0;
}

运行的结果输出是(19)

官方解释

代码中定义了一个宏 M(A,B,C),它接受三个参数 AB 和 C,并将它们替换为表达式 A*B+C。这意味着在代码中每次使用 M(x, y, z) 时,它都会被预处理器替换为 x*y+z

在 main 函数中,定义了三个整数变量 ab 和 c,并分别赋值为 1、2 和 3。

接下来,代码中使用宏 M 来计算一个表达式,并将结果输出到控制台。这里,M(a+b,b+c,c+a) 会被替换为 (a+b)*(b+c)+(c+a)。将 ab 和 c 的值代入,我们得到 (1+2)*(2+3)+(3+1),即 3*5+4,最终结果为 19。

自己的理解

M(A,B,C)与M(a+b,b+c,c+a)等价的话,A=a+b,B=b+c,C=c+a;

  1. 先算a+b,也就是1加2,等于3。
  2. 再算b+c,也就是2加3,等于5。
  3. 然后根据A*B+C的例子替换为 (a+b)*(b+c),得到15。
  4. 最后加上c+a,也就是3加1,得到4。
  5. 把15和4加起来,得到最终的结果19

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/275958.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Let’s Move Sui , 一起来学习吧

Let’s Move Sui是一个全新的交互式学习平台&#xff0c;通过SuiFrens的帮助教您如何在Sui上构建。设计供新手和经验丰富的开发者使用&#xff0c;Let’s Move Sui提供了一次非凡的Sui开发之旅&#xff0c;利用了Move在Sui上的独特之处&#xff0c;从基于对象的数据模型的基础知…

Acer宏碁非凡Swift SFG16-71工厂模式原厂Win11系统,预装OEM系统恢复开箱状态

宏基笔记本电脑SFG16-71原装出厂Windows11系统安装工厂包下载&#xff0c;带恢复重置功能 链接&#xff1a;https://pan.baidu.com/s/1JK02kBbwKG_cIBNlEOzrOw?pwdzdfm 提取码&#xff1a;zdfm 原装工厂包系统自带所有驱动、Office办公软件、出厂时自带主题壁纸图片、系统…

在【IntelliJ IDEA】中配置【Tomcat】【2023版】【中文】【图文详解】

作为一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;IntelliJ IDEA为Web服务器提供了卓越的支持&#xff0c;从而极大地简化了程序员在Web开发过程中的工作流程。学习Java Web开发实质上就是掌握如何创造动态Web资源&#xff0c;这些资源在完成开发后&…

Linux - 安装 nacos(详细教程)

目录 一、简介二、安装前准备三、下载与安装四、基本配置五、单机模式 一、简介 官网&#xff1a;https://nacos.io/ GitHub&#xff1a;https://github.com/alibaba/nacos Nacos 是阿里巴巴推出的一个新开源项目&#xff0c;它主要是一个更易于构建云原生应用的动态服务发现…

离线数仓(六)【ODS 层开发】

前言 今天开始正式的数仓搭建&#xff0c;所谓 ODS 层的工作就是把我们各种数据源采集发送来的各种类型的数据&#xff08;Json、tsv类型&#xff09;映射到 Hive 表中&#xff0c;映射时可以进行一些简单的处理&#xff0c;比如简单的数据清洗&#xff0c;舍弃一些没有必要的字…

金三银四!一个年薪160W+的就业方向!

前言 随着越来越多的科技大厂加入鸿蒙生态建设&#xff0c;鸿蒙开发人才正在市场上被争抢。资深工程师开出的年薪高达近百万&#xff0c;架构师更是高至160万&#xff0c;真可谓“鸿蒙猿年薪超百万”。如何抓住新技术红利&#xff0c;尽早上车&#xff1f;你会成为下一个鸿蒙开…

C语言——详解字符函数和字符串函数(一)

Hi,铁子们好呀&#xff01;今天博主来给大家更一篇C语言的字符函数和字符串函数~ 具体讲的内容如下&#xff1a; 文章目录 &#x1f386;1.字符分类函数&#x1f4af;&#x1f4af;⏩1.1 什么是字符分类函数的&#xff1f;&#x1f4af;&#x1f4af;⏩1.2 字符函数的类型有哪…

一文讲懂 C++ 类和对象(1)

0. 面向过程程序设计和面向对象程序设计的区别 面向对象程序设计往往关注的是怎么去做&#xff0c;是将解决问题的步骤分析出来&#xff0c;然后用函数把步骤一步一步实现&#xff0c;然后再依次调用就可以了。而面向对象是将构成问题的事物&#xff0c;分解成若干个对象&…

基于springboot+vue实现汽车改装方案网站系统项目【项目源码+论文说明】

基于springboot实现汽车改装方案网站系统演示 摘要 本文主要讲述了基于SpringBootMySql开发技术开发的汽车改装方案网站的设计与实现。这里的汽车改装方案网站是通过一个平台使所有的汽车爱好者们可以不用出门就可以体验到专业的汽车改装方案设计服务。现实生活中如果需要进行…

牛客-DP38 【模板】二维差分

【模板】二维差分_牛客题霸_牛客网 (nowcoder.com) b站有视频&#xff1a;讲解前缀和和差分 二维差分_哔哩哔哩_bilibili 注意&#xff1a;差分的过程叫差分&#xff0c;而不仅仅是d[]这个数组&#xff0c;其他数组经行了差分的操作&#xff0c;就也是差分啊&#xff01;&…

springcloud第3季 consul服务发现注册,配置中心2

一 consul的作用 1.1 为何使用注册中心 为何要用注册中心&#xff1f; 1.A服务调用B服务&#xff0c;使用ip和端口&#xff0c;如果B服务的ip或者端口发生变化&#xff0c;服务A需要进行改动&#xff1b; 2.如果在分布式集群中&#xff0c;部署多个服务B&#xff0c;多个服…

JAVA基础—集合详细解析

1.JAVA中的4种集合类型 Set&#xff1a;无序、不可重复的集合List&#xff1a;有序、重复的集合Queue&#xff1a; 队列Map&#xff1a;映射关系 首先&#xff0c;JAVA的集合类主要有两个接口派生而出&#xff1a;Collection和Map。Collection和Map就是JAVA集合的根接口。所以后…

Kubernetes弃用Dockershim,转向Containerd:影响及如何应对

Kubernetes1.24版本发布时&#xff0c;正式宣布弃用Dockershim&#xff0c;转向Containerd作为默认的容器运行环境。Kubernetes以CRI(Container Runtime Interface)容器运行时接口制定接入准则&#xff0c;用户可以使用Containerd、CRI-O、CRI- Dockerd及其他容器运行时作为Kub…

在Docker上传我们自己的镜像(以springboot项目为例)

首先确定好在我们的centOS服务器上已经安装并配置好docker 配置自己的springboot镜像并运行 获取springboot的jar包 maven clean--》mavenue package --》复制target目录下生成的jar包 在服务器选择一个文件夹上传jar包&#xff0c;我这里选用的文件夹叫做/opt/dockertest…

【话题】2024年AI辅助研发趋势,有那些应用领域

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】系列文章&#xff0c;这一次的话题是《2024年AI辅助研发趋势》 目录 背景概念实践医药领域汽车设计领域展望未来文章推荐 背景 随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅…

使用电脑的时候最怕有英文?微信的这个功能一定要用起来!

相信各位小伙伴对微信都不陌生。我们平常使用微信的大部分时间都是聊天、朋友圈、视频号等。 如果有人给你发来一张全英文图片的截图&#xff0c;你会咋整&#xff1f; 请人翻译&#xff1f;这个显然不需要。 一个个字母手打上去&#xff1f;这字数少了还行&#xff0c;但多了…

HarmonyOS NEXT应用开发之深色模式适配

介绍 本示例介绍在开发应用以适应深色模式时&#xff0c;对于深色和浅色模式的适配方案&#xff0c;采取了多种策略如下&#xff1a; 固定属性适配&#xff1a;对于部分组件的颜色属性&#xff0c;如背景色或字体颜色&#xff0c;若保持不变&#xff0c;可直接设定固定色值或…

strcat的模拟实现

一&#xff1a;strcat函数的定义&#xff1a; strcat函数功能的解释&#xff1a; 将源字符串追加&#xff08;连接&#xff09;到目的字符串的后面 strcat函数要点&#xff1a; 源字符串必须以 \0 结束。 目标空间必须有足够的大&#xff0c;能容纳下源字符串的内容。 目…

智慧城市与智慧乡村:共创城乡一体化新局面

一、引言 随着科技的不断进步和城乡发展的日益融合&#xff0c;智慧城市与智慧乡村的建设已成为推动城乡一体化发展的新引擎。智慧城市利用物联网、大数据、云计算等先进技术&#xff0c;实现城市治理、公共服务、产业发展等领域的智能化&#xff1b;而智慧乡村则借助现代科技…

spring中事务失效的场景有哪些?

异常捕获处理 在方法中已经将异常捕获处理掉并没有抛出。 事务只有捕捉到了抛出的异常才可以进行处理&#xff0c;如果有异常业务中直接捕获处理掉没有抛出&#xff0c;事务是无法感知到的。 解决&#xff1a;在catch块throw抛出异常。 抛出检查异常 spring默认只会回滚非检…