C++的auto类型说明符详解 附易错实例

简介: C++的auto类型说明符详解 附易错实例

基本概念


C++11标准引入了auto类型说明符,auto类型说明符可以让编译器来分析表达式所属的类型。


编译器通过什么来分析表达式的类型?


答案是通过变量的初始值。


所以,auto定义的变量必须有初始值。


auto i = 1 + 3;


i的初始值是1和3相加的结果。编译器会根据i的初始值自动推断变量i的类型。


1和3都是int类型,所以i的类型就是int。


以此类推,倘若它俩都变成double类型,那么i的类型就是double。


使用auto也能在一条语句中声明多个变量。


但是因为一条声明语句只能有一个基本数据类型,所以该语句中所有变量的数据类型都必须一样。


易错点


auto i=1+3,j=5;//正确,都为int类型
auto a=1.23,b=2//错误,一个double,一个int

需要注意的是,当使用auto声明一个引用类型或者const类型时,就不能让编译器自主判断了。


这种情况我们必须手动添加。


auto i=1+3;//i是int类型
auto &m=i;//m是绑定在i上面的一个int类型引用
const auto n=i;//n是值为4的常量


易错实例


auto是非常方便的语法,但是不能滥用,可能会有意想不到的错误。


像下面的情况,请你找一下错误所在吧!


#include<bits/stdc++.h>
using namespace std;
int main()
{
  string s = "123";
  for (auto i = s.size() - 1; i >= 0; --i)
  cout << s[i];
  return 0;
}


实例详解


你可能会自信地认为输出的结果是321.


那么很遗憾,你的答案是错误的。


上面的代码会输出一堆乱码。


原因就在于auto上面。


仔细研究一下auto i = s.size() - 1;i被推导成什么类型了?是int类型吗?


事实上i被推导成了无符号整形。


因为s.size()返回的就是一个无符号整形。


无符号整形没有负数,计算机会把无符号整形的-1,-2等负数解释成非常大的正整数值。


所以上述代码一直满足i >= 0的条件。


C++里没有越界检测机制,即使正整数的值已经超过了字符串的长度,循环体依旧可以成功运行。


所以程序会莫名其妙的输出乱码。


而且,即使i从正整数值递减到0,依然会因为刚才解释的原因再次回到那个非常大的正整数值。


所以程序是一个死循环。


要解决死循环也非常简单。


解决办法


不用auto就行。。。


#include<bits/stdc++.h>
using namespace std;
int main()
{
  string s = "123";
  for (int i = s.size() - 1; i >= 0; --i)
  cout << s[i];
  return 0;
}


5a0ce471ea888663bb02ad111733705a_f1452bf69d434b149100bfc8c4f906ae.png


一句话总结,auto虽好,也不要贪杯哦。。。


除非你确保auto推导出来的类型是你想要的 。

54fb0425f1bb34b5c8745b3c2fa1a2e7_74705767a63e4c3ca9ef88760e0a2d39.jpeg


相关文章
|
1月前
|
存储 安全 编译器
【C++专栏】C++入门 | auto关键字、范围for、指针空值nullptr
【C++专栏】C++入门 | auto关键字、范围for、指针空值nullptr
31 0
|
1月前
|
C++
C++ 数学函数、头文件及布尔类型详解
C++ 支持数学操作,如`max`和`min`函数找最大值和最小值,以及`&lt;cmath&gt;`库中的`sqrt`、`round`等数学函数。`bool`类型用于布尔逻辑,取值`true`(1)或`false`(0)。布尔表达式结合比较运算符常用于条件判断,例如在`if`语句中检查年龄是否达到投票年龄。在代码示例中,`isCodingFun`和`isFishTasty`变量分别输出1和0。
124 1
|
4天前
|
安全 编译器 程序员
【C++入门到精通】C++类型的转换 | static_cast | reinterpret_cast | const_cast | dynamic_cast [ C++入门 ]
【C++入门到精通】C++类型的转换 | static_cast | reinterpret_cast | const_cast | dynamic_cast [ C++入门 ]
13 0
|
6天前
|
存储 安全 编译器
【C++】基础知识讲解(引用、内联、auto,基于范围for循环)
【C++】基础知识讲解(引用、内联、auto,基于范围for循环)
16 1
|
10天前
|
C++
【C++】istream类型对象转换为逻辑条件判断值
【C++】istream类型对象转换为逻辑条件判断值
【C++】istream类型对象转换为逻辑条件判断值
|
12天前
|
安全 编译器 程序员
【C++入门】内联函数、auto与基于范围的for循环
【C++入门】内联函数、auto与基于范围的for循环
|
18天前
|
C++
C++ 访问说明符详解:封装数据,控制访问,提升安全性
C++ 中的访问说明符(public, private, protected)用于控制类成员的可访问性,实现封装,增强数据安全性。public 成员在任何地方都可访问,private 只能在类内部访问,protected 则允许在类及其派生类中访问。封装提供数据安全性、代码维护性和可重用性,通过 setter/getter 方法控制对私有数据的访问。关注公众号 `Let us Coding` 获取更多内容。
26 1
|
18天前
|
C++
【C++】std::string 转换成非const类型 char* 的三种方法记录
【C++】std::string 转换成非const类型 char* 的三种方法记录
7 0
|
26天前
|
存储 安全 编译器
【C++成长记】C++入门 |auto、范围for、nullptr
【C++成长记】C++入门 |auto、范围for、nullptr
|
1月前
|
存储 编译器 Linux
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
24 0