C++6 auto|decltype|nullptr|string

一,auto类型推导

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

示例:

int main()
{
	auto x = 10;//x是int类型
	auto a = &x;//a是int*类型
	const auto* xp = &x, u = 6;//xp是const int *类型的。u是const int 类型
}

auto声明的变量必须要有初始化值。

auto不能作用于函数参数。

auto不能用于非静态成员变量。

auto无法定义数组。

二,decltype关键字

auto用于通过一个表达式在编译时确定待定义的变量类型,auto所修饰的变量必须被初始化,编译器需要通过初始化来确定auto所代表的类型,即需要定义变量。若只希望得到类型,我们可以使用decltype关键字。

语法格式如下:decltype(exp)

其中exp表示一个表达式(expression)。

格式上decltype很像sizeof用来推导表达式类型大小的操作符。类似于sizeof,decltype的推到过程是在编译期完成的,并不会真的计算表达式的值。

int main()
{
	int x = 10;
	decltype(x) y = 1;//int
	const int& i = x;
	decltype(i) j = y;//const int &
}

当括号内为变量本身为引用

如果是值类型则是类型

三,指针空值nullptr

初始化指针是将其指向一个”空“的位置,比如0。由于大多数计算机系统不允许用户程序写地址为0的地址空间,倘若程序无意间对该指针所指地址赋值,程序会在运行时推出。这样也方便我们找出错误所在位置。

所以通常情况下,我们能看见的指针初始化语法如下:

int* my_ptr = 0;
int* my_ptr = NULL;
//一般情况下NULL是个宏定义,在<stddef.h>里我们能找到如下代码:
#undef NULL
#if defined (_cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

可以看到,NULL可能被定义为字面常量0,或者是定义为无类型指针(void*)0常量。不过无论采用什么样的定义,我们在使用空值的指针时,都不可避免地会遇到一些麻烦。让我们先看一个关于函数重载的例子。这个例子我们引用自C++11标准关于 nullptr 的提案。

1 void fun(char *)
2 {
3 printf(" call fun(char *) n");
4 }
5 void fun(int i)
6 {
7 printf(" call fun(int i) n");
8 }
9 int main()
10 {
11 fun(0);
12 fun(NULL); // 期望调用 fun(char*);
13 fun((char*)0);
14 }

引起该问题的元凶是字面常量0的二义性,在C++98标准中,字面常量0的类型既可以是一个整型,也可以是一个无类型指针(void*)0。如果程序员想在代码清单中调用fun (char*)版本的话,则必须像随后的代码一样,对字面常量0进行强制类型转换((char*)0)并调用,否则编译器总是会优先把0看作是一个整型常量。

 在C++11新标准中,出于兼容性的考虑,字面常量0的二义性并没有被消除。但标准还是为二义性给出了新的答案, 就是 nullptr。在C++11标准中, nullptr是一个所谓"指针空值类型"的常量。指针空值类型被命名为 nullptr _t, 事实上, 我们可以在支持nullptr的头文件 (cstddef) 中找出如下定义:
1 typedef dec1type(nullptr) nullptr _t;

 可以看到,nullptr _t的定义方式非常有趣,与传统的先定义类型,再通过类型声明值的做法完全相反 (充分利用了decltype 的功能) 。我们发现, 在现有编译器情况下, 使用nullptr _t的时候必须#include (#include有些头文件也会间接#include, 比如) , 而 nullptr则不用。这大概就是由于nullptr

是关键字, 而 nullptr _t是通过推导而来的缘故。

简单而言,由于nullptr是有类型的,且仅可以被隐式转化为指针类型。

1 void fun(char*)
2 {
3 printf(" call fun(char *) n");
4 }
5 void fun(int i)
6 {
7 printf(" c a 11 fun(int i) n");
8 }
9 int main()
10 {
11 fun(nullptr);
12 fun(0);
13 return 0;
14 }
15 // 输出
16 // call fun(char *)
17 // call fun(int i)
18

可以看到,在改为使用nullptr之后,用户能够准确表达自己的意图,在书写C++11代码想使用NULL的时候, 将NULL 替换成为 nullptr我们就能获得更加健壮的代码。
nullptr和 nullptr _t

C11标准不仅定义了指针空值常量 nullptr, 也定义了其指针空值类型 nullptr _t, 也就表示了指针空值类型并非仅有nullptr一个实例。通常情况下, 也可以通过 nullptr _t来声明一个指针空值类型的变量 (即使看起来用途不大)。

除去 nullptr及 nullptr _t以外, C++中还存在各种内置类型。C++11标准严格规定了数据间的关系。大体上常见的规则简单地列在了下面:

所有定义为nullptr _t类型的数据都是等价的,行为也是完全一致。
nullptr _t类型数据可以隐式转换成任意一个指针类型。
nullptr _t类型数据不能转换为非指针类型, 即使使用

1 reinterpret _ cast<nu11ptr_t>();
2
3
4 int main()
5 {
6 int a = nu11ptr; // error;
7 int *p = nullptr; // ok;
8 char *cp = nullptr; // ok;
9 }

的方式也是不可以的。
nullptr _t类型数据不适用于算术运算表达式。
nullptr _t 类型数据可以用于关系运算表达式, 但仅能与nullptr _t类型数据或者指针类型数据进行比较,当且仅当关系运算符为==、<=、>=等时返回true。
注意:
1、nullptr 是C++11新引入的关键字,是一个所谓"指针空值类型"的常量,在C++程序中直接使用。
2、在C++11 中, sizeof(nullptr) 与sizeof((void*)0) 所占的字节数相同都 (4, 或8) 。
3、为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr

四,typedef与using


1 #include<string> //
2 #include<string. h> // 或
3 #include<cstring>
4 using namespace std;
5 int main()
6 {
7 char str[]={"tulun"}; // str 是数组, 存储字符串
8 int 1en = strlen(str);
9 string s1 ="tulun"; // 字符串
10
11 for(int i = 0;i<1en;++i)
12 {
13 cout<<str[i];
14 }
15 // s1. length(); // s1. size();
16 for(int i = 0;i<s1. size();++i)
17 {
18 cout<<s1[i];
19 }
20 cout<<s1<<end1;
21 s1 = "hello";
22 cout<<s1<<end1;
23 s1+="tulun";
24 cout<<s1<<end1;
25 cin>>s1; // new data // 空格为中止符
26 cout<<s1<<end1;
27 }

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值