【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

这篇具有很好参考价值的文章主要介绍了【C++入门必备知识:|引用| +|auto关键字| + |范围for|】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


在这里插入图片描述
【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

①.引用

Ⅰ.引用概念

引用不是新定义一个变量,而是给已经存在的变量取别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存区间。

比如水浒传里的李逵
小名叫铁牛,江湖人称黑旋风。这些都是他,只不过名字不同。 【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

Ⅱ.引用使用

类型& 引用变量名=引用实体

int main()
{
	int a = 10;
	int& ra = a;//给变量a取别名为ra
	int& rra = ra;//又给变量rra取别名为rra ,其实本质上都是a
	printf("%p\n", a);
	printf("%p\n", ra);
	printf("%p\n", rra);
}

【C++入门必备知识:|引用| +|auto关键字| + |范围for|】
【C++入门必备知识:|引用| +|auto关键字| + |范围for|】
从语法上我们看,就是给a取别名,并没有开辟空间。

注意:引用类型必须和引用实体是同种类型的。

Ⅲ.引用特性

1.一个变量可以有多个引用
2.引用在定义时必须初始化
3.引用一旦引用一个实体,再不能引用其他实体。 C++的引用不能改指向

1.一个变量可以有多个引用

就像李逵可以有多个别名一样。

int main()
{
	int a = 10;
	int& ra = a;
	int& rra = a;
	printf("%p\n", a);
	printf("%p\n", ra);
	printf("%p\n", rra);//它们的本质都是a
}

2.引用在定义时必须初始化
你要取别名,倒是说给谁取别名呀,你不说谁知道这个名字是谁的。

int main()
{
	int a=10;
	int&ra;//这样是不可以的,编译器会报错。
	//引用在定义时必须要初始化。
}

3.引用一旦引用一个实体,再不能引用其他实体。

int main()
{
	int a = 10;
	int&ra=a;
	int b=20;
	ra=b;//这里ra=b是将b的值赋给ra,而不是让ra变成b的别名。C++的引用不能改指向。ra仍然是a的别名
}

注意:
同一个域不能同名引用,不能域里可以同名,但在不同域里是可以同名的,是可以区分的。

Ⅳ.使用场景

引用第一使用场景:

1.做函数参数

void Swap(int*a, int* b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
//引用
void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
意义:

1.引用做参数–【输出型参数】
什么叫输出型参数呢?就是传进去使用还要带出来
这里利用形参就是实参的变名,改变形参就改变了实参
不同于传指针参数。
2.引用做参数—【提高效率】
对于/大对象/深度拷贝的数据是可以提高效率的。
因为是引用不开空间

#include <time.h>
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{
	A a;
	// 以值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分别计算两个函数运行结束后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
	TestRefAndValue();
}

【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

虽然指针也能做到上面的功能。
但是引用更方便。

引用第二大使用场景:

2.做函数返回值

int fun()//返回值就用int来接受
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	int ret = fun();//最后将返回值返回ret
	printf("%d ", ret);
}

【C++入门必备知识:|引用| +|auto关键字| + |范围for|】
没有毛病吧。根据函数栈帧的创建和销毁我们知道,在函数调用完时,函数栈帧会销毁,而这个返回值将会保存在一个寄存器中,相当于一个临时变量。操作系统会开辟一个临时变量来保存这个返回值,如何再将临时变量赋给ret。最后ret得到了函数的返回值。
【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

而这个过程需要需要创建临时变量,那么就需要开销。
其实只要看函数返回值,只要是传值返回的
不管怎么样编译器都会生成临时变量。
但是当用引用作为返回值时,最后就不需要创建临时变量了。
也就是传引用返回就不会生成临时变量。

int& fun()//用引用作为返回值
{
	static int n = 0;
	n++;
	return n;//最后函数返回的是n的别名,不需要创建临时变量保存,因为别名不需要开辟空间
}
int main()
{
	int ret = fun();//fun的返回值就是n的别名,别名不需要开辟空间,中间没有临时变量,直接就赋值会ret了。
	printf("%d ", ret);
}

那我们是不是以后函数返回值都用引用呢?
当然不行了,上面的案例也是特殊的,因为static修饰的变量在静态区,当函数栈帧销毁时,并不影响变量a,所有当引用取别名时可以找到它。

【C++入门必备知识:|引用| +|auto关键字| + |范围for|】
所以这里打印的ret的值是不确定的。
如果fun函数结束,栈帧销毁,没有清理栈帧,那么ret的结果是侥幸是正确的。
如果fun函数结束,栈帧销毁,清理栈帧,那么ret的结果是随机值。

意义:

1.减少拷贝,提高效率
但要记住并不是任何地方都可以引用返回值
当函数 返回值为局部变量时,这种是不行的。
因为返回局部对象引用很危险。最后的结果取决于函数调用完栈帧销毁不销毁

