C++学习笔记02-结构基础(问题-解答自查版)

news2024/9/24 9:27:21

前言

以下问题以Q&A形式记录,基本上都是笔者在初学一轮后,掌握不牢或者频繁忘记的点

Q&A的形式有助于学习过程中时刻关注自己的输入与输出关系,也适合做查漏补缺和复盘。

本文对读者可以用作自查,答案在后面,需要时自行对照。

--

问题集

## 2022年6月9日 -《C++ Primer plus》第5~8章

Q1:下面语句的执行结果?(注意:逗号的优先级)

        int cats = 17, 240;

        int cats = (17, 240);

Q2:以下两个C++函数的定义?哪个正确?

        void sum_arr(int iarray[], int n){ }

        void sum_arr(int[] iarray, int n){ }

Q3:手写迭代器,代码中 const int *i 是什么含义?

void print_arr(const int * begin, const int * end){

   for (const int *i = begin; i != end; i++) 

        cout << *i << " ";

}

int main(){

    int arr[arrSize]= {1,2,3,4,5,6,7};

    print_arr(arr, arr + arrSize);   //优点:从 地址begin~地址end 的遍历

}

Q4:C++中,这样能修改const变量吗?

        const float gmoon =1.63;

        float *pm = &g_moon;

Q5:如何定义一个第一个参数接受二维数组的函数体?:int sum(  ,int size)

Q6:函数探幽——引用的本质?可以有空引用吗?

Q7:如何理解引用将两个变量 wallet1和wallet2 产生交换?

Q8: double refcube (const double &ra ); 入参 声明成这样有什么作用?

Q9:已知 double refcube (const double &ra ); 函数声明

        double z = refcube (x + 3.0); 这个调用正确吗?

         (注意本eg中:x是一个引用型double变量)

Q10:C++中,比较严谨的左值定义?

        另外地,有没有简单粗暴的理解方法?

Q11:已知 double refcube (double &ra ); 函数声明。

        什么时候编译器会让ra默认创建临时变量?(了解即可)

Q12:右值引用如何声明?一种特殊语法,使用在什么地方?

Q13:函数返回结构体引用变量的目的是什么?

Q14:将类对象传递给函数时,C++通常的做法是使用()

Q15:这个函数重载的方式正确吗?

 Q16:这个函数重载的是否正确?

        int func(int a);

        int func(const int a);

Q17:模版函数的两种写法?

Q18:显式模板化是什么?其函数的声明?

Q19:重载匹配的规则?

Q20:cout << lesser<> (m, n) << endl ;  这个语法是什么意思?

Q21:函数模板中遇到未知变量类型,该使用何种关键字进行?

ps:这个情境最主要是因为模版无法预知入参运算的结果,比如 int+float 和 int+long 就很不同

参考解答

Q1:下面语句的执行结果?

        int cats = 17, 240;

        int cats = (17, 240);

A1:

 Q2:以下两个C++函数的定义?哪个正确?

        void sum_arr(int iarray[], int n){ }

        void sum_arr(int[] iarray, int n){ }

函数的入参为数组的时候,入参应被视为数组本身,还是数组首地址?

A2:void sum_arr(int iarray[], int n){ }正确;

根据C++规则,入参为数组,入参 int iarray[] = 数组名 = 函数指针 = 其第一个元素的地址

也就是说:函数传递的实则为地址

这里补充了一个实验:

void sum_arr(int iarray[], int n){

    cout << 1;

}

void sum_arr(int * iarray, int n){

    cout << 2;

}

在这段代码中,函数 sum_arr 并不视为两种重载,而是视为重复定义,也就是其本质一样

void sum_arr(int iarray[ ], int n) 实际在编译时被转换成了 → void sum_arr(int * iarray, int n)

注意:在C++中,当且仅当用于函数头或函数原型中,int *arr 和 int arr []的含义才是相同的。它们都意味着 arr 是一个 int 指针。

  

 Q3:手写迭代器,代码中 const int *i 是什么含义?

void print_arr(const int * begin, const int * end){

   for (const int *i = begin; i != end; i++) 

        cout << *i << " ";

}


int main(){

    int arr[arrSize]= {1,2,3,4,5,6,7};

    print_arr(arr, arr + arrSize);   //优点:从 地址begin~地址end 的遍历

}

A3:const int *i 表示一个 指向 const int 的指针,意味着这个指针的位置不会发生改变。

