网站建设氺首选金手指13自己想学做博客网站

张小明 2025/12/30 14:25:01
网站建设氺首选金手指13,自己想学做博客网站,常用微信小程序api,seo关键词排名优化怎样收费#x1f525;小叶-duck#xff1a;个人主页 ❄️个人专栏#xff1a;《Data-Structure-Learning》 《C入门到进阶自我学习过程记录》 ✨未择之路#xff0c;不须回头 已择之路#xff0c;纵是荆棘遍野#xff0c;亦作花海遨游 目录 前言 一、引用 1、引用的概念…小叶-duck个人主页❄️个人专栏《Data-Structure-Learning》《C入门到进阶自我学习过程记录》✨未择之路不须回头已择之路纵是荆棘遍野亦作花海遨游目录前言一、引用1、引用的概念和定义二、引用的特性三、引用的使用四、const引用1、const对象的引用2、普通对象的引用2.1 表达式的引用2.2 类型转换的引用五、指针和引用的关系六、nullptr结束语前言在上一篇文章C入门基础指南输入输出、缺省参数与函数重载我们主要是讲解了C入门基础中的输入输出、缺省参数以及函数重载今天我们会结束C的入门基础将最后剩下的入门基础知识全部讲解完。一、引用1、引用的概念和定义概念引用不是新定义一个变量而是给已存在变量取了一个别名编译器不会为引用变量开辟内存空间它和它引用的变量共用同一块内存空间。定义类型 引用别名引用对象;C中为了避免引入太多的运算符会复用C语言的一些符号比如前面的 和 这里引用也和取地址使用了同一个符号 大家注意使用方法角度区分就可以。//Test.cpp #includeiostream using namespace std; int main() { int a 0; //引用b和c都是a的别名 int b a; int c a; //也可以给别名b取别名d相当于还是a的别名 int d b; d; // 这里取地址我们会发现是一样的这也印证了a和其引用的变量共用同一块内存空间 cout a endl; cout b endl; cout c endl; cout d endl; cout a endl; cout b endl; cout c endl; cout d endl; return 0; }并且我们会发现我们对 d 进行 d 时a、b、c、d均变成了1这不由让我们想到了在C语言中学习到的一个比较难以理解的东西地址传参。二、引用的特性引用在定义时必须初始化//Test.cpp int main() { int a 10; int ra; return 0; }一个变量可以有多个引用这个特性在上面已经提到过了相当于就是一个变量可以有多个别名。引用一旦引用一个实体再不能引用其他实体//Test.cpp int main() { int a 10; int b a; int c 20; // 这里并非让b引用c因为 C 引用不能改变指向 // 这里是一个赋值 b c; cout a endl; cout b endl; cout c endl; //a与b的地址仍然是相同的而c是另一个变量 return 0; }三、引用的使用引用传参跟指针传参功能是非常类似的只是引用传参会相对更方便一些之前第一次接触学习地址这个东西的时候想必大家或多或少都有点难以理解甚至有时分不清到底什么时候用值传参什么时候用地址传参归根结底我们就是要搞清楚所用的变量需不需要进行修改如果需要进行修改则就要传其地址。但是引用这个东西相当于直接和地址联系在一起由于别名和变量的地址自动就是相同的所以在一些函数调用中我们如果想要变量进行修改则无需再利用地址传参了引用就可以解决void Swap(int rx, int ry) //引用传参rx相当于就是变量x的别名ry相当于就是变量y的别名 { int tmp rx; rx ry; ry tmp; } int main() { int x 0, y 1; cout x y endl; Swap(x, y); cout x y endl; return 0; }由于形参 rx 和 ry 分别就是实参 x 和 y 的别名而两者本来地址就是相同的所以在函数内部对形参进行修改外部的实参也会发生变化。说到底引用传参跟指针传参功能是非常类似的只是引用传参会相对更方便一些。引用在实践中第一主要是于引用传参中能减少拷贝提高效率不仅在函数调用中可以使用引用之前我们所学的数据结构中对于栈的相关方法实现前面我们都是利用指针来实现代码引用也能解决//Stack.h #includeiostream #includeassert.h #includestdlib.h using namespace std; typedef int STDataType; typedef struct Stack { STDataType* arr; int top; int capacity; }ST; //栈的初始化 void STInit(ST rs, int n 4); //可以将缺省参数和引用同时使用将大大提高代码效率 //入栈 void STPush(ST rs, STDataType x); //Stack.cpp #include Stack.h //栈的初始化 void STInit(ST rs, int n) { rs.arr (STDataType*)malloc(sizeof(STDataType) * n); rs.top 0; rs.capacity n; } //入栈 void STPush(ST rs, STDataType x) { assert(rs); if (rs.capacity rs.top) //栈满了 { int newcapacity rs.capacity 0 ? 4 : 2 * rs.capacity; STDataType* tmp (STDataType*)realloc(rs.arr, sizeof(STDataType) * newcapacity); if (tmp NULL) { perror(realloc fail); return; } rs.capacity newcapacity; rs.arr tmp; } rs.arr[rs.top] x; rs.top; } //Test.cpp #include Stack.h int main() { //调用全局的 ST st1; STInit(st1); STPush(st1, 1); STPush(st1, 2); return 0; }引用在实践中第二主要是于引用做返回值中能改变引用对象时同时改变被引用对象在之前我们学习栈的一个方法出栈时我们只是知道这个函数能让我们得到栈顶的数据但是当我们想要对栈顶数据修改时我们其实并不能直接通过这个函数来实现//Stack.h //出栈 int STTop(ST rs); //Stack.cpp int STTop(ST rs) { assert(rs.top 0); return rs.arr[rs.top - 1]; } //Test.cpp #include Stack.h int main() { //调用全局的 ST st1; STInit(st1); STPush(st1, 1); STPush(st1, 2); STTop(st1) 3; return 0; }当我们函数调用后得到的值进行修改则会报这样的错误原因是当这个函数执行完代码 return 返回时会有一个类似临时变量的东西先把返回值存起来再通过这个临时变量把数据作为 STTop(st1) 这个表达式的返回值而这个临时变量有一个特性就是临时变量具有常性。可以理解为类似我们C语言中学习到的一个关键字const由于具有常性所以是不能对其进行修改的。如果我们想要对栈顶数据进行修改则需要再定义一个新函数来实现这样肯定相对麻烦点。所以此时引用做返回值就能解决这个问题由于是引用做返回值则函数执行完后传的是返回值的别名相当于就是没有了临时变量这个东西也就使其不具有常性了这也就是说为什么引用做返回值能改变引用对象时同时改变被引用对象引用对象就是函数的返回值而被引用对象就是栈。//Stack.h //出栈 int STTop(ST rs); //Stack.cpp int STTop(ST rs) { assert(rs.top 0); return rs.arr[rs.top - 1]; } //Test.cpp #include Stack.h int main() { //调用全局的 ST st1; STInit(st1); STPush(st1, 1); STPush(st1, 2); cout STTop(st1) endl; STTop(st1) 3; //如果不是引用做返回值则不能对其进行修改值因为表达式是不可修改的左值 //引用做返回值则可以直接对其进行修改 cout STTop(st1) endl; return 0; }引用返回值的场景相对比较复杂我们在这里简单讲了一下场景还有一些内容后续类和对象章节中会继续深入讲解。引用和指针在实践中相辅相成功能有重叠性但是各有特点互相不可替代。C的引用跟其他语言的引用(如Java)是有很大的区别的除了用法最大的点C引用定义后不能改变指向Java的引用可以改变指向。四、const引用1、const对象的引用可以引用一个 const 对象但是必须用 const 引用。const 引用也可以引用普通对象因为对象的访问权限在引用过程中可以缩小但是不能放大。在C语言的学习中我们就接触了这个关键字 constconst可以使一个变量只可读不可写也就是不可被修改。那权限放大和权限缩小又是什么意思呢//Test.cpp int main() { const int a 10; int ra a; return 0; }这个报错的原因说简单点就是权限放大首先我们知道引用对象和被引用对象两者没有区别只是引用对象是被引用对象的别名罢了所以两者其实是平起平坐的。而上述代码中a 变量是只可读不可写的但是 ra 作为 变量 a 的别名却没有 const 的约束也就是说 ra 是既可以读也可以写的这样不就出现问题了吗本来 ra 只是 a 的一个别名却把权限从只可读不可写变成了既可以读也可以写这就叫做权限放大。而如果想要让别名 ra 和 a 平起平坐就需要利用const引用了const int ra a;//Test.cpp int main() { int b 20; const int rb b; b 10; rb 10; return 0; }当一个变量没有 const 约束也就是说既可以读也可以写时而被 const 引用了也就使其别名 rb 变成了只可读不可写这就叫做权限缩小。但需要注意的是由上述代码我们发现只有引用对象 rb 被限制为只可读不可写但被引用对象 b仍然可以进行修改。2、普通对象的引用2.1 表达式的引用需要注意的是类似 int rb a*3; 这样一些场景下也就是表达式时a * 3 的结果会先保存在一个临时对象中而C规定临时对象具有常性所以这里就触发了权限放大必须要用const引用才可以。错误示范//Test.cpp int main() { int a 10; int r 30; //30为常量也具有常性引用时如果不用const也相当于权限放大所以需要const引用 int rb a * 3; //a * 3 为表达式表达式的引用会存在临时对象C规定临时对象为常性所以也需要const引用 return 0; }正确示范//Test.cpp int main() { int a 10; const int r 30; const int rb a * 3; return 0; }2.2 类型转换的引用和上面表达式的引用一样类似 double d 12.34; int rd d; 这样一些场景下在类型转换中也会产生临时对象存储中间值临时对象具有常性所以这里也触发了权限放大必须要用const引用才可以。错误示范//Test.cpp int main() { double d 12.34; int rd d; return 0; }正确示范//Test.cpp int main() { double d 12.34; const int rd d; return 0; }并且如果存在临时对象则rd 为临时对象的别名而并非 d 的别名因为我们知道引用的两者只是名字上的不同类型和地址都是完全一致的而d 和 rd 本身的类型就不同所以 rd 不是 d 的别名并且通过地址打印我们也可以证明//Test.cpp int main() { double d 12.34; const int rd d; cout d endl; cout rd endl; return 0; }所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象C中把这个未命名对象叫做临时对象。所以到现在能存在临时对象的情况我们知道了三种(1)引用做函数的返回值(2)表达式的引用(3)类型转换的引用。五、指针和引用的关系C中指针和引用就像两个性格迥异的亲兄弟指针是哥哥引用是弟弟在实践中他们相辅相成功能有重叠性但是各有自己的特点互相不可替代。语法概念上引用是一个变量的取别名不开空间指针是存储一个变量地址要开空间。引用在定义时必须初始化指针建议初始化但是语法上不是必须的。引用在初始化时引用一个对象后就不能再引用其他对象而指针可以在不断地改变指向对象。引用可以直接访问指向对象指针需要解引用才是访问指向对象。sizeof 中含义不同引用结果为引用类型的大小但指针始终是地址空间所占字节个数(32位平台下占4个字节64位下是8个字节)指针很容易出现空指针和野指针的问题引用很少出现引用使用起来相对更安全一些。六、nullptrNULL实际是一个宏在传统的C头文件(stddef.h)中可以看到如下代码#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif在C中NULL被定义为字面常量0而在C中被定义为无类型指针 (void*) 的常量。不论采取何种定义在使用空值的指针时都不可避免的会遇到一些麻烦本想通过 f(NULL) 调用指针版本的 f(int*) 函数但是由于NULL被定义成0变成了调用了 f(int x) 因此与程序的初衷相悖。而只有将 NULL 类型强转成 int* 才可实现。void f(int x) { cout f(int x) endl; } void f(int* ptr) { cout f(int* ptr) endl; } int main() { f(0); // 本想通过 f(NULL) 调用指针版本的f(int*)函数但是由于在C中NULL被定义成0调用了f(int x)因此与程序的初衷相悖 f(NULL); f((int*)NULL); //f((void*)NULL); //编译报错error C2665: “f”: 2 个重载中没有一个可以转换所有参数类型 return 0; }而到了C11后就引入了nullptrnullptr 是一个特殊的关键字nullptr 是一种特殊类型的字面量它可以转换成任意其他类型的指针类型。使用 nullptr 定义空指针可以避免类型转换的问题因为 nullptr 只能被隐式地转换为指针类型而不能被转换为整数类型。void f(int x) { cout f(int x) endl; } void f(int* ptr) { cout f(int* ptr) endl; } int main() { f(0); f(NULL); f(nullptr); return 0; }就是说以后C学习中如果我们需要用到空指针则不再是用 NULL 而是用 nullptr 了。结束语到此C的入门基础知识的讲解就完成了内容量还是不少的主要还是为C后续的学习做铺垫。希望这篇文章对大家学习C有所帮助
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

