前置知识
在 Win32 程序中使用了许多在 OI 中很难涉及的东西,因此需要补充前置知识。
指针
指针的 const 修饰
const 可以修饰数据类型,也可以修饰指针变量。
常量指针(修饰数据类型)
const 修饰数据类型时,指针指向的地址可以改变,但指针指向的地址所对应的内容不可以改变。
1 2 3 4 | |
指针常量(修饰指针变量)
const 修饰指针变量时,指针指向的地址不可以改变,但指针指向的地址所对应的内容可以改变。
1 2 3 4 | |
Tip
修饰指针变量时,*const 只作用于后面的变量,如果有 int *const p = &a, c = 0;,那么 c 只是一个 int 型的变量;修饰数据类型时,const 作用于数据类型,可以作用于同一个语句中定义的所有变量,即 const int *p = &a, c = 0; 中 c 的数据类型为 const int。
值得注意的是,const int 和 int const 等价,即 int const a = 0, b = 0; 中 a 和 b 都是 const int 类型。
指针的 typedef
指针的 typedef 写作 typedef int *Pint;,在声明变量时,Pint p; 就和 int *p; 等价了。同样,若 typedef const int *Pint;,则 Pint p; 和 const int *p; 等价;若 typedef int *const Pint;,则 Pint p; 和 int *const p; 等价。值得注意的是,若 typedef int *Pint;,则 const Pint p; 与 Pint *const p; 等价。
至于 const 的作用范围,typedef const int *Pint, tni; 中 const 修饰 int,即 tni 为 const int 类型;typedef int *const Pint, tni; 中 *const 修饰 Pint,即 tni 为 int 类型。
const_cast
当你写下这样的语句:
1 2 | |
你会发现在 G++ 中有这样的警告:ISO C++ forbids converting a string constant to 'STR' {aka 'char*'},而在 MSVC 中过不了编译。这是因为我们将一个字符串常量赋值给了一个字符串变量。正确的赋值方法是这样:
1 2 | |
switch 语句
你可能会问,这有什么好讲的呢?
switch 语句实际上相当于一个 goto,会从一个符合条件的 case 标记后运行。这也就解释了需要 break 的原因,因为 case 就相当于是一个 goto 的标记,程序是跳转到 case 后并一直向后运行的,因此如果不 break 就会运行到后面不应该运行的代码。
值得注意的是,如果 goto 到了一个变量的作用域中,这个程序非良构,switch 也是同理,例如:
1 2 3 4 5 6 7 8 9 10 11 | |
在这个例子中,变量 x 的作用域是整个 switch 语句,但如果 n 的值不是 \(1\),就会跳过 x 的定义。此时 g++ 会给你一个警告,但 MSVC 甚至不会让你通过编译。所以在使用 switch 语句时,一定要注意限制定义在 switch 语句内变量的作用域,就像这样:
1 2 3 4 5 6 7 8 9 10 11 12 | |