Q4:这样能修改const变量吗?

        const float gmoon =1.63;

        float *pm = &g_moon;

A4:不可以,语法上直接报错,其正确格式:

        const float gmoon = 1.63;

        const float *pm = &g_moon;

C++禁止将 const 的地址赋给非 const 指针。// error: invalid conversion from 'const char*' to 'char*' [-fpermissive]

如果读者非要这样做,可以使用强制类型转换来突破这种限制,详情请参阅第15章中对运算符const_cast 的讨论,这个东西专门用来突破const界限。

Q5:如何定义一个第一个参数接受二维数组的函数体?:int sum(  ,int size)

A5:如下

ar2是指针而不是数组。还需注意的是,指针类型指出,它指向由 4 个int组成的数组

因此,指针类型指定了列数,这就是没有将列数作为独立的函数参数进行传递的原因。

Q6:函数探幽——引用的本质?可以有空引用吗?

A6:给变量取别名;

引用变量的主要用途是用作函数的形参,引用变量用作参数,函数将使用原始数据,而不是其副本

引用要求初始化的时候就产生“绑定”,不能跳过初始化。这个特性比较类似const指针

Q7:如何理解引用将两个变量 wallet1和wallet2 产生交换?

A7:在swapr()中,变量a和b是 wallet1 和 wallet2 的别名,所以交换a和b的值相当于交换 wallet1 和 wallet2 的值;

注意:引用是别名,而不是地址只是提供了一种方式来访问和操作它所绑定的对象。

这里有个习作,看看能不能看懂:

    int man = 233;        // 定义man

    int & robot = man;    // 定义引用变量 robot,绑定man,以后robot就是man的别名了

   

    vplus(robot);         // 给robot表示的变量输入vplus函数

    cout << man;         

}



void vplus (int & value){    // vplus:给入参表示的变量++; 即:给value表示的robot表示的man变量++

    value ++;                // 实际上,robot,man和vplus运行中的value指向了同一个值

}

Q8: double refcube (const double &ra ); 参数 声明成这样有什么作用?

A8:声明引用变量 &ra 是不可变的引用。引用型变量如果在函数体内部变来变去,外面的值也就发生变化了。

这个功能对于 ra 是一个double而言,实际上和值传递没有区别。

这个功能最有用的地方是用来引用struct或者class,如下:

之后在其中不用指针操作,而是可以直接在函数体内写 ft.name = "Joe"

Q9:接上面,已知 double refcube (const double &ra ); 声明

        double z = refcube (x + 3.0); 这个调用正确吗? (本eg:x是一个非const 的 double 引用变量)

A9:不正确,因为x+3不是一个变量。

        这里涉及了一个不容易被注意的规则:如果实参(double)与引用参数(const double &)不匹配,C++将生成临时变量。(具体的规则可以看Q11)

Q10:C++中,比较严谨的左值定义?

A10:定义比较简单,主要基于是否可被赋值,int a,以及 const int a; 都可以被视作左值

        较为粗暴的理解:

        C++中所有值必然属于左值或者右值
        在C++11中可以取地址的、有名字的就是左值
        反之,不能取地址的、没有名字的就是右值

Q11:已知 double refcube (double &ra ); 声明

        什么时候会让ra默认创建临时变量?(编译器差异,了解即可)

A11:目前,这种语法如果使用右值,已经不再是告警,而是直接报错:包括下面 c++ prime plus 书中的案例

旧版本两种情况:

        1)实参的类型正确,但不是左值;

        2)实参的类型不正确,但可以转换为正确的类型。

        总而言之,就是需要临时整一下,不能直接提供。

Q12:右值引用如何声明?一种特殊语法,使用在什么地方?

A12:用&&声明,

    int && ref = 7;

    cout << ref << endl;

允许将资源(如内存、文件句柄等)从临时对象转移到新对象,实现移动语义

Q13:函数返回结构体引用变量的目的是什么?

A13:为了效率,少一次拷贝。

Q14:将类对象传递给函数时,C++通常的做法是使用()

A14:引用

Q15:这个函数重载的方式正确吗?

A15:不正确。

Q16:这个函数重载的是否正确?

        int func(int a);

        int func(const int a);

A16:不正确,const 不会被认作区分。

Q17:模版函数的两种写法?

A17:

template <typename T>;

或者 template <class T>;  // 后者C++98老式风格

void Swap(T &a,T &b) ;

