前置知识
在 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 |
|