做网站直播平台,wordpress linux 伪静态,开发外包平台,WordPress重力表单注册auto关键字#xff08;c11#xff09;
1. auto关键字的诞生背景
随着程序的逐渐复杂#xff0c;程序代码中用到的类型也越来越复杂。譬如#xff1a;
类型难以拼写#xff1b;含义不明确容易出错。
比如下面一段代码#xff1a;
#include string
#include c11
1. auto关键字的诞生背景
随着程序的逐渐复杂程序代码中用到的类型也越来越复杂。譬如
类型难以拼写含义不明确容易出错。
比如下面一段代码
#include string
#include map
int main()
{
std::mapstd::string, std::string m{ { apple, 苹果 }, { orange,
橙子 },
{pear,梨} };
std::mapstd::string, std::string::iterator it m.begin();
while (it ! m.end())
{
//....
}
return 0;
} std::mapstd::string, std::string::iterator 是一个类型但是该类型太长了容 易写错并且耗费时间成本。有人会说我们学过typedef给他起个别名。
但typedef也会遇到新的问题
typedef char* pstring;
int main()
{
const pstring p1; // 编译成功还是失败
const pstring* p2; // 编译成功还是失败
return 0;
} 在编程时常常需要把表达式的值赋值给变量这就要求在声明变量的时候清楚地知道表达式的类型。然而有时候要做到这点并非那么容易因此C11给auto赋予了新的含义。 2. auto简介 C11中标准委员会赋予了auto全新的含义即auto不再是一个存储类型指示符而是作为一个新的类型指示符来指示编译器auto声明的变量必须由编译器在编译时期推导而得。 char TestAuto()
{char m*;return m;
}
int main()
{int a 10;auto b a;auto c t;auto d TestAuto();cout typeid(b).name() endl;cout typeid(c).name() endl;cout typeid(d).name() endl;return 0;} 注意 使用auto定义变量时必须对其进行初始化在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明而是一个类型声明时的“占位符”编译器在编译期会将auto替换为变量实际的类型。 3. auto的使用细则
3.1 auto同指针与引用结合使用 用auto声明指针类型时用auto和auto*没有任何区别但用auto声明引用类型时则必须 加 int main()
{int a 10;auto* b a;auto c b;auto d a;cout typeid(b).name() endl;cout typeid(c).name() endl;cout typeid(d).name() endl;*b 30;cout a endl;**c 50;cout a endl;d 80;cout a endl;return 0;
} 3.2 在同一行定义多个变量 当在同一行声明多个变量时这些变量必须是相同的类型否则编译器将会报错因为编译 器实际只对第一个类型进行推导然后用推导出来的类型定义其他变量 3.3 auto不能推导的场景
1.auto不能作为函数的参数 因为此处编译器无法对a的实际类型进行推导。
2. auto不能直接用来声明数组 为了避免与C98中的auto发生混淆C11只保留了auto作为类型指示符的用法。
基于范围的for循环c11
1. 范围for的语法
对于一个有范围的集合而言由程序员来说明循环的范围是多余的有时候还会容易犯错误。因
此C11中引入了基于范围的for循环。for循环后的括号由冒号“ ”分为两部分第一部分是范
围内用于迭代的变量第二部分则表示被迭代的范围
int main()
{int arr[] { 1,2,3,4,5 };for (auto e : arr){e * 2;//如果要修改内容需要引用}for (auto e : arr){cout e ;}char str[] abcde;for (auto a : str){cout a ;}return 0;
}
注意与普通循环类似可以使用continue跳出本次循环也可以使用break退出循环。 2. 范围for的使用条件 for循环迭代的范围必须是确定的 对于数组而言就是数组中第一个元素和最后一个元素的范围对于类而言应该提供 begin和end的方法begin和end就是for循环迭代的范围。 注意以下代码就有问题因为for的范围不确定 void test(int arr[])
{for (auto e : arr){cout e ;}
}int main()
{int arr[10] { 1,2,3,4,5 };test(arr);return 0;
} 指针空值nullptrc11
C98中的指针空值 在良好的C/C编程习惯中声明一个变量时最好给该变量一个合适的初始值否则可能会出现不可预料的错误比如未初始化的指针。如果一个指针没有合法的指向我们基本都是按照如下方式对其进行初始化 int main()
{int a 0;int* p NULL;return 0;
}
我们来看下面这段代码
void test(int a)
{cout test(int a) endl;
}
void test(int* p)
{cout test(int* p) endl;
}
int main()
{test(0);test(NULL);test((int*)NULL);return 0;
}
在我们看来NULL是空指针因此应该调用两次test(int* p)但其实不然我们来看看结果。 这是为什么呢 我们可以看到NULL实际上是一个宏可能被定义为字面常量0或者被定义为无类型指针(void*)的常量。不论采取何种定义在使用空值的指针时都不可避免的会遇到一些麻烦。 注意
1. 在使用nullptr表示指针空值时不需要包含头文件因为nullptr是C11作为新关键字引入
的。
2. 在C11中sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性在后续表示指针空值时建议最好使用nullptr。
结语
接下来正式进入c的难点类与对象共勉