Q18:显式模板化是什么?其函数的声明?

A18:

Q19:重载匹配的规则?

A19:哪个最接近匹配哪个。默认优先级:正常函数 > 模版函数

Q20:cout << lesser<> (m, n) << endl ;  这个语法是什么意思?

A20:主要是对于有函数模板和正常函数并存的情况,手动选择函数模板。

Q21:函数模板中遇到未知变量类型,该使用何种关键字进行?

ps:这个情境最主要是因为模版无法预知入参运算的结果,比如 int+float 和 int+long 就很不同

A21:通过关键字 decltype(x) y ,make y's type same as x;这个语法有点 auto y as x 的意思;

decltype 的内在本质是一个查表逻辑

Q22:函数模板中遇到未知返回值类型,该使用何种关键字进行?

ps:比起上一个问题,这个的难度在于考虑 x和y 甚至没有声明,编译器一无所知

后置返回类型 的内在本质是让 x和y 两个入参具备了作用域前提

A22:auto func()  -> TYPE,

// 这里的 TYPE 可以是传统类型,也可以是 decltype(入参)

经测验,这个代码可以运行正常(没有用decltype):

template <typename T1, typename T2>

auto add(T1 a, T2 b){     //   auto add(T1 a, T2 b)  -> decltype(a+b)  is also correct

    return a+b;

}

int main(){

    int a = add(5,6);

    double b = add(5, 6.2);

    cout << a << endl;

    cout << b << endl;

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git的使用教程

仓库分区 Git本地有三个工作区域:工作目录&#xff08;Working Directory&#xff09;,暂存区&#xff08;Stage/Index&#xff09;&#xff0c;资源库&#xff08;Repository或Git Directory&#xff09;。如果再加上远程的git仓库&#xff08;Remove Directory&#xff09;就…

SAP PP 物料主数据字段状态控制

参考 https://zhuanlan.zhihu.com/p/452823415 物料主数据里面的状态 由 1、行业 2、工厂 3、物料类型 4、事务代码 5、采购相关字段 6、客制 优先级 隐藏->显示->必输->可选

Go基础编程 - 11 - 函数(func)

接口&#xff08;interface&#xff09; 函数1. 函数定义1.1. 函数名1.2. 参数列表1.3. 返回值列表 2. 匿名函数3. 闭包、递归3.1 闭包3.1.1 函数、引用环境3.1.2 闭包的延迟绑定3.1.3 goroutine 的延迟绑定 3.2 递归函数 4. 延迟调用&#xff08;defer&#xff09;4.1 defer特…

C语言中的控制语句(三):while 和 do while 语句

文章目录 [toc] &#x1f34a;自我介绍&#x1f34a;while语句&#x1f34a;do...while循环&#x1f34a;&#x1f34a; 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello…

单调栈(随缘复习到了,顺手刷了)

也是不知道为什么突然又复习到单调栈了&#xff0c;所以顺手刷了三道题&#xff0c;总结一下 P6503 [COCI2010-2011#3] DIFERENCIJA 思路&#xff1a;这题是要求每个子区间里面的最大值和最小值的差&#xff0c;我们一开始想的必然是纯暴力呀&#xff0c;但是一看这数据&#…

主流硬派SUV齐聚尼三锅,方程豹豹5成功冲顶

随着汽车的飞速普及&#xff0c;越来越多的车主都喜欢上了越野。 而在浩瀚无垠的沙漠腹地&#xff0c;尼三锅以其独特的地理形态&#xff0c;成为了无数越野爱好者心中的圣地与试炼场。 近日&#xff0c;众多汽车博主携自己的爱车普拉多、方程豹豹5、牧马人、坦克400、坦克700、…

图书馆座位管理系统 /图书馆座位预约系统/图书馆管理系统的设计与实现

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&a…

excel批量新建多个同类型的表格

背景引入 比如&#xff0c;一个企业有多个部门&#xff0c;现在需要按照某一个excel表模板收集各个部门的信息&#xff0c;需要创建数十个同类型表格&#xff0c;且标题要包含部门名称。 1.修改模板表格标题 在一个文件夹下面放入需要发放给各个部门的表格&#xff0c;将标题…

轨迹优化 | 基于ESDF的共轭梯度优化算法(附ROS C++/Python仿真)

目录 0 专栏介绍1 数值优化&#xff1a;共轭梯度法2 基于共轭梯度法的轨迹优化2.1 障碍约束函数2.2 曲率约束函数2.3 平滑约束函数 3 算法仿真3.1 ROS C实现3.2 Python实现 0 专栏介绍 &#x1f525;课程设计、毕业设计、创新竞赛、学术研究必备&#xff01;本专栏涉及更高阶的…

Chapter17 表面着色器——Shader入门精要学习

Chapter17 表面着色器 一、编译指令1.表面函数2.光照函数3.其他可选参数 二、两个结构体1.Input 结构体&#xff1a;数据来源2.SurfaceOutput 三、Unity背后做了什么四、表面着色器的缺点 一、编译指令 作用&#xff1a;指明该表面着色器的 表面函数 和 光照函数&#xff0c;并…

LeetCode 58.最后一个单词的长度 C++

LeetCode 58.最后一个单词的长度 C 思路&#x1f914;&#xff1a; 先解决当最后字符为空格的情况&#xff0c;如果最后字符为空格下标就往后移动&#xff0c;直到不为空格才停止&#xff0c;然后用rfind查询空格找到的就是最后一个单词的起始位置&#xff0c;最后相减就是单词…

前台文本直接取数据库值doFieldSQL插入SQL

实现功能&#xff1a;根据选择的车间主任带出角色。 实现步骤&#xff1a;OA的“字段联动”功能下拉选项带不出表“hrmrolemembers”&#xff0c;所以采用此方法。 doFieldSQL("select roleid from HrmResource as a inner join hrmrolemembers as b on a.id b.resource…

AGI 之 【Hugging Face】 的【从零训练Transformer模型】之二 [ 从零训练一个模型 ] 的简单整理

AGI 之 【Hugging Face】 的【从零训练Transformer模型】之二 [ 从零训练一个模型 ] 的简单整理 目录 AGI 之 【Hugging Face】 的【从零训练Transformer模型】之二 [ 从零训练一个模型 ] 的简单整理 一、简单介绍 二、Transformer 1、模型架构 2、应用场景 3、Hugging …

Flink架构底层原理详解:案例解析(43天)

系列文章目录 一、Flink架构&#xff08;掌握&#xff09; 二、Flink代码案例&#xff08;掌握&#xff09; 三、UDF&#xff08;熟悉&#xff09; 四、Flink常见面试题整理 文章目录 系列文章目录前言一、Flink架构&#xff08;掌握&#xff09;1、系统架构1.1 通信&#xff…

海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)