当返回值为静态变量时不危险,函数调用结束,函数栈帧销毁不影响静态变量的存在。
不会有随机值的问题。静态变量还在,那么取别名就合法。

传引用返回–没有创建临时变量,只是取别名。别名==变量。
返回变量的别名,没有临时变量,也没有拷贝。所以可以提高效率。
传值返回–需要开辟临时变量-再拷贝回去。

引用返回门槛:不能随意引用传参返回

1.基本任何场景都可以用引用传参
2.但要谨慎用引用返回,出了函数作用域,对象不在, 就不能用引用返回,还在就能用。

2.查改返回值
引用做返回值,可以修改返回值,和获取返回值。
因为返回值就是这个要修改或者要返回变量的别名,对别名修改或者获取。就是修改该变量。

Ⅵ.常引用

1.引用过程中,权限不能放大

int main()
{
	1.//引用过程中,权限不能放大
	const int a = 0;//表示a不能修改
	int& b = a;//不能通过引用别名来修改a,这种方法是错误的。

    2.//引用过程中,权限是可以平移或缩小的。
    int x=0;
    int &y=x;
    const int&z=x;
    3.//对z这个别名进行修饰,也就是z这个别名权限缩小了。但其他别名的权限还是正常的。 
    ++x;
}

2.不能引用带有常性的变量。

double a=1.2;
int b=a;
//其实在类型转化会产生临时变量,产生一个int 类型的临时变量

int&bb=a;
//这个也是一样,a是double类型,别名bb是int类型,发生类型转化,然后产生一个临时变量存在着dd,这个dd就具有常性了,因为临时变量具有常性。

而带有常性的变量就不能使用引用了。

Ⅶ.引用与指针区别

1.引用在语法概念上就是一个别名,没有开辟空间,和其引用的实体共用同一块空间。
2.但在底层实现上,引用其实是有空间的,因为引用是按照指针方式来实现的。
不同点:

-1.引用概念上是定义一个变量的别名,指针是存储一个变量的的地址
-2.引用在定义时,需要初始化,指针没有要求。
-3.引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在如何时候指向任何一个同类型实体。
-4.没有NULL引用概念,但有NULL指针

-5.有多级指针,但是没有多级引用。
-6.引用比指针使用起来更安全。
-8.在sizeof下含义不相同:在引用用计算的就是别名类型的大小,而指针是固定的,始终是地址空间所占字节个数。(32位下4字节)
-9.引用自加表示引用的实体加1,而指针自加,表示指针向后偏移一个类型的大小。

②.auto关键字

在C++11中,auto的作用是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

    int a = 0;
	auto b = a;//auto可以自动识别a的类型
	auto c = 's';//自动识别字符‘s’的类型

还有要注意在使用auto时定义变量时,必须要对其进行初始化

	int a=0;
	auto b;//使用auto却不初始的编译器会报错
	auto c ;//这样不初始化是不对的。

【注意】

在使用auto定义变量时,必须对其初始化,在编译阶段编译器需要根据初始化表达式来推到auto的实际类型,因此auto并非是一种”类型“声明,而是一个类型声明时的”占位符“,编译器在编译期会将auto替换为变量实际的类型。

1.使用规则

1.auto与指针和引用结合使用

用auto声明指针类型时,用auto和auto没有区别。*
但用auto声明引用类型时,必须加上&。

	int a=0;
	auto pa=&a;//auto与指针和引用结合使用
	auto* pa = &a;
	auto&ra=a;

2.在同一行定义多个变量。

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

	auto a = 1, b = 2;
	auto c = 3, d = 4.0;//这样就不对了,auto一行定义多个变量虽然可以,但是要求这一行变量类型都相同才可以。d的类型与c不同

3.auto不能作为函数的参数。

void fun(auto a)//这种写法是不允许的
{}

4.auto不能直接用来声明数组

 int a[]={6,5,4};
 auto c={9,8,7};//这种写法是不允许的。

③.基于范围的for循环

如果我们想要打印一个数组,就必须遍历这个数组,而遍历这个数组就得需要知道这个数组的大小是多少。

int main()
{
	int a[] = { 9,8,7,6,5,4,3,2,1 };
	int n = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < n; i++)
	{
		cout << a[i] << endl;
	}
	return 0;
}

而对于我们来说,这种写法有时会出现很多问题,比如数组大小计算错误,或者循环条件写错,所以C++11中引入了基于范围的for循环。

for循环后面的括号由冒号" :"分为两个部分,第一部分是范围内用于迭代的变量类型,第二部分则表示被迭代的范围。

for(auto__:__);

int arr[] = { 9,8,7,5,6,3,2,4 };
	for (auto e : arr)
	{
	cout << e << endl;	
	}

1.使用规则

1.使用于数组
2.依次取数组中的数据赋值给e(这里的e可以随便写其他,没有规定,可以是x,可以是y)
3.自动迭代,自动判断结束。
4.与普通循环类似,可以用continue来结束本次循环,也可以用break跳出整个循环。

