C++特性——auto关键字、范围for、指针空值nullptr

简介: C++特性——auto关键字、范围for、指针空值nullptr


1. auto关键字

在写代码时,我们常常会遇到定义变量时变量的类型名太长的情况,例如:

namespace lwj
{
  struct Stack
  {
    Stack()
    {
      _a = nullptr;
      _top = 0;
    }
    int* _a;
    int _top;
  };
}
int main()
{
  lwj :: Stack st;
  lwj :: Stack st_bak = st;
    return 0;
}

我们发现,变量stst_bak的类型名实在是太长了,有没有什么办法解决呢?

C++引入了auto这个关键字来解决这个问题。

7.1 auto的功能

auto关键字可以自动识别变量的类型。

例如:

lwj :: Stack st;
auto st_bak = st;
int a = 1;
auto a_bak = a;
auto b = 1.0;
//typeid可以打印一个变量的类型
cout << typeid(st).name() << endl;
cout << typeid(st_bak).name() << endl;
cout << typeid(a).name() << endl;
cout << typeid(a_bak).name() << endl;
cout << typeid(b).name() << endl;

output:

struct lwj::Stack
struct lwj::Stack
int
int
double

1.2 关于auto关键字的细节

  1. 使用auto关键字必须初始化:
auto num;
//会报错:“num”: 类型包含“auto”的符号必须具有初始值设定项
  1. 这是因为:

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

  1. auto关键字初始化指针变量时,*可带可不带:声明引用时,&必须带上
int a = 1;
auto ptr = &a;
auto* ptr_bak = &a;
auto& num = a;
cout << typeid(ptr).name() << endl;
cout << typeid(ptr_bak).name() << endl;
cout << typeid(num).name() << endl;
  1. output:
int *
int *
int
  1. 在同一行定义多个变量
    在同一行用auto关键字定义多个变量时,这些变量必须是相同的类型。例如:
auto num1 = 1, num2 = 2.0;
/*
会报错:
    error C3538: 在声明符列表中,“auto”必须始终推导为同一类型
    message : 可能是“int”
    message : 或    “double”
*/
  1. auto关键字不能做函数形参
    例如:
void Func(auto num1){}
//会报错:参数不能为包含“auto”的类型
//因为auto并不能确定num1的类型
  1. auto关键字不能声明数组
    例如:
auto Num[3] = { 1, 2, 3 };
//会报错:
/*
  “auto [3]”: 数组不能具有其中包含“auto”的元素类型
  error C3535: 无法推导“auto [3]”的类型(依据“initializer list”)
  error C2440: “初始化”: 无法从“int”转换为“std::initializer_list<int>”
  message : 无构造函数可以接受源类型,或构造函数重载决策不明确
*/

2. 范围for

在C++中,我们可以用这样一个循环来输出一个数组:

int Num[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
for (auto i : Num)
{
    cout << i << ' ';
}
  • 这样的for循环叫做范围for
  • for (auto i : Num)中,:前的内容表示用于范围内迭代的变量,例如上面的代码,就是依次取数组Num的数据赋值给i
  • :后的内容就表示循环迭代的范围

我们可以用下面的操作实现将数组内的每个数变为原来的两倍

//将用于迭代的变量声明为引用,这样每次迭代i就是数组内每个数据的别名
for (auto& i : Num)
{
    i *= 2;
}

2.1 限制条件

要使用范围for,就要确保迭代的范围时明确的

例如下面的用法就是错误的:

void Print(int* nums)
{
    //nums是一个指针,没有明确的迭代范围。用法错误
  for (int i : nums)
    cout << i << ' ';
}
int main()
{
  int Num[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
  Print(Num);
  return 0;
}

3. 指针空值nullptr

先来看下面的代码:

void Func(int* ptr)
{
  cout << "int*" << endl;
}
void Func(int num)
{
  cout << "int" << endl;
}
int main()
{
  Func(NULL);
  Func((int*)NULL);
  return 0;
}

output:

int
int*

这下有些小伙伴就会疑惑了:

以前我们学习C语言时,初始化指针变量都是这么定义的:int* ptr = NULL。我们用NULL初始化指针变量,为什么**NULL会被认定为整形**呢?

  • 实际上,NULL实际上是库中的宏定义
#define NULL 0
  • 我们也可以用typeid来查看一下NULL的类型:
cout << typeid(NULL).name() << endl;
  • output:
int

因此,为了避免上述的尴尬,在C++中,如果要让一个指针为空时,我们可以用关键字nullptr。例如:

int* ptr = nullptr;

至此,关于C++的特性我们就已经有了基本的了解。

下一个篇章,我们将开启对C++类和对象的学习,感兴趣的小伙伴可以订阅此专栏。

本篇完。

相关文章
|
16天前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
50 0
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
140 4
|
3月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
3月前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
3月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
73 1
|
3月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
54 2
|
3月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
3月前
|
存储 C++ 索引
C++函数指针详解
【10月更文挑战第3天】本文介绍了C++中的函数指针概念、定义与应用。函数指针是一种指向函数的特殊指针,其类型取决于函数的返回值与参数类型。定义函数指针需指定返回类型和参数列表,如 `int (*funcPtr)(int, int);`。通过赋值函数名给指针,即可调用该函数,支持两种调用格式:`(*funcPtr)(参数)` 和 `funcPtr(参数)`。函数指针还可作为参数传递给其他函数,增强程序灵活性。此外,也可创建函数指针数组,存储多个函数指针。
|
4月前
|
编译器 C++
【C++核心】指针和引用案例详解
这篇文章详细讲解了C++中指针和引用的概念、使用场景和操作技巧,包括指针的定义、指针与数组、指针与函数的关系,以及引用的基本使用、注意事项和作为函数参数和返回值的用法。
58 3
|
3月前
|
存储 编译器 程序员
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(二)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值