微信网站建设平台自助建站系统软件

nroff/troff 与 ISO 8859-1 字符集使用指南 1. nroff/troff 概述 nroff 和 troff 是用于文本格式化和排版的工具,在 Unix 系统中广泛用于编写手册页。在不同的 Unix 系统中,相关的宏文件位置和文件名可能有所不同,通常位于 local/share/groff/x.y.z/tmac/name.tmac 。 …

张小明 2025/12/30 14:24:28 网站建设

工程建设动态管理网站wordpress 技术 主题

深入了解X Window System配置 1. 引言 现代主流桌面操作系统大多提供图形用户界面(GUI),在Linux系统中,主要的GUI就是X Window System(简称X)。X的配置难度不一,多数发行版在安装时会提供自动检测和简易配置选项,不过当这些选项无法满足需求时,就需要深入研究X配置文…

张小明 2025/12/30 14:23:54 网站建设

怎么搞到网站如何免费简单建一个网站

写在开头 在开始之前,我想说的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而…

张小明 2025/12/30 14:23:20 网站建设

北京注册建设公司网站企业网站建设维护合同书

第一章:金融合规Agent审计日志的核心价值在金融行业,合规性是系统设计与运维的首要前提。审计日志作为合规Agent的核心组件,不仅记录系统操作的全过程,还为监管审查、异常检测和责任追溯提供关键数据支撑。其核心价值体现在可追溯…

张小明 2025/12/30 14:22:46 网站建设

大型移动网站建设郑州区块链数字钱包网站开发过程

EmotiVoice 能否识别文本情感并自动匹配语音情绪? 在虚拟主播的直播中,一句平淡的“我很难过”听起来却像在念菜谱;在智能助手中,“恭喜你!”被读得毫无波澜——这些场景暴露了传统语音合成系统最致命的短板&#xff1…

张小明 2025/12/30 14:22:11 网站建设

做网站的宽度为多少钱长沙功能网站建设

终极ncm文件转换方案:ncmppGui完整使用指南 【免费下载链接】ncmppGui 一个使用C编写的转换ncm文件的GUI工具 项目地址: https://gitcode.com/gh_mirrors/nc/ncmppGui 你是否曾经遇到过下载的网易云音乐文件在其他播放器中无法播放的困扰?ncm格式…

张小明 2025/12/30 14:21:37 网站建设