还有如果想要利用范围for改变数组内容该任何改变呢?
如果想让数组内数据都变成2倍这样写可以吗?

int arr[] = { 9,8,7,5,6,3,2,4 };
	for (auto x : arr)
	{
		x * 2;
	}

要注意,这里只是将arr数组内容依次赋值给x,但x改变能改变数组内的数据吗?当然不能了。
所以我们想要改动数组内的数据,只要传引用即可,每次改变的是数组数据的别名。改变别名就改变了数组数据。

int arr[] = { 9,8,7,5,6,3,2,4 };
	for (auto& x : arr)
	{
		x * 2;
	}

【注意】
for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供
begin和end的方法,begin和end就是for循环迭代的范围。文章来源地址https://www.toymoban.com/news/detail-420862.html

到了这里,关于【C++入门必备知识:|引用| +|auto关键字| + |范围for|】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】引用、内联函数、auto关键字等

    前言:在前面我们讲解了C++入门基础的一些学习例如命名空间、缺省参数、函数重载等。今天我们将进一步的学习,跟着博主的脚步再次往前迈一步吧。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C++学习 👈 💯代码仓库:卫卫周大胖的学习日记💫 💪关注博

    2024年02月20日
    浏览(68)
  • 【C++初阶(三)】引用&内联函数&auto关键字

    目录  前言  1. 引用   1.1 引用的概念   1.2 引用的特性  1.3 引用的权限  1.4 引用的使用  1.5 引用与指针的区别 2. 内联函数 2.1  什么是内联函数 2.2  内联函数的特性  3. auto  3.1 auto简介  3.2 auto使用规则  3.3 auto不能使用的场景 4.  基于范围的for循环  4.1 范围for使用

    2024年02月08日
    浏览(61)
  • 【C++】:函数重载,引用,内联函数,auto关键字,基于范围的for循环,nullptr关键字

    在C语言中,同名函数是不能出现在同一作用域的,但是在C++中却可以,但是要满足函数重载的规则。 那什么是函数重载呢?它的规则是什么呢? 函数重载 :是函数的一种特殊情况,C++允许在 同一作用域 中声明几个功能类似的 同名函数 ,这些同名函数的 形参列表(参数个数

    2024年04月26日
    浏览(55)
  • 【C++初阶】引用&内联函数&auto关键字&范围for循环&nullptr

    ========================================================================= 个人主页还有更多系列专栏: 小白不是程序媛 我的小仓库: Gitee C++系列专栏: C++头疼记 ========================================================================= 目录 前言 引用 概念 引用的特点 常引用  引用的使用场景 做参数  做返

    2024年02月08日
    浏览(47)
  • 【C++】C++入门第二课(函数重载 | 引用 | 内联函数 | auto关键字 | 指针空值nullptr)

    目录 前言 函数重载 概念 重载函数的条件 C++支持重载函数的原理--名字修饰 引用 概念 特性 常引用(const引用) 使用场景 传值,传引用效率比较 引用和指针的区别 内联函数 概念 特性 auto(C++11) auto简介 auto的使用规则 指针空值nullptr(C++11) C++98中的指针空值 结语

    2024年04月15日
    浏览(48)
  • C++ 入门篇(八) auto关键字

    目录 一、auto简介 二、auto的使用场景 三、注意事项 拓、范围for  【总结】 【源代码】  1.是什么?         auto是一个提示符,提示编译器根据变量的值来推导变量的类型。         在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,C++11中,

    2024年02月08日
    浏览(47)
  • 【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr

      目录 1. 引用 1.1 引用概念 1.2 引用特性 1.3 常引用 1.4 使用场景 1.5 传值、传引用效率比较 1.6 引用和指针的区别 2. 内联函数 2.1 概念 2.2 特性 3.auto(C++11) 3.1 类型别名思考 3.2 auto简介 3.3 auto的使用细则 3.4 auto不能推导的场景 4. 基于范围的for循环(C++11) 4.1 

    2024年02月15日
    浏览(77)
  • 【C++】C++入门 auto关键字详解(C++11)

    前言 C语言中包括了auto,它可用于定义局部变量。但自从所有的非全局变量的缺省值假定为auto以来,auto就几乎很少使用了。 在C或者以前C++中,auto基本上可以被无视. 但是在C++11中auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器, a

    2024年02月08日
    浏览(49)
  • 【C++入门】auto关键字(C++11) + 指针空值nullptr(C++11)

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。 随

    2024年02月04日
    浏览(83)
  • C++ : auto关键字

            前提引入:                 1.类型名,在绝大多数编程时,我们都会引入类型来定义一个我们需要的数据。                 类型众多,偶尔我们会遇见一串类型名,使用起来无比复杂。存在拼写错误,含义不明确导致出错的问题。                 列如:      

    2023年04月11日
    浏览(97)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包