一个服务器多个网站好吗,兵团第二师建设环保局网站,百度竞价开户,公司设立网址文章目录 1.内联函数2.auto关键字2.1auto简介2.2auto的注意事项2.3auto不能推导的场景 3.基于范围的for循环(C11)4.指针空值nullptr(C11) 1.内联函数
概念#xff1a;
以inline修饰的函数叫做内联函数#xff0c;编译时C编译器会在调用内联函数的地方展开#xff0c;没有函… 文章目录 1.内联函数2.auto关键字2.1auto简介2.2auto的注意事项2.3auto不能推导的场景 3.基于范围的for循环(C11)4.指针空值nullptr(C11) 1.内联函数
概念
以inline修饰的函数叫做内联函数编译时C编译器会在调用内联函数的地方展开没有函数调用建立栈帧的开销内联函数提升程序运行的效率。
下面的代码就是不使用内联函数会建立栈帧。
如果在上述函数前增加inline关键字将其改成内联函数在编译期间编译器会用函数体替换函数的调用。 注意Debug下默认是不展开的因为展开以后不方便调试。需要设置编译器。 此时汇编代码中是没有call指令的函数展开了。
特性
inline是一种以空间换时间的做法如果编译器将函数当成内联函数处理在编译阶段会用函数体替换函数调用缺陷可能会使目标文件变大优势少了调用开销提高程序运行效率。inline对于编译器而言只是一个建议不同编译器关于inline实现机制可能不同一般建议将函数规模较小(即函数不是很长具体没有准确的说法取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰否则编译器会忽略inline特性。 如果函数的规模较大(不建议展开)展开以后编译出来的可执行程序就会变大。 inline不建议声明和定义分离分离会导致链接错误。因为inline被展开就没有函数地址了链接就会找不到。可以理解为内联函数没有地址它已经被展开了 【面试题】 宏的优缺点 优点 增强代码的复用性。提高性能。 缺点 不方便调试宏。因为预编译阶段进行了替换导致代码可读性差可维护性差容易误用。没有类型安全的检查 。 C有哪些技术替代宏 常量定义 换用const、enum短小函数定义 换用内联函数 2.auto关键字
2.1auto简介
随着程序越来越复杂程序中用到的类型也越来越复杂经常体现在
类型难于拼写含义不明确导致容易出错
有的同学也许也会想到可以使用typedef 给较长的类型取别名但是这种方法是有缺陷的例如
在早期C/C中auto的含义是使用auto修饰的变量是具有自动存储器的局部变量但遗憾的是一直没有人去使用它大家可思考下为什么 早期的auto关键字虽然是用来声明具有自动存储器的局部变量但是我不写auto它也是局部的何必自找麻烦。 C11中标准委员会赋予了auto全新的含义即auto不再是一个存储类型指示符而是作为一个新的类型指示符来指示编译器auto声明的变量必须由编译器在编译时期推导而得。 typeid是一个关键字用来获取一个表达式的类型信息。
注意 使用auto定义变量时必须对其进行初始化在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明而是一个类型声明时的“占位符”编译器在编译期会将auto替换为变量实际的类型。 2.2auto的注意事项
auto与指针和引用结合起来使用
用auto声明指针类型时用auto和auto * 没有任何区别但用auto声明引用类型时则必须加 在同一行定义多个变量
当在同一行声明多个变量时这些变量必须是相同的类型否则编译器将会报错因为编译器实际只对第一个类型进行推导然后用推导出来的类型定义其他变量。
2.3auto不能推导的场景
auto不能作为函数的参数
若auto作为参数那形参是什么类型呢编译器是不知道的编译时就不知道栈帧要开多大
auto不能直接用来声明数组 为了避免与C98中的auto发生混淆(C11中被废弃了)C11只保留了auto作为类型指示符的用法auto在实际中最常见的优势用法就是跟C11提供的新式for循环还有lambda表达式等进行配合使用。
3.基于范围的for循环(C11)
范围for简介
在C98中如果要遍历一个数组可以按照以下方式进行
对于一个有范围的集合而言由程序员来说明循环的范围是多余的有时候还会容易犯错误。因此C11中引入了基于范围的for循环。for循环后的括号由冒号“ ”分为两部分第一部分是范围内用于迭代的变量第二部分则表示被迭代的范围。 要想改变数组中的元素需要使用引用 注意与普通循环类似可以用continue来结束本次循环也可以用break来跳出整个循环。
范围for的使用条件
for循环迭代的范围必须是确定的
对于数组而言就是数组中第一个元素和最后一个元素的范围对于类而言应该提供begin和end的方法begin和end就是for循环迭代的范围。 注意以下代码就有问题因为for的范围不确定
void TestFor(int array[]){for(auto e : array)//errorcout e endl;}4.指针空值nullptr(C11)
如果一个指针没有合法的指向我们基本都是按照如下方式对其进行初始化
void TestPtr()
{int* p1 NULL;int* p2 0;// ……
}NULL实际是一个宏在传统的C头文件(stddef.h)中可以看到如下代码
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif可以看到NULL可能被定义为字面常量0或者被定义为无类型指针(void)的常量*。不论采取何种定义在使用空值的指针时都不可避免的会遇到一些麻烦比如 程序本意是想通过f(NULL)调用指针版本的f(int*)函数但是由于NULL被定义成0因此与程序的初衷相悖。 在C98中字面常量0既可以是一个整形数字也可以是无类型的指针(void*)常量但是编译器默认情况下将其看成是一个整形常量如果要将其按照指针方式来使用必须对其进行强转(void*)0。 在使用nullptr表示指针空值时不需要包含头文件因为nullptr是C11作为新关键字引入的。 在C11中sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。 为了提高代码的健壮性在后续表示指针空值时建议最好使用nullptr。