C11新特性中auto和decltype

1.类型推导:auto

C ++11引入了 auto 和 decltype 关键字实现类型推导,通过这两个关键字不仅能方便地获取复杂的类型,而且还能简化书写,提高编码效率。 C11中 auto 成为类型指示符( type - specifier )。在C语言中叫存储类型指示符。

auto 类型推导: auto 定义的变量,可以根据初始化的值,在编译时推导出变量名的类型。

注意:1)最好auto 与变量是一对一的,如果不是要注意初始化的类型要一致,否则容易出现二义性

2)推演auto的类型的时候,如果给出了几个✳,那么auto所指的类型中就相应的少几个✳,

3)使用auto时必须初始化。才能推断出auto的类型,并且替换掉。

void main()
{
	auto a = 10;//10->x->int  .auto=int;
	auto dx = 12.21;
	auto fx = 12.3f;
	auto ch = 'a';

	auto x = 5;//x->int  auto->int 
	const auto* xp = &x;//xp->const int*  auto->const int
	auto ip = &x;//ip->int * auto->int *
	auto* sp = &x;//sp->int*  auto->int
}

由上面的例子可以看出来, auto 并不能代表一个实际的类型声明(如 s 的编译错误),只是一个类型声明的"占位符"。

使用 auto 声明的变量必须要有初始化值,以让编译器推断出它的实际类型,并在编译时将 auto 占位符替换为真正的数据类型。

auto的推导规则 从上面的示例中可以看到 auto 的一些使用方法。它可以同指针、引用结合起来使用,还可以带上 cv 限定符( cv - qualifier (修饰词), const 和 volatile 限定符的统称)。

一旦数据的类型出现了const那么auto一定出现const

void main()
{
	const int a = 10;
	auto  b = a;//b->int   auto->int
	auto& c = a;//因为a是常变量,所以c->const int&   auto->const int

}

auto不能推导的场景

1)auto不能作为函数的参数

auto不能作为形参类型,因为编译器无法对a的实际类型进行推导,只有在调用函数的时候,才会进行传参,在这之前不知道auto类型的话,栈帧的大小,以及给a变量分配空间的大小都不知道,在编译的时候就会报错。

2)auto不能作为函数的返回值,但可以接收函数返回值

3)auto不能用来声明数组

2.类型推导:declttype

上一节所讲的 auto ,用于通过一个表达式在编译时确定待定义的变量类型, auto 所修饰的变量必须被初始化,编译器需要通过初始化来确定 auto 所代表的类型,即必须要定义变量。若仅希望得到类型,而不需要(或不能)定义变量的时候应该怎么办呢?

C ++11新增了 decltype 关键字,用来在编译时推导出一个表达式的类型。 它的语法格式如下: decltype ( exp ) 其中, exp 表示一个表达式( expression )。 从格式上来看, decltype 很像 sizeof -﹣用来推导表达式类型大小的操作符。类似于 sizeof ,

int my_add(int a, int b)
{
	return a + b;
}
void main()
{
	int x = 10;
	decltype(x) y = 1;//根据推演出的x的类型来定义y
	decltype(x) a;//不赋值也是可以的 ,因为decltype只是获取类型
	decltype(x + y) z = 10;//同样不会去计算x+y 而是得到类型给z初始化

	const int& x = 10;
	decltype(x) j = 20;//推导出x的值是const int &

	int z = 10;
	const decltype(z)* p = &z;//p->const  int *
	decltype(z)* ip = &z;//ip->int *
    
    decltype(my_add(1,2)) z;//不会去调用该函数,只是得到函数返回值就可以了
}

3.基于范围的for循环

在C98中,不同的容器和数组,遍历的方法不尽相同,写法不统一,也不够简洁,而 C ++11基于范围的 for 循环以统一、简洁的方式来遍历容器和数组,用起来更方便了。 在 C ++中遍历一个数组(容器)的方法一般是这样的以下是基于范围的 for 循环的一般格式:

for ( ElemType val : array )
{
     ...//statement 循环体
}

ElemType :是范围变量的数据类型。它必须与数组(容器)元素的数据类型一样,或者是数组元素可以自动转换过来的类型。

val :是范围变量的名称。该变量将在循环迭代期间依次接收数组中的元素值。在第一次循环迭代期间,它接收的是第一个元素的值;在第二次循环迭代期间,它接收的是第二个元素的值;以此类推。

array :是要让该循环进行处理的数组(容器)的名称。该循环将对数组中的每个元素迭代一次。不能对指针进行迭代,指针不是集合的概念

statement :是在每次循环迭代期间要执行的语句。要在循环中执行更多的语句,则可以使用一组大括号来包围多个语句。与其他循环体一样,可以用 continue 来结束本次循环,也可以用 break 来跳出整个循环。

总结:这个for循环是创建变量接收每个数组或容器中的值,所以对变量的改变不会影响到数组或容器本身,但是如果要改变数组或容器的值就要去使用引用。

void main()
{
	int ar[] = { 1,2,3,4,5,6,7,8 };
	for (int x : ar)
	{
		cout << x << " ";
		x += 10;
	}
	cout << endl;
	for (int x : ar)
	{
		cout << x << " ";
		
	}
	cout << endl;
	 
	for (int &x : ar)//引用
	{
		cout << x << " ";
		x += 10;
	}
	cout << endl;
	for (int x : ar)
	{
		cout << x << " ";
		x += 10;
	}
	cout << endl;
}

4.基于范围的for循环和auto

void main()
{
	int ar[] = { 12,23,34,45,56,67,78 };
	char str[] = { 'a','b','c','d' };
	double dx[] = { 1.2,2.3,3.4,4.5 };

	for (auto x : ar)
	{
		cout << x << "   ";
	}
	cout << endl;
	for (auto y : str)
	{
		cout << y << "   ";
	}
	cout << endl;
	for (auto d : dx)
	{
		cout << d << " ";
	}
	cout << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我在凌晨等太阳¤

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

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

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

打赏作者

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

抵扣说明:

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

余额充值