C--圣经中的C++基本技巧(老鸟勿入)by dongbinghua
[Skill 1]:int i = 5, // i
j = 10, // j
k = 18; // Assign eighteen to k[Skill 2]:int i = 777;
i = !!i; // if (i != 0) i = 1;[Skill 3]:bool bFlag;
char ch;
bFlag = ch != 'y'; // how beatiful... :)[Skill 4]:
int Val, One = 1, Two = 2, Three = 3;
Val = (One, --Two, Three + 3); // now Val = 6, ',' operator return the last expression's result
Val = One++, Two, Three; // Val = 1[Skill 5]:
// 如果MoreData() 返回真,那么MoreTime()不会被调用,...如果MoreTime() 里面有很重要的代码...将不会被执行...寒..
if ((MoreData() || MoreTime()))
{
// do something...
}
// 同理, 如果--aCounter 为 0 的话,....bCounter不再会被计算.
if (--aCounter && --bCounter)
{
// do something...
}[Skill 5]:
// only CPP can use this, C cannot.
int i(3), b(4), c(5); // int i = 3, b = 4, c = 5;
char ch('A');
float Val(12.34);[Skill 6]:
// 参数个数可变函数...需要特殊处理
void DoList(int, ...)
{
// do something...
}[Skill 7]:
// 无名函数形参
int Func(int x, int)
{
return x * 2;
}
void main()
{
Func(2, 3)
}
[Skill 8]:
// 全局变量 [ 注意全局作用解析符 :: ]
int Counter = 10; // 默认为
static int Val = 50; // 本文件内有效 file-scope variable
extern int Big = 100; // 使用另外一个文件申明的全局变量 Big, 本项目内有效
void main()
{
int Counter;
Counter = ::Counter; // :: 引用全局, because ::Counter = 10;
}[Skill 9]:
// 局部变量 四种存储类型 auto, static, extern, register
void CallMe(void)
{
auto int i = 500; // 每次执行CallMe(); 都产生一个 i, 并赋值为500
static int j = 60; // 只在第一次执行CallMe()时执行赋值, 以后j将保持上次执行时的值, j 不会消亡.
extern int k; // 使用另外一个文件申明的全局变量 k, 本函数内有效
register int l; // 寄存器变量, 程序无法取得其地址&l, 其他都和 auto 一样 [可能会提高程序运行速度]
}[Skill 10]:
// const & volatle
void main()
{
const int Max = 50; // Max的值不能再被修改
volatile int Value = 30; // Value的值可能会被其他什么东西修改
for (int i = 0; i < Value; i++) // 每次CPU都要去提取内存中 Value 的值,而不是Cache或Register中的备份
{
// do something...
}
}[Skill 11]:
// 结构体申明的时候不会分配内存...
struct Date
{
short month, day, year;
};
// 申明变量
struct Date Birthday;
Date Sunday; // 省略 struct 关键字 C++专有, C不行
Date Dt = {7, 12, 1981}; // 初始化, {}中值可以少(少了的自动清零)如 {7, 12, }, 但不可以多, 也不可以是这样赋值 {7, , 1981}[Skill 12]:
// union 的使用
union Holder
{
char holdchar;
short holdint;
long holdlong;
float holdfloat;
}; // 注意';', sizeof(Holder) = sizeof(long), union的大小等于最大的数据成员
void main()
{
Holder hld = {'X'}; // 联合只能对第一个变量成员进行初始化
hld.holdchar = 'A';
cout << hld.holdchar;
hld.holdfloat = 123.456;
cout << hld.holdfloat;
}[Skill 13]:
// 注意: 如果是全局匿名联合必须申明为静态的
union
{
int today, balance; // today, balance共用一块内存区
}
today = 23;
cout << today;
balance = 10;
cout << balance;[Skill 14]:
enum Colors {Red = 5, Green = 7, Blue}
Colors col = 8; // now col = Blue :)[Skill 15]:
int Zones[5] = {1, 2, 3, 4, 5}; // 可以一样多, 和 char 数组不一样
int Numbers[10] = {1}; // 可以少, 其余的自动清零
int BigBlockMem[62253] = {0}; // 全部清零
int MultiArray[20][30][40] = {0}; /* or {{0}, {0}, {0}} */ // 全部清零char str[] = "Hello, My Friend!";
int i = 0;
while (str[i] != '\0')
{
count << str[i++]; // notice: i++... how beautiful
}[Skill 16]:
int ** ppMyAge; // pointer to int pointer
// 指针加减一个整数,实际是加上或减去它指向的数据类型的长度// 以下三个函数申明完全一样,最后的 25 将被编译器忽略
void ErrMsg(char * msg); 
void ErrMsg(char msg[]);
void ErrMsg(char msg[25]);[Skill 17]:
// 函数指针
int MyFunction(), YourFunction(); // Hei Hei...
int (*fptr)(); // 申明一个函数指针, 指向一个返回整形,无参数的函数
fptr = MyFunction; // 或者 fptr = &MyFunction 两种形式都可以使用
int x = fptr(); // 或者 int x = (*fptr)(); const char str[] = "A good day";
char * ptr = str; // Err
const char * ptr = str; // OK
void foo(char * ps);
void bar(const char * ps);
foo(ptr); // Err
bar(ptr); // OK[Skill 18]
int i, j; // int variables
int * ip; // pointer to int variables
int ** ipp; // pointer to int pointer
ip = & i; // assign
j = * ip; // assign[Skill 19] // Name Space
namespace MyNames
{
int Val1 = 10;
int Val2 = 20;
}
namespace MyOtherNames
{
int Val1 = 30;
int Val2 = 50;
}using namespace std;
using namespace MyNames;
using namespace MyOtherNames;
int main()
{
Val1 = 100; // Err
MyNames::Val1 = 100; // Good return 0;
}// 嵌套名字空间
namespace MyNames
{
int Val1 = 10;
int Val2 = 20; namespace MyInnerNames
{
int Val3 = 30;
int Val4 = 40;
}
}
std::cout << MyNames::MyInnerName::Val3 << std::endl;// 无名名字空间
// 无名名字空间中定义的标识符被设置为全局的名字空间
namespace
{
int Val1 = 10;
int Val2 = 20;
}
// 名字空间的别名
namespace MyNames
{
int Val1 = 10;
int Val2 = 20;
}
namespace MyAlias = MyNames;
std::cout << MyAlias::Val1 << std::endl;
// 预处理指令篇
[Skill 20]
# // 空指令, 没有任何效果.
#include // 包含一个源文件 
#define // 定义宏
#undef // 取消已经定义的宏
#if // 如果为真,则编译下面的代码
#ifdef // 如果给定的宏已定义,则编译下面的代码
#ifndef // 如果给定的宏没有定义,则编译下面的代码
#elif // 如果前面 #if 给定条件不为真,而当前给定条件为真,则编译下面代码
#endif // 结束一个#if.. #else 的条件编译块
#error // 停止编译并显示错误信息
#include <io.h> // 搜索编译器自带的头文件
#include "io.h" // 先搜索当前目录,找不到再搜索编译器自带的头文件#define Error(n) std::cout << "Error: " << n << endl预处理指令 ## 运算符
#define Link(a, b, c) a##b##c
unsigned long i = Link(11, 22, 33); // then i = 112233;--end
recorder: http://www.pcpig.com/