【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr

这篇具有很好参考价值的文章主要介绍了【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 范围for的语法

4.2 范围for的使用条件

5. 指针空值nullptr(C++11)

5.1 C++98中的指针空值


❀❀❀没有坚持的努力,本质上并没有多大的意义。


1. 引用

1.1 引用概念

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

 类型& 引用变量名(对象名) = 引用实体(注意:引用类型必须和引用实体同种类型

【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr,C++,笔记,c++,开发语言

b叫做a的引用,b也可以叫做a的别名(abcd四个,只要有一个发生变化,其余都发生变化)

应用1

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

数据进行交换,可以不用传指针,可以用引用

应用2

#include <iostream>

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}LTNode;

void LTPushBack_C(LTNode** pphead, int x)
{
	//C语言,单链表尾插需要传结构体的二级指针,因为需要改变首部地址
}

void LTPushBack_CPP(LTNode*& phead, int x)
{
	//C++中,用引用,仅仅需要传结构体地址
}

int main()
{
	LTNode* plist = NULL;
	//初始化
	LTPushBack_C(&plist, 1);
	LTPushBack_CPP(plist, 1);
	return 0;
}

也可以引用指针类型的 

注意:

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}LTNode,*PLTNode;

void LTPushBack_CPP(LTNode*& phead, int x)
{
	//C++中,用引用,仅仅需要传结构体地址
}
//这两个等同
void LTPushBack_CPP(PLTNode& phead, int x)
{
	//C++中,用引用,仅仅需要传结构体地址
}

1.2 引用特性

代码展示:

#include <iostream>

int main()
{

	int a = 10;
	int& b = a;
	int& c = a;
	int& d = b;
	//一个变量可以多次引用
	int& e;//代码运行到这里会报错,因为引用在定义时必须初始化
	int m = 2;
	b = m;//b在前面已经引用了a,在这里并不是成为m的别名,而是把m的值赋值给b,然后此时abcd的值都是2
	return 0;
}
1. 引用在 定义时必须初始化
2. 一个变量可以有多个引用
3. 引用一旦引用一个实体,再不能引用其他实体

1.3 常引用

const修饰的变量,只能读不能写(这里的权限,指的是读和写)

#include <iostream>

int main()
{
	int a = 0;
	int& b = a;//权限不变

	const int c = 2;
	int& d = c;//这里是错误的,权限不能被放大

	const int x = 3;
	const int& y = x;//这里是可以的,权限不变

	int m = 6;
	const int& n = m;//这里是可以的,权限缩小
	return 0;
}

取别名原则:对于引用类型,权限只能缩小,不能放大

临时变量具有常性

#include <iostream>

int main()
{
	int a = 10;
	int& b = a;

	const int& c = 20;//常量也可以取别名

	double d = 15.3;
	int f = d;//在这里,相当于f把自己的整数部分给一个临时变量,临时变量把值赋给f(临时变量具有常性)
	const int& e = d;//这里的e不是d的引用,而是临时变量的引用
	return 0;
}

【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr,C++,笔记,c++,开发语言

 

1.4 使用场景

(1)做参数

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

可以不用传指针

(2)做返回值

代码1展示:(传值返回)

#include <iostream>

int Count()
{
	int n = 0;
	n++;
	return n;
}//n出了这个函数就被销毁了,所以是赋值给临时变量的
int main()
{
	int ret = Count();

	return 0;
}

函数返回过程,把返回的值n给一个临时变量,临时变量的类型就是函数类型(上述代码的int),临时变量再把值赋给主函数的ret。(临时变量即有一个拷贝)

代码2展示:(传引用拷贝)

#include <iostream>
int& Count()
{
	static int n = 0;//static不能去掉,如果去掉,就会涉及出现越界问题(因为空间被系统回收)
	n++;
	return n;
}//返回int&,说明有一个临时引用是int&类型,临时引用是n的别名
int main()
{
	int& ret = Count();//ret是临时引用的别名,
	return 0;
}

没有拷贝,效率高

如果函数返回时,出了函数作用域,如果返回对象还在 ( 还没还给系统 ) ,则可以使用引用返回, 如果已经还给系统了,则必须使用传值返回。(否则会出现越界问题)

注意:

#include <iostream>
int Count()
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	const int& ret = Count();//因为是临时变量的别名,临时变量具有常性
	return 0;
}

1.5 传值、传引用效率比较

作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回, 而是 传递实参或者返回变量的一份 临时的拷贝 ,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。(传地址和传引用是差不多的)
传值和传引用在作为传参以及返回值类型上效率相差很大

