inline内联函数 auto类型修饰符 基于范围的for循环(C++11)

目录

inline内联函数

一、内联函数的性质

二、内联函数的使用

auto类型修饰符

一、auto类型修饰符的概念 

二、auto类型修饰符的使用 

三、auto关键字不能使用场景

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

一、基于范围的for循环的语法

二、 基于范围的for循环的前置条件

三、基于范围的for循环的使用


inline内联函数

一、内联函数的性质

内联函数(inline)是C++一种重要的构造函数的方法。内联函数可以消除函数调用的开销(即函数压栈),以空间换时间,提高程序运行的效率。在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。具有参数类型检查的功能,相当于宏的上位替代。

  1. 内联函数一般比较短小,通常不超过10行代码。
  2. 内联函数不能承载复杂的操作,如循环、递归等。inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等,编译器优化时会忽略掉内联。
  3. 内联函数不能包含复杂的控制语句,如switch、goto等。
  4. 内联函数不能包含复杂的数据类型,如结构体、类等。
  5. 不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

二、内联函数的使用

//头文件中完成定义与声明
inline int ADD(int a = 0, int b = 0, int c = 0)
{
	return a + b + c;
}

//在引用该头文件的cpp源文件中直接进行使用
int c = ADD(23, 45, 67);

 注:如果在类中直接定义,不需要用inline修饰,编译器自动化为内联函数。

如:

class ClassName
{

//...

//...

//编译器自动化将其化为inline内联函数
int ADD(int a = 0, int b = 0, int c = 0)
{
    return a + b + c;
}

//...

//...

}

auto类型修饰符

一、auto类型修饰符的概念 

auto是C++中的一种类型说明符,它允许编译器从变量的初始化器中推断出变量的类型。它是在C++11中引入的,用于简化变量的声明,特别是当类型很复杂或很难拼写时。

二、auto类型修饰符的使用 

  • auto与指针和引用结合起来使用,用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&。
  • 在同一行定义多个变量当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  • auto会忽略顶层const修饰。 

利用typeid().name()函数可以获得表达式的类型

    int x = 10;
    cout << typeid(x).name() << endl;
	auto a = x;
	cout << typeid(a).name() << endl;
	auto* b = &x;
	cout << typeid(b).name() << endl;
	auto c = &x;
	cout << typeid(c).name() << endl;
	auto& d = x;
	cout << typeid(d).name() << endl;

三、auto关键字不能使用场景

1.不能作为函数的参数

// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{
    
}

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

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表达式等进行配合使用。

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

一、基于范围的for循环的语法

基于范围的for循环是C++11引入的一种新的循环语句,它可以遍历一个序列中的所有元素,而无需使用迭代器或指针。它的语法如下:

for (declaration : range_expression)
{
    statement
}

其中,declaration 是一个定义,用于定义一个新变量,该变量将用于存储序列中的每个元素。range_expression 是一个表达式,它表示要遍历的序列。statement 是要执行的语句,它将针对序列中的每个元素执行一次。

二、 基于范围的for循环的前置条件

基于范围的 for 循环只能用于支持迭代器的容器类型。C++ 标准库提供了很多标准容器,如 std::vectorstd::liststd::map 等,这些容器类型都支持迭代器,因此都可以使用基于范围的 for 循环进行遍历。

使用数组定义的数组可以直接使用基于范围的 for 循环进行遍历,因为数组实际上是一个定长的容器,支持迭代器特性,也就是支持 begin()end() 成员函数来返回指向数组首元素和尾后元素的迭代器。

三、基于范围的for循环的使用

例如,以下代码使用基于范围的for循环遍历一个数组:

int arr[] = {1, 2, 3, 4, 5};
for (int i : arr)
{
    std::cout << i << ' ';
}

输出:

1 2 3 4 5

在这个例子中,declaration 是 int i,它定义了一个新变量 i,该变量将用于存储数组中的每个元素。range_expression 是 arr,它表示要遍历的数组。statement 是 std::cout << i << ' ',它将打印数组中的每个元素。

使用条件:

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

注意:

用动态开辟的数组,返回值为一个指针,这种指针并不是一个标准容器类型的迭代器,因此不能直接用于基于范围的 for 循环。

代码如下:

int* pa2 = new int[10] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << *p2 << endl;
for (int& e : pa2)
{
	cout << e << " ";
}
cout << endl;

会出现以下错误:

此基于范围的“for”语句需要适合的 "begin" 函数,但未找到。

对于使用 new 创建的动态数组,可以将其封装在一个容器类中,使其具有迭代器特性,从而能够使用基于范围的 for 循环进行遍历。例如,可以使用 std::vectorstd::array 来封装动态数组:

#include <iostream>
#include <vector>

int main() {
    int* arr = new int[5]{1, 2, 3, 4, 5};

    std::vector<int> v(arr, arr + 5);
    // 或者
    // std::array<int, 5> a{arr[0], arr[1], arr[2], arr[3], arr[4]};

    for (auto i : v) {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    delete[] arr;

    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值