介绍了C++一些基础知识,遇到的坑
整数类型转换
1 |
|
输出: 0, 1. 即 x > y, m < n. int与unsigned int进行比较时会都转成unsigned int,因此 x > y;short与unsigned short比较时会都转成int,因为C 标准规定,当进行整数提升时,如果 int 类型可以表示原始类型的所有值时,它就被转换为 int 类型;不然则被转换为 unsigned int 。因此m < n.
1 | uint64_t x = (1 << 52) // warning, 位移超过最大位, 因为 1 是 int 型的 |
关于 char、unsigned char、signed char
先说结论,它们是不一样的。
cppquiz里的一道题
1 |
|
输出:0
之前实习时碰到的一个坑,函数重载时,signed char和unsigned char会优先走int那条路。如下:
1 |
|
输出两个int.
volatile
意思为脆弱的易变的,用来防止编译器对其优化。因此其用途一般有以下三种:
- 外部设备寄存器映射后的内存 —— 因为外部寄存器随时可能由于外部设备的状态变化而改变,因此映射后的内存需要用 volatile 来修饰。
- 多线程或异步访问的全局变量。
- 嵌入式编程 —— 防止编译器对其优化。
volatile保证在访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器中缓存的值。对于第二种多线程情况下的使用,对volatile变量进行操作时也是需要加锁的。
数组和指针
1 |
|
输出:
1 | a: 280353f0 |
可以看出对数组,a, &a, &a[0]的值都是一样的,都是数组a的首地址。指针本身是一个变量同样占用了栈空间,地址为&p。p保存了int(10)的地址,对其进行’*’操作可以从这个地址中取值。
1 |
|
输出:
1 | &a[0][0] address is 0x36A30E20 |
可以发现 &a[0][0] 、 &a[0] 、 a ,还有 &a 的地址值都是相同的,然而其步进 1 即地址 +1 的值却完全不同。
因为尽管这几个变量的地址相同,但是其变量类型却是不同的:
&a[0][0]的类型是int *p,所以步长为 4 字节。&a[0]的类型为int *p[3],所以步长为 12 字节。a的类型也为int *p[3],所以其步长也为 12 字节。&a的类型为int *p[2][3],所以其步长为 24 字节。
union
联合体 union 内元素公用一片内存
1 | union{ |
可以得到float y的每一位bit值
也可以知道是大端存储还是小端存储,因为地址起始位置相同:u.x = 1;
那么若 u.c == 1 就是小端存储。
- 本文作者: JiXiaw
- 本文链接: http://jixiaw.github.io/2021/02/05/c++/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!