1.6 引用和指针的区别

引用和指针的不同点 :
1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
2. 引用 在定义时 必须初始化 ,指针没有要求
3. 引用 在初始化时引用一个实体后,就 不能再引用其他实体 ,而指针可以在任何时候指向任何一个同类型实体
4. 没有 NULL 引用 ,但有 NULL 指针
5. sizeof 中含义不同 引用 结果为 引用类型的大小 ,但 指针 始终是 地址空间所占字节个数 (32 位平台下占4个字节 )
6. 引用自加即引用的实体增加 1 ,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用
8. 访问实体方式不同, 指针需要显式解引用,引用编译器自己处理
9. 引用比指针使用起来相对更安全
语法的角度:引用是一个别名,没有额外开空间,指针存储的是地址,需要开一个4/8字节的空间;但是从底层的角度,是一样的方式实现的(汇编代码是一致的)

2. 内联函数

2.1 概念

inline 修饰 的函数叫做 内联函数 编译时 C++ 编译器会在 调用内联函数的地方展开 ,没有函数调用建立栈帧的开销,内联函数 提升程序运行的效率。
在函数前增加 inline 关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用

知识复习:写一个ADD的宏

 inline存在的意义:(1)解决宏函数晦涩难懂、容易写错(2)宏不支持调试

优点:(1)debug支持调试(2)不易写错,就是普通函数的写法(3)提升程序的效率

2.2 特性

1. inline 是一种 以空间换时间 的做法,省去调用函数额开销。所以 代码很长(大于10行) 或者有 循环 / 递归 的函数不适宜使用作为内联函数。
2. inline 对于编译器而言 只是一个建议 ,编译器会自动优化,如果定义为 inline 的函数体内有循环 / 递归等等,编译器优化时会忽略掉内联。
3. inline 不建议声明和定义分离 (头文件中,两个都写),分离会导致链接错误。因为 inline 被展开,就没有函数地址了,链接就会找不到。
知识点
宏的优缺点?
优点:
1. 增强代码的复用性。
2. 提高性能。
缺点:
1. 不方便调试宏。(因为预编译阶段进行了替换)
2. 导致代码可读性差,可维护性差,容易误用。
3. 没有类型安全的检查 。
C++ 有哪些技术替代宏
1. 常量定义 换用 const
2. 函数定义 换用内联函数

3.auto关键字(C++11)

3.1 类型别名思考

随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在:
1. 类型难于拼写
2. 含义不明确导致容易出错

【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr,C++,笔记,c++,开发语言

 auto可以自动定义类型,根据等号后面的变量

C++中,typeid(A).name();可以知道A的类型是什么

3.2 auto简介

在早期 C/C++ auto 的含义是:使用 auto 修饰的变量,是具有自动存储器的局部变量
C++11 中,标准委员会赋予了 auto 全新的含义即: auto 不再是一个存储类型指示符,而是作为一个新的类型 指示符来指示编译器, auto 声明的变量必须由编译器在编译时期推导而得
使用 auto 定义变量时 必须对其进行初始化 ,在编译阶段编译器需要根据初始化表达式来推导 auto 的实际类 。因此 auto 并非是一种 类型 的声明,而是一个类型声明时的 “占位符” ,编译器在编译期会将 auto 替换为 变量实际的类型

3.3 auto的使用细则

(1)auto与指针和引用结合起来使用

auto 声明 指针类型 时,用 auto auto* 没有任何区别,但用 auto 声明引用类型时则必须加 &

auto*定义的必须是指针类型

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

auto意义之一:类型很长时,懒得写,可以让他自动推导。 

3.4 auto不能推导的场景

1. auto 不能作为函数的参数以及函数的返回值
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
2. auto 不能直接用来声明数组
void TestAuto()
{
 int a[] = {1,2,3};
 auto b[] = {4,5,6};
}

3. 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法

4. auto 在实际中最常见的优势用法就是跟以后会讲到的 C++11 提供的新式 for 循环,还有 lambda 表达式等进行配合使用。

4. 基于范围的for循环(C++11)

4.1 范围for的语法

C++11 中引入了基于范围的for 循环。 for 循环后的括号由冒号 分为两部分:第一部分是范围内用于迭代的变量, 第二部分则表示被迭代的范围
void TestFor()
{
	int array[] = { 1, 2, 3, 4, 5 };
	//加&的原因是e是array内容的拷贝,所以改变e不是改变array里面的内容
	for (auto& e : array)
	{
		e *= 2;
	}
	//范围for,依次自动取arrar中的数据,赋值给e,自动判断结束
	for (auto e : array)//这里写int也可以
	{
		cout << e << " ";
	}
}
与普通循环类似,可以用 continue 来结束本次循环,也可以用 break 来跳出整个循环