海康威视工业相机SDKPythonPyQt开发数据采集系统&#xff08;支持软件触发、编码器触发&#xff09; pythonpyqt开发海康相机数据采集系统 1 开发软件功能&#xff1a; 支持搜索相机&#xff1a;Gige相机设备和USB相机设备支持两种触发模式&#xff1a;软件触发和编码器触发支…

Docker、containerd、CRI-O 和 runc 之间的区别

容器与 Docker 这个名称并不紧密相关。你可以使用其他工具来运行容器 您可以使用 Docker 或一堆非Docker 的其他工具来运行容器。docker只是众多选项之一&#xff0c;Docker&#xff08;公司&#xff09;在生态系统中创建了一些很棒的工具&#xff0c;但不是全部。 容器方面有…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十三章 驱动模块传参

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法(sci论文图片清晰度)

【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法 内容一&#xff1a;ppt把当前页输出为图片&#xff1a;内容二&#xff1a;ppt导出图片模糊的解决方法&#xff1a;方法&#xff1a;步骤1&#xff1a;打开注册表编辑器步骤2&#xff1a;修改注册表&#xff1a; 该文…

使用jacob文字生成语音文件时遇到的问题及解决方案

使用jacob文字生成语音文件时 出现如下错误 java.lang.UnsatisfiedLinkError: no jacob-1.18-x64 in java.library.path错误表明Java虚拟机无法在其指定的java.library.path路径中找到名为jacob-1.18-x64的本地库文件。这个错误通常发生在尝试通过JNI或者JNA调用本地库时&…

算法学习笔记(Hello算法)—— 初识算法

1、相关链接 Hello算法&#xff1a;Hello 算法 (hello-algo.com) 2、算法是什么 2.1 算法定义 算法是一系列明确、有限且有效的步骤或指令的集合&#xff0c;用于解决特定问题或执行特定任务。 算法具有以下基本特征&#xff1a; 输入&#xff1a;算法至少有一个输入&…