介绍了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 许可协议。转载请注明出处!