关键字专题
先从一些较难理解的关键字开始
1.constexpr
参考网址: 概念描述还可以,举例有错[]:https://zhuanlan.zhihu.com/p/93641410
作为常量,计算过程可以放在编译器而不是运行期。
const和constexpr区别:
- const没有分出编译期常量和运行时常量
- constexpr 修饰指针时只对指针有效,与指针指向对象无关
2.
3.代用运算符
4.运算符优先级
- x++ + ++y + y; //后续的y是会收到前面的++y运算的影响的
5.存储类说明符
- auto
- register:自动存储期
- static:静态或线程存储期和内部连接
- extern:静态或线程存储期和外部连接
- thread_local:线程存储期
- mutable:不影响存储期或连接
6.const_cast
强制类型转换运算符
参考网址:[]:https://www.runoob.com/cplusplus/cpp-casting-operators.html
const_cast 运算符用于修改类型的 const / volatile 属性。除了 const 或 volatile 属性之外,目标类型必须与源类型相同。
修改一些指针/引用的权限
7.volatile
volatile ——定义类型为易变。
由于volatile 易变,因此不使用寄存器中的备份而使用其本身。
遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
8.什么情形要用到volatile
- 并行设备的硬件寄存器
- 多线程共享的变量
- 中断访问的非自动变量
9.一个变量可以既是const 又是 volatile吗
可以,一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
10.volatile操作是原子操作吗?
10.用变量a写出以下变量的定义
- 一个正整数 `` int a ;
- 一个指向整型数的指针 ``int *a;
- 一个指向整型指针的指针 ``int **a;
- 一个有10个整型数的数组 ``int a[10]; array<int,10> a;
- 一个有10个整型指针的数组 ``int *a[10];
- 一个指向有10整数的数组的指针 ``int (*a[10];
- 一个指向返回整型数的函数的指针 `` int (*a)(int);
- 一个有10个指针的数组,该指针指向一个函数,这个函数返回整型数和有一个整型参数`` int (*a[10])(int)
- 一个常量的指针 ``int const * a; const int* a;
- 一个指针常量``int * const a ;
- 一个常量的指针常量``int const* const a; const int* const a;
上次遇到这段还是有点不熟悉(09-03)
【入门视角】:[]:https://www.cnblogs.com/gis-lhx/p/12483203.html
其实还是得先从结合性优先级进行判断。
比如说区分指针函数和函数指针
他们本质区别是 指针变量 还是是 函数
通过加了()使得结合优先级发生变化
函数指针:int (*fun)(int x,int y); ()将与fun先结合起来 ,fun是一个指针
指针函数:int *fun(char *s1,char *s2);//将s2指向的字符串复制到s1中 这里的fun没有和 结合起来 所以是函数
再比如说指针数组与数组指针
指针数组int *p[n]; [ ]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
数组指针:int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n。
11. Lambda表达式
12.GCC相关的关键字
memory 破坏描述符 属于是内嵌汇编
(1)不要将该段内嵌汇编指令与前面的指令重新排序;也就是在执行内嵌汇编代码之前,它前面的指令都执行完毕。
(2)不要将变量缓存到寄存器,因为这段代码可能会用到内存变量,而这些内存变量会以不可预知的方式发生改变,因此 GCC 插入必要的代码先将缓存到寄存器的变量值写回内存,如果后面又访问这些变量,需要重新访问内存。
c语言如何进行内嵌汇编?
GCC 如何编译内嵌汇编代码:
[1] 输入变量与占位符
根据限定符和破坏描述部分,为输入和输出部分的变量分配合适的寄存器,如果限定符指定为立即数(“i”),或内存变量(“m”),则不需要该步骤,如果限定符没有具体指定输入操作数的类型(如“g”),GCC 会视需要决定是否将该操作数输入到某个寄存器。这样每个占位符都与某个寄存器、内存变量或立即数形成了一一对应的关系。对分配了寄存器的输入变量需要增加代码将它的值读入寄存器。另外还要根据破坏描述符的部分增加额外代码。
[2] 指令模板部分
然后根据这种一一对应的关系,用这些寄存器、内存变量或立即数来取代汇编代码中的占位符。
[3] 变量输出
按照输出限定符的指定将寄存器的内容输出到某个内存变量中,如果输出操作数的限定符指定为内存变量(“m”),则该步骤被省略。
13.inline关键字
为什么引入inline关键字:因为有些小函数如果被频繁调用的话,会大量消耗栈空间。
14.inline是强制命令吗?
inline只是对编译器的一种建议,而不是强制命令。最终决定实不实现的是编译器本身。编译器不会对太复杂的代码进行编译,尤其是一些含有复杂判断条件的。
15.inline的本质是什么?
inline的本质是将对函数的每一个调用都直接用代码进行替换。这样可以减小栈空间的使用。但是也存在别的问题,如果代码调用次数过多,会导致代码体积太大。
其次还可能造成额外的换页行为,然后造成更多的缓存不命中,最后反而运行时间增加。
16.inline 和宏函数的区别是什么?
- 执行的时间不同:inline是在编译阶段完成的,而宏函数是在预编译阶段完成的
- 语法检查:宏函数只是简单的文本替换,没有语法检查,有些优先级必须通过括号来强制执行,但是inline内联函数其本身就是一个正常的函数(自然要检查语法)
- inline 易于调试 , 而宏函数不易于调试。
14.static关键字
这个关键字也算是见得多了。
无非是从作用域和生命周期去谈
重点针对
本文来自博客园,作者:快乐过了阈值,转载请注明原文链接:https://www.cnblogs.com/black-worrior-2000/p/16565361.html
墨愁前路无知己,天下谁人不识君。
浙公网安备 33010602011771号