网站下载音乐,骨干专业建设网站,专业微网站营销,企业标准信息公共服务平台对前一篇文章写点随笔#xff1a;https://blog.csdn.net/weixin_43172531/article/details/132893176
基本数据类型(8种)和类型修饰符(4种)#xff1a;
void与指针*组合在一起才有具体实体意义。 void本身代表没有类型、没有实体#xff0c;例如void main(void)。
char c…对前一篇文章写点随笔https://blog.csdn.net/weixin_43172531/article/details/132893176
基本数据类型(8种)和类型修饰符(4种)
void与指针*组合在一起才有具体实体意义。 void本身代表没有类型、没有实体例如void main(void)。
char char[]为字符、字符串应该是运算成本最高的类型很多时候可以考虑强转为整数进行处理。 float double的运算代价也相对于整数更大也可以尽量考虑转换为整数处理。浮点数还有精度损失问题可以考虑转换为整数处理。定义结构体实现无限制精度PI的几十种无穷级数展开公式等。 int与short、long、signed、unsigned等修饰符的组合。目前一般int都定义为32bitlong定义为cpu字长。更安全的方式是i64 ui64这种定义方式。 _Bool类型兼容了bool未明确类型size老方案中定义bool为int时可以存任意非0的代表true_Bool类型不行了只有0、1。 _Complex为复数c99提供了内置的语法支持实际在此之前也可以用自定义结构体实现。新增这个内置类型可能是有些新的硬件内置了复数的存储和运算支持可以更好地利用硬件获得更高的运行效率。这也是硬件、数据结构、算法三位一体的设计体现。 _Imaginary为纯虚数一般编译器都不支持实际可能存在某些硬件层面的考虑但可被_Complex涵盖。
复杂类型(5种)
struct告诉编译器变量顺序存放。 union告诉编译器变量重叠存放。 enum常量定义。不要忽略null、count概念。 typedef类型别名。 sizeof获得类型的byte大小编译期计算。
实际只有struct、union两种类型定义方式实际也不是类型定义只是基础类型或者组合类型的内存排列方式的描述。编译器在编译期根据用户的定义去解释操作代码如何访问内存。机器码层面是没有复杂类型概念的只有01概念。其实也没有float、char的概念。但为了效率现代的高性能cpu、gpu、cpu可能在硬件层面对特定基础类型进行了优化有了特定指令。因此老的认知可能需要重新调整。
存储级别关键字(7种)
auto、static、register、extern、const、volatile、restrict都是对编译器的引导与内存的存储位置、访问方式、优化方式、链接方式等相关。
跳转结构(4种)
return 存储到eax寄存器 continue跳过for、while的一次循环但不跳出循环 break跳出for、while、switch goto最基础最原始的跳转基本很少用
分支结构(5种)
if 尽量不写复杂的判断拆开判断不容出错。 else 尽量不省略任何分支即使确定没有也写上输出错误信息。 switch case尽量用连续整数做case分支涉及编译器优化问题。将if 字符串判断转换为switch enum代码。 default分支不要忽略空这个概念。
循环结构(3种)
for尽量用for不容易出错。for(;;效率较高 do{break;}while(…)与while(…){break;} 容易出错。有些适用的场景。
左值lvalue右值rvalue
感觉左值与指针对象概念类似右值与地址值的概念类型。左值是有实体的内存对象右值是存储在某个地方的值或者某个对象的属性并不是一个有实体的对象。
inline
inline内联函数函数实现必须可见简单说inline函数必须在h文件中。 本质是给编译器在编译器一个内联的建议一是减少函数调用的上下文切换成本二是使得编译后的函数二进制码尽量内聚不跨页达到最优执行效率。 典型的面向编译器编程思想实际也带了一点面向硬件编程的思想。 同时存在跨平台、编译器问题。 对调试有一定影响。
_Alignas _Alignof
内存访问效率相关。一般边界建议是cpu字长例如64bit对应8byte边界对齐。 函数一般是0x10边界对齐。 页边界是4096实际大内存申请使用最优策略就是4096的整数倍且边界地址就在4096. 大内存被申请时不一定在缓存、内存中实际操作系统要等到第一次被访问时才会分配映射到虚地址上。那么尽量不memset 0内存其实是一个蛮好的策略。
_Atomic _Thread_local
用得少多线程边界资源共享读写的问题底层实现涉及硬件支持。参考典型模式即可。 我记得在很久以前有篇文章说cpp本质上不支持多线程安全目前看来硬件、语法、基础库都有扩展估计已经解决了这个老问题。 _Atomic可以修饰原子变量也可以修饰原子函数。保证操作不可中断。 atomic_fetch_add、atomic_load C11 引入了 threads.h 头文件来支持线程的创建、终止和管理。
#include threads.h
int thread_function(void *arg) {return 0;
}
int main() {thrd_t thread;thrd_create(thread, thread_function, NULL);thrd_join(thread, NULL);return 0;
}互斥量mtx_t
mtx_t mutex;
int shared_resource 0;
void access_resource() {mtx_lock(mutex);// ... manipulate shared resource ...mtx_unlock(mutex);
}条件变量cnd_t
#include threads.h
mtx_t mutex;
cnd_t cond;
int data_ready 0;
void producer() {// ... produce data ...mtx_lock(mutex);data_ready 1;cnd_signal(cond);mtx_unlock(mutex);
}
void consumer() {mtx_lock(mutex);while (!data_ready) {cnd_wait(cond, mutex);}// ... consume data ...mtx_unlock(mutex);
}_Generic
语法_Generic( expression, association-list )
#define TYPE_NAME(x) _Generic((x), \int: int, \float: float, \double: double, \default: other \
)感觉是为了弥补宏功能缺陷的。适用场景可以提高效率将部分运行期开销转移到编译期。 不同的数值类型选择适当的函数版本可以间接实现函数重载。
_Noreturn
明确函数的语义。避免编译报错、告警。
_Static_assert
编译期告警。方便进行代码的安全性检查例如对位域、union、struct的内存分布进行编译期检查避免跨平台出现问题。