超详细的保姆级C++入门学习(引用,auto,nullptr)

news/2024/10/29 5:32:08/

目录

1. 引用

1.1 引用概念

1.2 引用特性

1.3 常引用

1.3.1指针与引用的权限放大问题

1.4 使用场景

1.4.1做参数

1.4.2. 做返回值

1.5 传值、传引用效率比较

1.6 引用和指针的区别

引用和指针的不同点:

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

2.1  随着程序越来越复杂,程序中用到的类型也越来越复杂

auto简介

auto不能推导的场景

3 范围for的语法(C++11)

3.1范围for的使用条件

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


1. 引用

1.1 引用概念

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

类型& 引用变量名(对象名) = 引用实体;

int b=0;
int & a=b;

1.2 引用特性

1. 引用在定义时必须初始化

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

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

1.3 常引用

1.3.1指针与引用的权限放大问题

void TestConstRef()
{const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10; // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d; // 该语句编译时会出错,类型不同,会产生临时变量,临时变量具有常性,不能被修改const int& rd = d;
}

1.4 使用场景

1.4.1做参数

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

1.4.2. 做返回值

int& Count()
{static int n = 0;n++;// ...return n;
}
int& add(int& a, int& b,int& ret)
{ret= a + b;return ret;
}

注意:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

1.5 传值、传引用效率比较

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

#include <time.h>
typedef struct AR
{int a[10];
}A;// 值返回
A TestFunc1(A a) 
{ return a; }
// 引用返回
A& TestFunc2(A& a)
{ return a; }
int main()
{A arr;arr.a[0] = 0;// 以值作为函数的返回值类型size_t begin1 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc1(arr);size_t end1 = clock();// 以引用作为函数的返回值类型size_t begin2 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc2(arr);size_t end2 = clock();// 计算两个函数运算完成之后的时间cout << "TestFunc1 time:" << end1 - begin1 << endl;cout << "TestFunc2 time:" << end2 - begin2 << endl;
}

返回值越大,传值和指针在作为传参以及返回值类型上效率相差越大。

1.6 引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

引用和指针的不同点:

1. 引用概念上定义一个变量的别名,指针存储一个变量地址。

2. 引用在定义时必须初始化,指针没有要求

3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体

4. 没有NULL引用,但有NULL指针

5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32 位平台下占4个字节)

6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

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

2.1  随着程序越来越复杂,程序中用到的类型也越来越复杂

经常体现在:

1. 类型难于拼写

2. 含义不明确导致容易出错

使用typedef给类型取别名确实可以简化代码,但是typedef有会遇到新的难题:

typedef char* pstring;
int main()
{const pstring p1;    // 失败const pstring* p2;   // 编译成功,因为 const修饰 *p2return 0;
}

auto简介

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的 是一直没有人去使用它,大家可思考下为什么?

C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一 个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

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

auto不能推导的场景

1. auto不能作为函数的参数

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

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

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

3 范围for的语法(C++11)

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因 此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围。

注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。

3.1范围for的使用条件

1. for循环迭代的范围必须是确定的 对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供 begin和end的方法,begin和end就是for循环迭代的范围。

注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])
{for(auto& e : array)cout<< e <<endl;
}

2. 迭代的对象要实现++和==的操作。(关于迭代器这个问题,以后会讲,现在提一下,没办法 讲清楚,现在大家了解一下就可以了)

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

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif

为解决NULL代指空指针存在的二义性问题,在C++11版本(2011年发布)中特意引入了nullptr这一新的关键字来代指空指针,从上面的例子中我们可以看到,使用nullptr作为实参,确实选择了正确的以void*作为形参的函数版本。

NULL在C++中就是0,这是因为在C++中void* 类型是不允许隐式转换成其他类型的,所以之前C++中用0来代表空指针,但是在重载整形的情况下,会出现上述的问题。所以,C++11加入了nullptr,可以保证在任何情况下都代表空指针,而不会出现上述的情况,因此,建议以后还是都用nullptr替代NULL吧,而NULL就当做0使用。
 

