C++入门(五)内联,auto

目录

内联函数的提出

内联的特点

声明和定义不能分离

 auto函数

typedef缺点

 一些特点

auto的语法糖功能 

c/c++空指针问题


内联函数的提出

C++推荐用constenum来替代宏常量,用inline去替代宏函数

宏函数缺点:

不能调试

有些条件下非常复杂,不易掌握

直接替换,无法检测类型安全

我们可以先实现一个简单的加法宏函数 

39e1651678144dc987b4734f8778f704.png

 可以看出宏函数的构造十分复杂,加括号的目的是为了使运算更加安全,此处我们测试宏函数所以不多赘述。

这里使用宏函数有两个优势:

1.不用开辟栈帧,节约空间

2.可以接收多种类型的数据,比如int 、double

接下来我们用内联函数重写Add函数

inline int Add(int x, int y)
{
	int z = x + y;
	return z;
}

需要注意的是,编译器的debug版本内联需要配置才能起作用,release版本下内联也会起作用。具体配置方法,这样就对Add这个函数进行了一个优化。

内联的特点

inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
用函数体替换函数调用。

缺陷:(编译出来的可执行程序变大优势:少了调用开销,提高程序运
行效率。

因为函数调用是直接去call这个函数的地址进行函数栈帧的开辟,调用完成后就会销毁,而内联函数虽然优化了一些函数调用操作,但却都实实在在地写入到了程序中。

内联函数只是一种对编译器的建议,如果你调用了写了100行代码的1000次inline,你就会得到100000行代码,这时编译器就会制止你愚蠢的行为。

对于优化规模较小,流程直接,频繁调用的函数,请使用内联。(不要用递归)

声明和定义不能分离

//test.h
inline int Add(int x, int y)
//test.cpp
#include"test.h"
inline int Add(int x, int y)
{
	int z = x + y;
	return z;
}
//主程序
#include"test.h"
int main()
{   
    Add(1,2);
    return 0;
}

 分离后会出现链接错误,这是因为inline是优化后的函数,他不会去调用函数栈帧,自然在链接过程中无法找到函数地址,即无法链接上test.cpp的内容,因为就没有产生相应的符号表

所以推荐直接在.h文件定义

 auto函数

auto即自动推导函数

auto a = 2;
auto b = 2.4;
auto c = &a;

 这里我们用“typeid”这个函数来识别它们的类型

799b7c2a378a4091b434d5c427266f5f.png

//推导函数返回值
inline int Add(int x, int y)
{
	int z = x + y;
	return z;
}
auto d = Add(1, 2);
cout << typeid(d).name() << endl;

 自然,auto的好处在后面的学习中会代替一些比较复杂的类型比如说迭代器等,方便简化代码。

typedef缺点

随便提一下,假设类型名很长也可以用typedef来定义,但是却没有auto来得方便,毕竟,术业有专攻。下面是一个typedef缺陷的代码例子

typedef int* ptr;
const ptr p;
const ptr* pp;

哪一个对,哪一个错?或者都对?

答案是第一个错误,第二个正确。因为在未执行预处理操作替换时,const是修饰p的,一旦替换进去,就成了int* const ptr了,我有一篇文章区分过const位置代表什么意思,这代表这常量指针,特点是必须初始化一个值,因为不能修改指针指向的地址

 一些特点

auto* c = &a;
auto& d = a;

我们注意一下这样使用的时候赋值对象是否正确,否则就会报错,并且指针类型是可以直接被auto推断出来的,可以根据可读性自行添加,而引用类型就是给这个对象取别名,使推到类型增加引用属性。

auto的语法糖功能 

e7d98e18a46b465397a08b6f499a45a7.png

两组代码对比分析,可以理解为下面的方式是对上面的一种简化,原理是自动依次取数组中数据赋值给x对象,自动判断结束

除此之外,若想改变数组的值,只需在auto后加上&就行了,这样从单纯的赋值变成了数组每个值的别名,实现修改操作。

38a619b487494fd4948f392048479df4.png

特殊情况 

void f(int arr[])//指针
{
	for (auto& x : arr)
	{
		cout << x << " ";
	}
}

将auto放入函数中推导是不行的,因为传过来的不是整个数组,而是数组首元素地址。

auto支持同时初始化多个参数,但参数类型必须一致

auto a = 3,b = 4.0//错误
auto c = 1,b = 2;

        auto不能做形参,个人理解是避免与函数重载混淆

        auto不能声明数组,因为可能会出现内部成员不一致的情况。

        总之,auto是把双刃剑,得合理运用。

c/c++空指针问题

        我们知道,c得空指针是NULL,到了c++,NULL出现了一些问题,被替换成了整数0

C++11 引入了 `nullptr` 关键字,以替代原来用于表示空指针的整数常量 `NULL` 或 `0`。`nullptr` 有明确定义的类型,可以更安全地用于类型推断和函数重载解析。

        使用 `nullptr` 还可以避免一些令人困惑和易错的问题。例如,如果将整数常量 `0` 与指针进行比较,则编译器将隐式地将其转换为指针类型,这可能会导致无意中匹配错误类型的重载函数。而通过使用 `nullptr`,可以避免这种问题,因为它只能被隐式转换为指针或成员指针类型,不会转换为整数类型。

34233601c201470b85e7641e0eeecd14.png

这就是c++的预备知识了,接下来我们学习c++的类和对象吧。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小C您好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值