4.2 范围for的使用条件

1. for 循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围 ;对于类而言,应该提供 begin end
方法, begin end 就是 for 循环迭代的范围。
注意:以下代码就有问题,因为 for 的范围不确定
void TestFor(int array[])
{
 for(auto& e : array)
 cout<< e <<endl;
}

这里的array是数组的首元素的地址,所以范围不定文章来源地址https://www.toymoban.com/news/detail-614839.html

2. 迭代的对象要实现 ++ == 的操作

5. 指针空值nullptr(C++11)

5.1 C++98中的指针空值


	//指针初始化
	int* p1 = NULL;
	int* p2 = 0;
	int* p3 = nullptr;//建议用这一种
C++98 中,字面常量 0 既可以是一个整形数字,也可以是无类型的指针 (void*) 常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0
注意:
1. 在使用 nullptr 表示指针空值时,不需要包含头文件,因为 nullptr C++11 作为新关键字引入的
2. C++11 中, sizeof(nullptr) sizeof((void*)0) 所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用 nullptr

到了这里,关于【C++初阶】C++基础(下)——引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

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

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

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

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

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

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

    2024年04月15日
    浏览(48)
  • 【C++】内联函数、auto关键字、基于范围的for循环、指针空值nullptr

    👀樊梓慕: 个人主页  🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.内联函数 1.1概念 1.2特性 2.auto 2.1类型别名思考 2.2auto简介 2.3auto的使用细则 2.4auto不能使

    2024年02月07日
    浏览(47)
  • 【与C++的邂逅之旅】--- 内联函数 && auto关键字 && 基于范围的for循环 && nullptr

    关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა 博主专栏: 💡 与C++的邂逅之旅 💡 数据结构之旅 上篇我们了解了函数重载和引用,我们继续学习有关C++的一些小语法— 内联函数,auto,基于范围的for循环以及 nullptr,请放心食用 ~ 这个函数不陌生吧,我们在实现排序算法时经常

    2024年04月09日
    浏览(88)
  • 从C语言到C++(第一章_C++入门_下篇)内联函数+auto关键字(C++11)+范围for +nullptr

    目录 1. 内联函数 1.1 内联函数的概念 1.2 内联函数的特性 1.3 宏的优缺点和替代方法 2. auto(C++11) 2.1 改版前的auto 2.2 C++11的auto 2.3 auto 的使用场景 2.4 使用auto的注意事项 3. 范围 for(C++11) 3.1 范围 for 的用法 3.2 范围 for 的使用条件 4. 指针空值 nullptr 4.1 C++ 98 中的指针空

    2023年04月21日
    浏览(47)
  • 计算机语言 之【C++】入门级知识讲解(命名空间,C++输入输出,缺省参数,函数重载,引用,内敛函数,auto关键字,for循环,指针空值nullptr)

    三点睡六点起,阎王夸我好身体 不到三点我不睡,太平间里抢C位 目录: 前言: 本片博客是以学习过C语言之后进入C++学习为前提,讲解C++入门级知识,为C++之后的学习做铺垫 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀

    2024年04月11日
    浏览(133)
  • 【开懂C++】引用与关键字auto

    引用就是给一个已经存在的变量取一个别名,与变量共用一段内存空间。注意引用的类型必须和变量类型相同,来演示下引用如何使用。 如上面的代码所示:我们给a取了个别名b,给b取别名c…也就是b是a的引用,c是b的引用…。 其实b,c,d都代表着a,它们都共用着一块内存空间

    2023年04月18日
    浏览(51)
  • 【C++入门必备知识:|引用| +|auto关键字| + |范围for|】

    在这里插入图片描述 引用不是新定义一个变量,而是给已经存在的变量取别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存区间。 比如水浒传里的李逵 小名叫铁牛,江湖人称黑旋风。这些都是他,只不过名字不同。 类型 引用变量名=引用实体

    2023年04月22日
    浏览(51)
  • 【C++初阶】C++基础(上)——C++关键字、命名空间、C++输入&输出、缺省参数、函数重载

    目录 1. C++ 2. 命名空间 2.1 命名空间的定义 2.2 命名空间的使用 3. C++输入输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C++支持函数重载的原理——名字修饰(name Mingling) 5.3 extern \\\"C\\\" ❀❀❀ 没有坚持的努力,本质上并没有多

    2024年02月15日
    浏览(57)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包