C++初阶(四)---->auto关键字,范围for循环和nullptr关键字

本文主要内容:
1.auto关键字
2.范围for循环
3.nullptr关键字


1.auto关键字
1.1 简单使用auto
这个关键字你可能或或少听说过,在C语言中这个关键字几乎是没有什么特别的作用。但是在
C++11
中,这个关键字被赋予了特殊的含义.使用了auto关键字声明的定义的变量的类型可以由编译器在编译期间自动推导出类型!
举一个简单的例子:

int Count()
{
	int x = 10;
	return x;
}
int main()
{
	int m = 5;
	auto n = m;
	auto q = 'c';
	auto t = Count();
	//typeid(变量名).name()---->返回变量类型的字符串表达
	cout <<"n的类型是:" << typeid(n).name() << endl;
	cout << "q的类型是: " << typeid(q).name() << endl;
	cout << "t的类型是: " << typeid(t).name() << endl;
	return 0;
}

程序运行结果如下:
在这里插入图片描述
不难看出,auto关键字定义的变量最终都推导出了正确的类型!但是auto并不是变量类型的声明,可以理解为这里只是占位符,编译器必须能在编译期间正确推导出相应的类型!那么也就意味着使用auto关键字推导类型的变量必须初始化!
1.2auto使用的注意事项
1.auto推导指针类型的时候有没有’*'都可以
对于使用auto去推导指针类型,auto和auto*的效果相同

  int x = 10;
	auto px = &x;
	auto* ppx = &x;
	cout << "px的类型" << typeid(px).name() << endl;
	cout << "ppx的类型" << typeid(ppx).name() << endl;

在这里插入图片描述
但是如果要推导出引用类型,auto后面必须显示加上&符号

int main()
{  
	int x = 10;
	auto a = x;
	auto& rx = x;
	rx = 20;
	cout << "a的类型" << typeid(a).name() << endl;
	cout << "rx的类型" << typeid(rx).name() << endl;
	return 0;
}

在这里插入图片描述
这里我们改rx的同时,a的值也被改了。所以这里的rx是a的一个引用.
如果要使用auto对同一行多个变量类型推导,那么多个变量的类型必须一样!

auto a=1,b=2;//正确可以推导出int
auto a=2.0,b=3;//错误,无法确定以那一个类型为准

那么当变量类型比较短的时候,可能这个auto关键字的作用体现的不是很大,不妨来看下面这个例子:

 std::vector<std::string>v;
//一个存放string类型vector的迭代器类型完整写法
  std::vector<std::string>::iterator it =v.begin();
  //使用auto
  auto it=v.begin();

怎么样,是不是方便了很多,所以说在变量类型很长的时候,使用auto关键字偷懒就显得很棒了.
1.3auto无能为力的场景
auto不能够作为函数参数的类型:为了避免 你滥用auto造成的问题,所以C++规定auto不能作为函数参数的类型

int func(auto a)//不能用auto作为函数参数的类型
{}

同理,auto也不能作为函数的返回值类型

auto func(int x)//不能用auto作为函数返回值类型
{}

auto也不能作为数组的类型

auto a[5]={1,2,3,4,5};//错误,auto不能作为数组类型声明

auto还应用于我们接下来介绍的新式for循环。接下来我们就来介绍一下这个新的for循环.


2.范围for循环
2.1新式for循环语法格式
那么在C语言或者是早期C++标准下,假设我们要遍历一个数组,那么我们需要这么些

void PrintArray()
{
	int a[] = { 9,8,7,6,5,4,3,2,1 };
	for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
	{
		cout << a[i] << " ";
	}
	cout << endl;
}

这样写不仅很繁琐,而且很容易出错。那么在C++11标准里引入了范围for循环,那么上面的代码用范围for循环可以这么写

void PrintArray()
{
	int a[] = { 9,8,7,6,5,4,3,2,1 };
	//范围for
	cout << "范围for语句:" << endl;
	for (int c : a)
	{
		cout << c << " ";
	}
	cout << endl;
}

在这里插入图片描述
可以看到这里也正确打印出了结果。范围for循环和普通的循环一样,使用continue可以跳过当次循环,而使用break可以跳出循环,其次,这里的for循环还可以使用结合前面的auto关键字使用:

int a[] = { 9,8,7,6,5,4,3,2,1 };
//范围for
	cout << "范围for语句:" << endl;
	for (auto c : a)
	{
		cout << c << " ";
	}
	cout << endl;

范围for循环的工作原理可以这么理解:从范围a里面逐一取出元素赋值给c,所以如果想要通过范围for循环改变里面的内容,就需要使用引用类型

void PrintArray()
{
	int a[] = { 9,8,7,6,5,4,3,2,1 };
	//范围for
	cout << "范围for语句:" << endl;
	for (auto& c : a)
	{
		c *= 2;
	}
	for (auto c : a)
	{
		cout << c << ' ';
	}
	cout << endl;
}

运行结果:
在这里插入图片描述
使用范围for语句有如下条件约束
1.范围for循环的范围必须是确定的

//由于数组传参只拷贝了首元素地址,不是一个范围,所以无法使用范围for循环
void Test(int a[])
{}

2.迭代对象必须实现++和–的操作
这个条件2在后面的博客会讲到,这里只是简单提一下。


3.nullptr关键字
我们知道,在使用变量之前我们都要对变量进行初始化。指针变量也是如此。我们来看这样的一段代码:

void func(int x)
{
	cout << "func(int)" << endl;
}
void func(int* px)
{
	cout << "func(int*)" << endl;
}
int main()
{   
	func(0);
	func(NULL);
	return 0;
}

我们知道在C语言中,NULL是就是(void*)0,而void是可以转换成int的,所以预计会打印出第一个打印出func(int),第二个打印出func(int*)。那么真的是这样吗?程序运行结果如下:
在这里插入图片描述
奇怪,这里为什么打印出的是两个func(int),NULL不应该打印出func(int*)那么我们来看一下C++官方库是怎么定义NULL的
在这里插入图片描述
可以看到,当文件是c++文件的时候,这个NULL是被替换成0的!这也就是为什么第二个调用打印出来func(int),这也可以说是早期C++官方库处理的一些小失误所以为了解决这一个问题,C++引入一个新的关键字来替代C语言中的NULL----->nullptr

void func(int x)
{
	cout << "func(int)" << endl;
}
void func(int* px)
{
	cout << "func(int*)" << endl;
}
int main()
{   
	//只能强制类型转换才是指针了
	func((int*)NULL);
	//新关键字替代NULL
	func(nullptr);
	return 0;
}

所以,在以后的C++程序里面,为了程序代码的健壮性,我们统一使用nullptr来替代NULL


总结:

1.auto关键字可以进行类型推导,必须初始化,不能做函数参数,返回值,也不能用在数组类型
2.范围for循环的基本语法
3.nullptr关键字

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值