#include <iostream>
using namespace std;void func(void* i)
{cout << "func1" << endl;
}void func(int i)
{cout << "func2" << endl;
}void main(int argc,char* argv[])
{func(NULL);func(nullptr);getchar();
}


http://www.ppmy.cn/news/36053.html

相关文章

python进行股票收益率计算和风险控制的实现

股票收益率计算和风险控制的实现 在进行股票投资时&#xff0c;计算收益率和进行风险控制是非常重要的。本文将介绍一个与此相关的函数&#xff1a;radio_day_cal()。 radio_day_cal()函数 def radio_day_cal(last_day, sheet_name, df_dict, code_list, new_list):i 0days…

芯片工程师的ChatGPT初体验(下)

既然了解了ChatGPT的强大背景&#xff0c;现在就在这个后台有10亿美金支撑的强大AI上小试牛刀一把吧&#xff0c;ICer Go! 测试一&#xff1a;TCL脚本理解测试 首先提供给ChatGPT一段innovus里的TCL脚本&#xff0c;脚本代码如下 ChatGPT还是中肯的&#xff0c;并没有说这个…

centos下mysql数据库迁移到数据盘

安装前的准备 永久关闭selinux cp /etc/selinux/config /etc/selinux/config.bak sed -i ‘s/SELINUXenforcing/\SELINUXdisabled/’ /etc/selinux/config 临时关闭 setenforce 0 //临时关闭selinux&#xff0c;重启后失效 1.停止mysql服务 如果是云系统&#xff0c;先把云系…

【LeetCode】

蓝桥杯 - dfs练习 LeetCode 1.两数之和 LeetCode 2.两数相加 LeetCode 3.无重复字符的最长字串 LeetCode 4.寻找两个正序数组的中位数 LeetCode 5.最长回文子串 LeetCode 7.整数反转 LeetCode 8. 字符串转换整数(atoi) LeetCode 9. 回文数 LeetCode 11.盛水最多的容器 LeetCod…

Qt5.12实战之正则与QregExp使用

1.普通字符匹配:ab : 匹配一个a和任意个b 如: ab abb abbbbbbc : 匹配一个c 如 : abcde 匹配内容: c 匹配开始索引:2 匹配结束索引 3bcd : 匹配字符串 bcd 如: abcde 匹配内容是: bcd 匹配开始索引是:1 匹配结束索引是:42.转换符匹配:\:转义字符匹配 如: \r \n \t \\ \^ \$ \. …

医院信息化-5 集成平台和数据中心

目录 1 集成平台1.1 技术上为什么要集成平台1.2 集成平台包括什么1.2.1 ESB(服务总线)1.2.2 IE(集成引擎)1.2.3 ETL工具1.2.4 患者主索引EMPI1.2.5 主数据MDM1.2.6 闭环管理1.2.7 CDA共享文档1.2.8 单点登录1.2.9 临床全息视图1.3 目前业内情况1.4 如何构建集成平台1.5 新技…

STM-32:TIM定时中断—定时器定时中断/定时器外部时钟

目录一、TIM简介1.1简介1.2TIM基本机构1.3基本定时器1.4通用定时器1.4.1通用定时器与基本定时器的异同1.4.2内外时钟源选择功能1.4.3编码器接口功能1.4.4主从触发模式功能1.4.5输出比较功能1.4.6输入捕获电路1.5高级计数器1.5.1重复计数器1.5.2死区生成电路与三相无刷电机1.5.3…

2023年广东省网络安全竞赛——Linux 操作系统渗透解析(超级详细)

任务四:Linux操作系统渗透测试 任务环境说明: 服务器场景:Server06服务器场景操作系统:Linux(版本不详) (关闭连接)通过本地PC中渗透测试平台Kali对服务器场景进行渗透测试,将该场景/var/www目录中唯一一个后缀为.bmp文件的文件名称作为Flag值提交;通过本地PC中渗透…