Saturday, December 10, 2011

What I should do during the winter vacation

The last class was over today. There are three finals and a project need to do. I think it is necessary to make a plan before the beginning of the vacation, which could make the plan more aggressive and ambitious. Now what is in my mind is as followed:

  1. do some ACM-ICPC problems. The best way to do it may be not by “Interview street”, as Lanbo told me that the problem there is a little complicated. I think I could find some problem from those blogs. I think I could do 30 or 40 and ensure the answers are correct;
  2. Get more familiar with CUDA, OpenCV, numerical calculation and matrix computation;

There may be something more, to be continued.

Thursday, December 8, 2011

How to verify the unique min-cut

How to verify that there is only one min-cut in a graph G(V, E), which have one sink, t, and a source, s. The first idea is as followed:
  • run the max-flow algorithm, such as Ford-Fulkerson or Edmonds-Karp, and keep the residual graph as G`.
  • run DFS, from s and t, on G` and find out a reachable set R1 and R2.
  • if and only if R1 + R2 = E, then return true, otherwise, return false.
This method uses a constraint of min-cut that all the edges through a min-cut in a max-flow graph have 0 capacity. So, if there are two min-cut, there must be another “bottleneck” that does not allow DFS to reach the node.
For a directed graph G(V, E). We could do the following to verify the unique or not.
  • run the max-flow algorithm;
  • for each edge e though the min cut, increase the capacity;
  • if the max flow does not change, the min cut is not unique; otherwise, it is unique.

Monday, December 5, 2011

VC/C++ 变量命名规则

一、程序风格:

1、严格采用阶梯层次组织程序代码:

各层次缩进的分格采用VC的缺省风格,即每层次缩进为4格,括号位于下一行。要求相匹配的大括号在同一列,对继行则要求再缩进4格。例如:

2、提示信息字符串的位置

在程序中需要给出的提示字符串,为了支持多种语言的开发,除了一些给调试用的临时信息外,其他所有的提示信息必须定义在资源中。

3、对变量的定义,尽量位于函数的开始位置。

二、命名规则:

1、变量名的命名规则

①、变量的命名规则要求用“匈牙利法则”。即开头字母用变量的类型,其余部分用变量的英文意思或其英文意思的缩写,尽量避免用中文的拼音,要求单词的第一个字母应大写。

即: 变量名=变量类型+变量的英文意思(或缩写)

对非通用的变量,在定义时加入注释说明,变量定义尽量可能放在函数的开始处。

见下表:

bool(BOOL)   用b开头   bIsParent   

byte(BYTE)   用by开头   byFlag   

short(int)   用n开头   nStepCount   

long(LONG)   用l开头   lSum   

char(CHAR)   用c开头   cCount   

float(FLOAT)   用f开头   fAvg   

double(DOUBLE)   用d开头   dDeta   

void(VOID)   用v开头   vVariant   

unsigned   int(WORD) 用w开头   wCount   

unsigned   long(DWORD)   用dw开头   dwBroad   

HANDLE(HINSTANCE) 用h开头   hHandle   

DWORD   用dw开头   dwWord   

LPCSTR(LPCTSTR)   用str开头   strString   

用0结尾的字符串 用sz开头   szFileName   

对未给出的变量类型要求提出并给出命名建议给技术委员会。

②、指针变量命名的基本原则为:

对一重指针变量的基本原则为:

“p”+变量类型前缀+命名

如一个float*型应该表示为pfStat   

对多重指针变量的基本规则为:

二重指针:   “pp”+变量类型前缀+命名

三重指针:   “ppp”+变量类型前缀+命名

......   

③、全局变量用g_开头,如一个全局的长型变量定义为g_lFailCount,即:变量名=g_+变量类型+变量的英文意思(或缩写)

④、静态变量用s_开头,如一个静态的指针变量定义为s_plPerv_Inst,即: 变量名=s_+变量类型+变量的英文意思(或缩写)

⑤、成员变量用m_开头,如一个长型成员变量定义为m_lCount;即:变量名=m_+变量类型+变量的英文意思(或缩写)

⑥、对枚举类型(enum)中的变量,要求用枚举变量或其缩写做前缀。并且要求用大写。

如:enum   cmEMDAYS   

{   

EMDAYS_MONDAY;   

EMDAYS_TUESDAY;   

……   

};   

⑦、对struct、union、class变量的命名要求定义的类型用大写。并要加上前缀,其内部变量的命名规则与变量命名规则一致。

结构一般用S开头

如:struct   ScmNPoint   

{   

int   nX;//点的X位置

int   nY;   //点的Y位置

};   

联合体一般用U开头

如:   union   UcmLPoint   

{   

long   lX;   

long   lY;   

}   

类一般用C开头

如:

class   CcmFPoint   

{   

public:   

float   fPoint;   

};   

对一般的结构应该定义为类模板,为以后的扩展性考虑

如:

template   

class   CcmTVector3d   

{   

public:   

TYPE   x,y,z;   

};   

⑧、对常量(包括错误的编码)命名,要求常量名用大写,常量名用英文表达其意思。

如:#define   CM_FILE_NOT_FOUND   CMMAKEHR(0X20B)   其中CM表示类别。

⑨、对const   的变量要求在变量的命名规则前加入c_,即:c_+变量命名规则;例如:

const   char*   c_szFileName;   

2、 函数的命名规范:

函数的命名应该尽量用英文表达出函数完成的功能。遵循动宾结构的命名法则,函数名中动词在前,并在命名前加入函数的前缀,函数名的长度不得少于8个字母。

例如:

long   cmGetDeviceCount(……);   

3、函数参数规范:

①、 参数名称的命名参照变量命名规范。

②、 为了提高程序的运行效率,减少参数占用的堆栈,传递大结构的参数,一律采用指针或引用方式传递。

③、 为了便于其他程序员识别某个指针参数是入口参数还是出口参数,同时便于编译器检查错误,应该在入口参数前加入const标志。如:

……cmCopyString(const   char   *   c_szSource,   char   *   szDest)   

4、引出函数规范:

对于从动态库引出作为二次开发函数公开的函数,为了能与其他函数以及Windows的函数区分,采用类别前缀+基本命名规则的方法命名。例如:在对动态库中引出的一个图象编辑的函数定义为   imgFunctionname(其中img为image缩写)。

现给出三种库的命名前缀:

①、 对通用函数库,采用cm为前缀。

②、 对三维函数库,采用vr为前缀。

③、 对图象函数库,采用img为前缀。

对宏定义,结果代码用同样的前缀。

5、文件名(包括动态库、组件、控件、工程文件等)的命名规范:

文件名的命名要求表达出文件的内容,要求文件名的长度不得少于5个字母,严禁使用象file1,myfile之类的文件名。

三、注释规范:

1、函数头的注释

对于函数,应该从“功能”,“参数”,“返回值”、“主要思路”、“调用方法”、“日期”六个方面用如下格式注释:   

//程序说明开始

//================================================================//   

//   功能: 从一个String   中删除另一个String。

//   参数:   strByDelete,strToDelete   

//   (入口)   strByDelete:   被删除的字符串(原来的字符串)

//   (出口)   strToDelete:   要从上个字符串中删除的字符串。

//   返回: 找到并删除返回1,否则返回0。(对返回值有错误编码的要//   求列出错误编码)。

//   主要思路:本算法主要采用循环比较的方法来从strByDelete中找到

//   与strToDelete相匹配的字符串,对多匹配strByDelete   

//   中有多个strToDelete子串)的情况没有处理。请参阅:

//   书名......   

//   调用方法:......   

//   日期:起始日期,如:2000/8/21.9:40--2000/8/23.21:45   

//================================================================//   

函数名(……)   

//程序说明结束

①、 对于某些函数,其部分参数为传入值,而部分参数为传出值,所以对参数要详细说明该参数是入口参数,还是出口参数,对于某些意义不明确的参数还要做详细说明(例如:以角度作为参数时,要说明该角度参数是以弧度(PI),还是以度为单位),对既是入口又是出口的变量应该在入口和出口处同时标明。等等。

②、 函数的注释应该放置在函数的头文件中,在实现文件中的该函数的实现部分应该同时放置该注释。

③、 在注释中应该详细说明函数的主要实现思路、特别要注明自己的一些想法,如果有必要则应该写明对想法产生的来由。对一些模仿的函数应该注释上函数的出处。

④、 在注释中详细注明函数的适当调用方法,对于返回值的处理方法等。在注释中要强调调用时的危险方面,可能出错的地方。

⑤、 对日期的注释要求记录从开始写函数到结束函数的测试之间的日期。

⑥、 对函数注释开始到函数命名之间应该有一组用来标识的特殊字符串。

如果算法比较复杂,或算法中的变量定义与位置有关,则要求对变量的定义进行图解。对难以理解的算法能图解尽量图解。

2、变量的注释:

对于变量的注释紧跟在变量的后面说明变量的作用。原则上对于每个变量应该注释,但对于意义非常明显的变量,如:i,j等循环变量可以不注释。

例如:   long   lLineCount   //线的根数。

3、文件的注释:

文件应该在文件开头加入以下注释:

/////////////////////////////////////////////////////////////////////   

//   工程:   文件所在的项目名。

//   作者:**,修改者:**   

//   描述:说明文件的功能。

//   主要函数:…………   

//   版本:   说明文件的版本,完成日期。

//   修改:   说明对文件的修改内容、修改原因以及修改日期。

//   参考文献:   ......   

/////////////////////////////////////////////////////////////////////   

为了头文件被重复包含要求对头文件进行定义如下:   

#ifndef   __FILENAME_H__   

#define   __FILENAME_H__   

其中FILENAME为头文件的名字。

4、其他注释:

在函数内我们不需要注释每一行语句。但必须在各功能模块的每一主要部分之前添加块注释,注释每一组语句,在循环、流程的各分支等,尽可能多加以注释。

其中的循环、条件、选择等位置必须注释。

对于前后顺序不能颠倒的情况,建议在注释中增加序号。

例如:

在其他顺序执行的程序中,每隔3—5行语句,必须加一个注释,注明这一段语句所组成的小模块的作用。对于自己的一些比较独特的思想要求在注释中标明。

四、程序健壮性:

1、函数的返回值规范:

对于函数的返回位置,尽量保持单一性,即一个函数尽量做到只有一个返回位置。(单入口单出口)。

要求大家统一函数的返回值,所有的函数的返回值都将以编码的方式返回。

例如编码定义如下:

#define   CM_POINT_IS_NULL   CMMAKEHR(0X200)   

:   

:   

建议函数实现如下:

long   函数名(参数,……)   

{   

long   lResult;   //保持错误号

lResult=CM_OK;   

//如果参数有错误则返回错误号

if(参数==NULL)   

{   

lResult=CM_POINT_IS_NULL;   

goto   END;   

}   

……   

END:   

return   lResult;   

}   

2、关于goto的应用:

对goto语句的应用,我们要求尽量少用goto语句。对一定要用的地方要求只能向后转移。

3、资源变量的处理(资源变量是指消耗系统资源的变量):

对资源变量一定赋初值。分配的资源在用完后必须马上释放,并重新赋值。

4、对复杂的条件判断,为了程序的可读性,应该尽量使用括号。

例:if(((szFileName!=NULL)&&(lCount> =0)))||(bIsReaded==TRUE))   

五、可移植性:

1、高质量的代码要求能够跨平台,所以我们的代码应该考虑到对不同的平台的支持,特别是对windows98和windowsnt的支持。

2、由于C语言的移植性比较好,所以对算法函数要求用C代码,不能用C++代码。

3、对不同的硬件与软件的函数要做不同的处理。

a Array 数组

b BOOL (int) 布尔(整数)

by Unsigned Char (Byte) 无符号字符(字节)

c Char 字符(字节)

cb Count of bytes 字节数

cr Color reference value 颜色(参考)值

cx Count of x (Short) x的集合(短整数)

dw DWORD (unsigned long) 双字(无符号长整数)

f Flags (usually multiple bit values) 标志(一般是有多位的数值)

fn Function 函数

g_ global 全局的

h Handle 句柄

i Integer 整数

l Long 长整数

lp Long pointer 长指针

m_ Data member of a class 一个类的数据成员

n Short int 短整数

p Pointer 指针

s String 字符串

sz Zero terminated String 以0结尾的字符串

tm Text metric 文本规则

u Unsigned int 无符号整数

ul Unsigned long (ULONG) 无符号长整数

w WORD (unsigned short) 无符号短整数

x,y x, y coordinates (short) 坐标值/短整数

v void 空

有关项目的全局变量用g_开始,类成员变量用m_,局部变量若函数较大则可考虑用l_用以显示说明其是局部变量。

前缀 类型 例子

g_ 全局变量 g_Servers

C 类或者结构体 CDocument,CPrintInfo

m_ 成员变量 m_pDoc,m_nCustomers

VC常用前缀列表:

前缀 类型 描述 例子

ch char 8位字符 chGrade

ch TCHAR 16位UNICODE类型字符 chName

b BOOL 布尔变量 bEnabled

n int 整型(其大小由操作系统决定) nLength

n UINT 无符号整型(其大小由操作系统决定) nLength

w WORD 16位无符号整型 wPos

l LONG 32位有符号整型 lOffset

dw DWORD 32位无符号整型 dwRange

p * Ambient memory model pointer 内存模块指针,指针变量 pDoc

lp FAR* 长指针 lpDoc

lpsz LPSTR 32位字符串指针 lpszName

lpsz LPCSTR 32位常量字符串指针 lpszName

lpsz LPCTSTR 32位UNICODE类型常量指针 lpszName

h handle Windows对象句柄 hWnd

lpfn (*fn)() 回调函数指针 Callback Far pointer to CALLBACK function lpfnAbort

Windows对象名称缩写:

Windows对象例子变量 MFC类 例子对象

HWND hWnd; CWnd* pWnd;

HDLG hDlg; CDialog* pDlg;

HDC hDC; CDC* pDC;

HGDIOBJ hGdiObj; CGdiObject* pGdiObj;

HPEN hPen; CPen* pPen; 

HBRUSH hBrush; CBrush* pBrush; 

HFONT hFont; CFont* pFont; 

HBITMAP hBitmap; CBitmap* pBitmap; 

HPALETTE hPalette; CPalette* pPalette; 

HRGN hRgn; CRgn* pRgn; 

HMENU hMenu; CMenu* pMenu; 

HWND hCtl; CStatic* pStatic; 

HWND hCtl; CButton* pBtn;

HWND hCtl; CEdit* pEdit; 

HWND hCtl; CListBox* pListBox;

HWND hCtl; CComboBox* pComboBox;

VC常用宏定义命名列表:

前缀 符号类型符号例子 范围

IDR_ 标识多个资源共享的类型 IDR_MAINFRAME 1~0x6FFF

IDD_ 对话框资源(Dialog) IDD_SPELL_CHECK 1~ 0x6FFF

HIDD_ 基于对话框的上下文帮助 HIDD_SPELL_CHECK 0x20001~0x26FF

IDB_ 位图资源(Bitmap) IDB_COMPANY_LOGO 1~0x6FFF

IDC_ 光标资源(Cursor) IDC_PENCIL 1~0x6FFF

IDI_ 图标资源(Icon) IDI_NOTEPAD 1~0x6FFF

ID_、IDM_ 工具栏或菜单栏的命令项 ID_TOOLS_SPELLING 0x8000~0xDFFF

HID_ 命令上下文帮助 HID_TOOLS_SPELLING 0x18000~0x1DFFF

IDP_ 消息框提示文字资源 IDP_INVALID_PARTNO 8~0xDFFF

HIDP_ 消息框上下文帮助 HIDP_INVALID_PARTNO 0x30008~0x3DFFF

IDS_ 字符串资源(String) IDS_COPYRIGHT 1~0x7FFF

IDC_ 对话框内的控制资源 IDC_RECALC 8~0xDFFF

Microsoft MFC宏命名规范 

名称 类型

_AFXDLL 唯一的动态连接库(Dynamic Link Library,DLL)版本

_ALPHA 仅编译DEC Alpha处理器

_DEBUG 包括诊断的调试版本

_MBCS 编译多字节字符集

_UNICODE 在一个应用程序中打开Unicode

AFXAPI MFC提供的函数

CALLBACK 通过指针回调的函数 

库标识符命名法

标识符 值和含义

u ANSI(N)或Unicode(U)

d 调试或发行:D = 调试;忽略标识符为发行

静态库版本命名规范

库 描述

NAFXCWD.LIB 调试版本:MFC静态连接库

NAFXCW.LIB 发行版本:MFC静态连接库

UAFXCWD.LIB 调试版本:具有Unicode支持的MFC静态连接库

UAFXCW.LIB 发行版本:具有Unicode支持的MFC静态连接库

动态连接库命名规范 

名称 类型

_AFXDLL 唯一的动态连接库(DLL)版本

WINAPI Windows所提供的函数

Windows.h中新的命名规范 

类型 定义描述

WINAPI 使用在API声明中的FAR PASCAL位置,如果正在编写一个具有导出API人口点的DLL,则可以在自己的API中使用该类型

CALLBACK 使用在应用程序回调程序,如窗口和对话框过程中的FAR PASCAL的位置

LPCSTR 与LPSTR相同,只是LPCSTR用于只读串指针,其定义类似(const char FAR*)

UINT 可移植的无符号整型类型,其大小由主机环境决定(对于Windows NT和Windows 9x为32位);它是unsigned int的同义词

LRESULT 窗口程序返回值的类型

LPARAM 声明lParam所使用的类型,lParam是窗口程序的第四个参数

WPARAM 声明wParam所使用的类型,wParam是窗口程序的第三个参数

LPVOID 一般指针类型,与(void *)相同,可以用来代替LPSTR

Google C++ 编码风格精简

  Google C++ 编码风格精简

头文件:

1.头文件防多重定义define格式:<PROJECT>_<PATH>_<FILE>_H_

2.能使用前置声明尽量不用头文件包含

3.只有当函数只有 10 行甚至更少时才将其定义为内联函数(注意虚函数,递归函数,以及使用了循环语句的函数)

4.复杂的内联函数的定义, 放在后缀名为 -inl.h 的头文件中

5.定义函数时,输入参数永远放在输出参数之前

6.项目内头文件应按照项目源代码目录树结构排列

7.example.cc包含头文件顺序:example.h,C系统文件,C++ 系统文件,其他库的h文件,本项目内h文件

作用域:

1.在.cc文件中, 允许甚至鼓励使用匿名名字空间;不要在h文件中使用匿名名字空间 

2.在.cc文件.h文件的函数, 方法或类中, 可以使用 "using"关键字 及 名字空间别名 

3.不要将嵌套类定义成公有, 除非它们是接口的一部分, 比如, 嵌套类含有某些方法的一组选项

4.使用静态成员函数或名字空间内的非成员函数, 尽量不要用裸的全局函数 

5.将函数变量尽可能置于最小作用域内, 并在变量声明时进行初始化

6.禁止使用 class 类型的静态或全局变量: 它们会导致很难发现的 bug 和不确定的构造和析构函数调用顺序

类:

1.构造函数中只进行那些没什么意义的初始化, 可能的话, 使用 Init() 方法集中初始化有意义的数据

2.如果一个类定义了若干成员变量又没有其它构造函数, 必须定义一个默认构造函数

3.对单个参数的构造函数使用 C++ 关键字 explicit(如果构造函数只有一个参数, 可看成是一种隐式转换)

4.仅在代码中需要拷贝一个类对象的时候使用拷贝构造函数; 大部分情况下都不需要, 此时应使用 DISALLOW_COPY_AND_ASSIGN

{

#define DISALLOW_COPY_AND_ASSIGN(TypeName) /

TypeName(const TypeName&); /

void operator=(const TypeName&)

}

5.仅当只有数据时使用 struct, 其它一概使用 class

6.使用组合常常比使用继承更合理. 如果使用继承的话, 定义为 public 继承

7.如果你的类有虚函数, 则析构函数也应该为虚函数

8.当重载一个虚函数, 在衍生类中把它明确的声明为 virtual

9.只在以下情况我们才允许多重继承: 最多只有一个基类是非抽象类; 其它基类都是以Interface为后缀的纯接口类

10.接口是指满足特定条件的类, 这些类以 Interface 为后缀 (不强制).

11.尽量不要重载运算符

12.数据成员在任何情况下都必须是私有的, 并根据需要提供相应的存取函数

13.在类中使用特定的声明顺序: public: 在 private: 之前, 成员函数在数据成员前

14.如果函数超过 40 行, 可以思索一下能不能在不影响程序结构的前提下对其进行分割

Google奇技:

1.尽量避免使用智能指针(任何情况下都不要使用 auto_ptr),使用时也尽量局部化

2.使用 cpplint.py 检查风格错误

C++特性:

1. 输入参数是值参或 const 引用, 输出参数为指针.

2.仅在输入参数类型不同, 功能相同时使用重载函数 (含构造函数)

3.不允许使用缺省函数参数

4.不允许使用变长数组和 alloca()

5.不要在 Google 的开源项目中使用异常(关于这一点google仅仅是为了自身方便=。=)

6.禁止使用RTTI

7.使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式

{

用 static_cast 替代 C 风格的值转换, 或某个类指针需要明确的向上转换为父类指针时

用 const_cast 去掉 const 限定符

用 reinterpret_cast 指针类型和整型或其它指针之间进行不安全的相互转换. 仅在你对所做一切了然于心时使用 dynamic_cast 测试代码以外不要使用. 除非是单元测试, 如果你需要在运行时确定类型信息, 说明有 设计缺陷

}

8.只在记录日志时使用流

9.对迭代器和模板类型, 使用前置自增 (自减).对简单数值 (非对象)无所谓

10.强烈建议你在任何可能的情况下都要使用 const

{

如果函数不会修改传入的引用或指针类型参数, 该参数应声明为 const.

尽可能将函数声明为 const. 访问函数应该总是 const. 其他不会修改任何数据成员, 未调用非 const 函数, 不会返回数据成员非 const 指针或引用的函数也应该声明成 const.

如果数据成员在对象构造之后不再发生变化, 可将其定义为 const.

}

11.C++ 内建整型中, 仅使用 int. 如果程序中需要不同大小的变量, 可以使用 <stdint.h> 中长度精确的整型, 如 int16_t

12.使用断言来指出变量为非负数, 而不是使用无符号型

13.代码应该对 64 位和 32 位系统友好(!!!)

14.使用宏时要非常谨慎, 尽量以内联函数, 枚举和常量代替之

{

不要在 .h 文件中定义宏

在马上要使用时才进行 #define, 使用后要立即 #undef

不要只是对已经存在的宏使用#undef,选择一个不会冲突的名称

不要试图使用展开后会导致 C++ 构造不稳定的宏, 不然也至少要附上文档说明其行为

}

15.整数用 0, 实数用 0.0, 指针用 NULL, 字符 (串) 用 '/0'

16.尽可能用 sizeof(varname) 代替 sizeof(type)

17.只使用 Boost 中被认可的库

命名约定:

1.函数命名, 变量命名, 文件命名应具备描述性; 不要过度缩写. 类型和变量应该是名词, 函数名可以用 “命令性” 动词

2.文件名要全部小写, 可以包含下划线 (_) 或连字符 (-). 按项目约定来.

3.类型名称的每个单词首字母均大写, 不包含下划线: MyExcitingClass, MyExcitingEnum.

4.变量名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾:my_local_variable,my_member_variable_

5.结构体的数据成员可以和普通变量一样, 不用像类那样接下划线

6.常量命名 在名称前加 k,接大写字母开头的单词

7.函数名的每个单词首字母大写, 没有下划线,取值和设值函数要与存取的变量名匹配.非常短小的内联函数名也可以用小写字母

8.名字空间用小写字母命名, 并基于项目名称和目录结构: google_awesome_project.

9.枚举的命名应当和常量一致: kEnumName.

代码注释:

1.使用行注释或块注释,统一就好

2.在每一个文件开头加入版权公告,然后是文件内容描述

{

版权;

许可版本:Apache2.0 BSD LGPL GPL;

作者;

文件内容

}

3.每个类的定义要附着类的功能和用法的注释

4.函数声明处注释描述函数功能,定义处描述函数实现

5.类数据成员应注释说明用途,是否可以接受NULL或-1等警戒值

6.全局变量注释说明含义和用途

7.复杂代码前要加注释;比较隐晦的代码后空两格加行尾注释

8.向函数传入整型,布尔值和指针时,注释说明含义,或使用常量让代码望文知意

9.临时,短期,或不够完美的解决方案使用TODO注释;格式//TODO(ID):Information

格式:

1.每一行长度不要超过80(路径,URL,头文件保护除外)

2.尽量不使用非ASCII字符,使用时必须使用UTF-8字符

3.只使用空格,每次缩进两个空格

4.函数声明:返回值和函数名在同一行,参数也尽量放在同一行

{

返回值总是和函数名在同一行;

左圆括号总是和函数名在同一行;

函数名和左圆括号间没有空格

圆括号与参数间没有空格;

左大括号总在最后一个参数同一行的末尾处 ;

右大括号总是单独位于函数最后一行;

右圆括号和左大括号间总是有一个空格;

函数声明和实现处的所有形参名称必须保持一致;

所有形参应尽可能对齐;

缺省缩进为2个空格;

换行后的参数保持4个空格的缩进;

}

5.如果函数声明成const,关键字const应与最后一个参数位于同一行 

6.如果有些参数没有用到, 在函数定义处将参数名注释起来

7.函数调用尽量放在同一行, 否则, 将实参封装在圆括号中

8.switch 语句可以使用大括号分段. 空循环体应使用 {} 或 continue. 

9.如果一个布尔表达式超过标准行宽断行方式要统一

10.return 表达式中不要用圆括号包围

11.预处理指令不要缩进, 从行首开始 

12.访问控制块的声明依次序是 public:, protected:, private:, 每次缩进 1 个空格

13.构造函数初始化列表放在同一行或按四格缩进并排几行

14.名字空间内容不增加缩进层次

15.永远不要在行尾添加没意义的留白

16.不在万不得已, 不要使用空行. 尤其是: 两个函数定义之间的空行不要超过 2 行, 函数体首尾不要留空行, 函数体中也不要随意添加空行

规则特例:

对于Windows程序员:

1.不要使用匈牙利命名法,使用 Google 命名约定, 包括对源文件使用 .cc 扩展名

2.尽量使用原有的 C++ 类型

3.使用 Microsoft Visual C++ 进行编译时, 将警告级别设置为 3 或更高, 并将所有 warnings 当作 errors 处理

4.不要使用 #pragma once; 而应该使用 Google 的头文件保护规则

5.除非万不得已, 不要使用任何非标准的扩展,

C++宏的使用(一)

C/C++宏的使用

1. 防止多重包含 2

2. 条件编译 2

3. 定义字面值常量 2

4. 定义为函数 2

5. 可变参数宏 3

6. 宏组合 3

6.1 一般用法 4

6.2 当宏参数是另一个宏的时候 4

6.2.1 非'#'和'##'的情况 4

6.2.2 当有'#'或'##'的时候 4

6.3 '#'和'##'的一些应用特例 5

6.3.1 合并匿名变量名 5

6.3.2 填充结构 5

6.3.3 记录文件名 6

6.3.4 得到一个数值类型所对应的字符串缓冲大小 6

7. 其他使用例子 6

7.1 得到指定地址上的一个字节或字 6

7.2 求最大值和最小值 6

7.3 得到一个field在结构体(struct)中的偏移量 6

7.4 得到一个结构体中field所占用的字节数 7

7.5 按照LSB格式把两个字节转化为一个Word 7

7.6 按照LSB格式把一个Word转化为两个字节 7

7.7 得到一个变量的地址(word宽度) 7

7.8 得到一个字的高位和低位字节 7

7.9 返回一个比X大的最接近的8的倍数 7

7.10 将一个字母转换为大写 7

7.11 判断字符是不是10进值的数字 7

7.12 判断字符是不是16进值的数字 8

7.13 防止溢出的一个方法 8

7.14 返回数组元素的个数 8

7.15 对于IO空间映射在存储空间的结构,输入输出处理

1. 防止多重包含

防止头文件多重包含:

如下

CODE:

#ifndef MAIN_H_

#define MAIN_H_

其它内容

#endif

作用就是阻止这个头文件被多次include。多次include就会出现重复的定义情况,所以需要在每个头文件中都使用这个定义。

2. 条件编译

#ifdef _DEBUG

printf("this debug info/n");

#endif

如果没有定义_DEBUG宏,那么上面那一行是不会编译进去。但是定义了_DEBUG后,上面那行就会编译进去。

#ifdef  _M_IX86

#elif defined _M_MRX000

#endif

3. 定义字面值常量

方便修改,尽量做到修改地方少。

#define PRINT_STR "你好"

main()

{

printf(PRINT_STR);

return 0;

}

4. 定义为函数

#ifdef _DEBUG

#define A(x) a(x)

#else

#define A(x) b(x)

#endif

int a(int x)

{

return x+1;

}

int b(int x)

{

return x+100;

}

int main()

{

printf ("A(10) value is %d",A(10));

return 0;

}

其实也可以定义成#define A a

但是定义成A(x)后只有A后面带一个(x)类型的编译器才会执行替换,比较安全,可以保证只替换函数而不替换变量。

5. 可变参数宏

有些时候定义一个宏来代替某个函数,但是这个函数是可变参数的话,那就需要考虑办法了

定义方法如下

#include <iostream>

using namespace std;

#define PRINT(...) cout<<(__VA_ARGS__)

#define PRINTC(...) printf(__VA_ARGS__)

int _tmain(int argc, _TCHAR* argv[])

{

//C++6.0不可运行

PRINT("FLY编译例子");

PRINT(endl);

PRINTC("%d %s %s",1,"吃饭了吗 smile MM:)","/n");

return 0;

}

6. 宏组合

也就是##和#的用法

##是连接符号,连接两个宏

#是把名字代替成字符串

6.1 一般用法

#define s5(a)    supper_##a

#include <stdio.h>

void supper_printf(const char* p )

{

printf("this is supper printf:/n%s/n",p);

}

int main()

{

s5(printf)("hello owrld");

return 0;

}

#用法如下

#include <stdio.h>

#define s(p)   #p

int main()

{

printf(s(p)"/n");

return 0;

}

6.2 当宏参数是另一个宏的时候

需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开。

6.2.1 非'#'和'##'的情况

#define TOW      (2)

#define MUL(a,b) (a*b)

printf("%d*%d=%d/n", TOW, TOW, MUL(TOW,TOW));

这行的宏会被展开为:

printf("%d*%d=%d/n", (2), (2), ((2)*(2)));

MUL里的参数TOW会被展开为(2)。

6.2.2 当有'#'或'##'的时候

#define A          (2)

#define STR(s)     #s

#define CONS(a,b)  int(a##e##b)

printf("int max: %s/n",  STR(INT_MAX));  // INT_MAX #include<climits>

这行会被展开为:

printf("int max: %s/n", "INT_MAX");

printf("%s/n", CONS(A, A));               // compile error

这一行则是:

printf("%s/n", int(AeA));

INT_MAX和A都不会再被展开,然而解决这个问题的方法很简单。加多一层中间转换宏。

加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数。

#define A           (2)

#define _STR(s)     #s

#define STR(s)      _STR(s)          // 转换宏

#define _CONS(a,b)  int(a##e##b)

#define CONS(a,b)   _CONS(a,b)       // 转换宏

printf("int max: %s/n", STR(INT_MAX));          // INT_MAX,int型的最大值,为一个变量#include<climits>

输出为: int max: 0x7fffffff

STR(INT_MAX)-->_STR(0x7fffffff) 然后再转换成字符串;

printf("%d/n", CONS(A, A));

输出为:200

CONS(A, A)-->_CONS((2), (2))-->int((2)e(2))

6.3 '#'和'##'的一些应用特例

6.3.1 合并匿名变量名

#define     ___ANONYMOUS1(type, var, line)  type  var##line

#define  __ANONYMOUS0(type, line)  ___ANONYMOUS1(type, _anonymous, line)

#define    ANONYMOUS(type)  __ANONYMOUS0(type, __LINE__)

例:ANONYMOUS(static int); 即: static int _anonymous70;  70表示该行行号;

第一层:ANONYMOUS(static int);  -->  __ANONYMOUS0(static int, __LINE__);

第二层:                        -->  ___ANONYMOUS1(static int, _anonymous, 70);

第三层:                        -->  static int  _anonymous70;

即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开。

6.3.2 填充结构

#define    FILL(a)   {a, #a}

enum IDD{OPEN, CLOSE};

typedef struct MSG

{

IDD id;

const char * msg;

}MSG;

MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};

相当于:

MSG _msg[] = {{OPEN, "OPEN"}, {CLOSE, "CLOSE"}};

6.3.3 记录文件名

#define  _GET_FILE_NAME(f)   #f

#define  GET_FILE_NAME(f)    _GET_FILE_NAME(f)

static char  FILE_NAME[] = GET_FILE_NAME(__FILE__);

6.3.4 得到一个数值类型所对应的字符串缓冲大小

#define  _TYPE_BUF_SIZE(type)  sizeof #type

#define  TYPE_BUF_SIZE(type)   _TYPE_BUF_SIZE(type)

char  buf[TYPE_BUF_SIZE(INT_MAX)];

-->  char  buf[_TYPE_BUF_SIZE(0x7fffffff)];

-->  char  buf[sizeof "0x7fffffff"];

这里相当于:

char  buf[11];

7. 其他使用例子

7.1 得到指定地址上的一个字节或字

#define MEM_B( x ) ( *( (byte *) (x) ) )

#define MEM_W( x ) ( *( (word *) (x) ) )

7.2 求最大值和最小值

#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )

#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

7.3 得到一个field在结构体(struct)中的偏移量

#define FPOS( type, field ) /

( (dword) &(( type *) 0)-> field )

7.4 得到一个结构体中field所占用的字节数

#define FSIZ( type, field ) sizeof( ((type *) 0)->field )

7.5 按照LSB格式把两个字节转化为一个Word

#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

7.6 按照LSB格式把一个Word转化为两个字节

#define FLOPW( ray, val ) /

(ray)[0] = ((val) / 256); /

(ray)[1] = ((val) & 0xFF)

7.7 得到一个变量的地址(word宽度)

#define B_PTR( var ) ( (byte *) (void *) &(var) )

#define W_PTR( var ) ( (word *) (void *) &(var) )

7.8 得到一个字的高位和低位字节

#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))

#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))

7.9 返回一个比X大的最接近的8的倍数

#define RND8( x )       ((((x) + 7) / 8 ) * 8 )

7.10 将一个字母转换为大写

#define UPCASE( c ) ( ((c) >= ''a'' && (c) <= ''z'') ? ((c) - 0x20) : (c) )

7.11 判断字符是不是10进值的数字

#define DECCHK( c ) ((c) >= ''0'' && (c) <= ''9'')

7.12 判断字符是不是16进值的数字

#define HEXCHK( c ) ( ((c) >= ''0'' && (c) <= ''9'') ||/

((c) >= ''A'' && (c) <= ''F'') ||/

((c) >= ''a'' && (c) <= ''f'') )

7.13 防止溢出的一个方法

#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))

7.14 返回数组元素的个数

#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )

7.15 对于IO空间映射在存储空间的结构,输入输出处理

#define inp(port)      (*((volatile byte *) (port)))

#define inpw(port)     (*((volatile word *) (port)))

#define inpdw(port)    (*((volatile dword *)(port)))

#define outp(port, val)   (*((volatile byte *) (port)) = ((byte) (val)))

#define outpw(port, val)  (*((volatile word *) (port)) = ((word) (val)))

#define outpdw(port, val)  (*((volatile dword *) (port)) = ((dword) (val)))

Virtual table in C++

The main purpose of virtual function mechanism is to implement polymorphism, which is one of the most important characters of OOP. Polymorphism, from some point of view, is to enable the base class to call the member function which is concrete, or override, in a derivative class. In another word, it tries to act different action without changing the code.

How to use virtual function is trivial to a coder. So I wont say much here. You may refer to some books about C++ for this topic. In this article, I would mainly focus on virtual table and analyze how virtual table works.

Virtual table, V-Table for short, is a table located in the top of an object. It is a list of addresses of virtual functions. Once we have such a table, inheritance, override could be implemented on top of it. For instance, if we have a pointer to parent class and point it to a derivative object, the virtual table contains the addresses of the function should be involved.

Let us check the following example:

typedef void(*Fun)(void);
 
class Base
{
public:
    virtual void a()
    {
        cout<<"Base::a()"<<endl;
    }
    virtual void b()
    {
        cout<<"Base::b()"<<endl;
    }
    virtual void c()
    {
        cout<<"Base::c()"<<endl;
    }
};
 
int main()
{
    Fun pFun = NULL;
    Base b;
    //
    cout<<"The address of virtual table: "<<(int *)*(int*)(&b)<<endl;
    cout<<"The address of the first virtual function: "<<(int*)*(int *)*(int*)(&b)<<endl;
    //
    pFun = (Fun)*(int *)*(int*)(&b);
    pFun();
    return 0;
}



The output of above code is as followed:


vt1


Furthermore, we could easily guess the addresses of other member functions as followed:


(Fun)*((int*)*(int*)(&b)+0); // Base::a()
(Fun)*((int*)*(int*)(&b)+1); // Base::b()
(Fun)*((int*)*(int*)(&b)+2); // Base::c()



Ok, the above addresses are too simple, right. Lets try an example a little complicated, simple inheritance without override.


Suppose we have two classes as the UML described.


o_Drawing3


As the derivative class does not override the functions in parent class, the virtual table are as followed:


o_vtable2


It is easy to find out that



  1. virtual functions are in the order of declaration;
  2. Functions in parent class are in front of derivative class.

For the case of inheritance with override, as the following classes.


o_Drawing4


The virtual table is as followed. Be aware of the first element in the table, which is different from the above example.


o_vtable3


From the figure above, we should notice that:



  1. the virtual function in parent class is replaced by the override function from the derivative class;

  2. the other functions remain the same.

So we run some code like:

Base* b = new Derive();
b->a();




We would get some result like “Derive::a()”.


Then, lets check the multiple inheritance. The first example is as followed:


o_Drawing1


As the first example, there is not virtual function override. So the virtual table would be very similar to simple inheritance. The only difference is that there would be as many virtual table as parent classes. In this case, there would be three virtual table, in the order of declaration.


o_vtable4



The final case is the multiple inheritance with overriding.


The classes are as follow:


o_Drawing2


The virtual table is as followed:


o_vtable5


We could find that all the virtual functions in the parent classes are replaced by the derivative class.



So, let try the following code to verify the above knowledge.


class Base1
{
public:
    virtual void a()
    {
        cout<<"Base1::a()"<<endl;
    }
    virtual void b()
    {
        cout<<"Base1::b()"<<endl;
    }
    virtual void c()
    {
        cout<<"Base1::c()"<<endl;
    }
};
class Base2
{
public:
    virtual void a()
    {
        cout<<"Base2::a()"<<endl;
    }
    virtual void b()
    {
        cout<<"Base2::b()"<<endl;
    }
    virtual void c()
    {
        cout<<"Base2::c()"<<endl;
    }
};
class Base3
{
public:
    virtual void a()
    {
        cout<<"Base3::a()"<<endl;
    }
    virtual void b()
    {
        cout<<"Base3::b()"<<endl;
    }
    virtual void c()
    {
        cout<<"Base3::c()"<<endl;
    }
};
 
class Derive: public Base1, public Base2, public Base3
{
public:
    void a()
    {
        cout<<"Derive::a()"<<endl;
    }
};
 
int main()
{
    Derive d;
    Base1 *b1 = &d;
    Base2 *b2 = &d;
    Base3 *b3 = &d;
    b1->a();
    b2->a();
    b3->a();
    b1->b();
    b2->b();
    b3->b();
    return 0;
}

vt2


Criticizes:


The virtual table mechanism plays an very important role in C++, without doubt. However, there are also some problems caused by it. 



  1. Try to access the functions in derivative class through a pointer of parent class. As shown in the following image:

o_vtable2


There is an entry for f1(), but I cannot access that function. However, you may violate this C++ grammar by directly decompose the virtual table to call it.



  1. Access non-public virtual function. Try the following code:


class Base 
{    
    private:virtual void f() 
    { 
        cout << "Base::f" << endl; 
    }
};
class Derive : public Base
{};
typedef void(*Fun)(void);
void main() 
{    
    Derive d;   
    Fun pFun = (Fun)*((int*)*(int*)(&d)+0);    
    pFun();
}





 


Thanks to the post here in Chinese. Some images in this blogs are from there.


Saturday, December 3, 2011

【转】怎么理解编码

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为"字节"。 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去。他们看到这样是好的,于是它们就这机器称为"计算机"。 开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。 他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端、打印机遇上约定好的这些字节被传过来时,就要做一些约定的动作。遇上00x10, 终端就换行,遇上0x07, 终端就向人们嘟嘟叫,例好遇上0x1b, 打印机就打印反白的字,或者终端就用彩色显示字母。他们看到这样很好,于是就把这些0x20以下的字节状态称为"控制码"。 他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示,一直编到了第127号,这样计算机就可以用不同字节来存储英语的文字了。大家看到这样,都感觉很好,于是大家都把这个方案叫做 ANSI 的"Ascii"编码(American Standard Code for Information Interchange,美国信息互换标准代码)。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。 后来,就像建造巴比伦塔一样,世界各地的都开始使用计算机,但是很多国家用的不是英文,他们的字母里有许多是ASCII里没有的,为了可以在计算机保存他们的文字,他们决定采用127号之后的空位来表示这些新的字母、符号,还加入了很多画表格时需要用下到的横线、竖线、交叉等形状,一直把序号编到了最后一个状态255。从128到255这一页的字符集被称"扩展字符集"。从此之后,贪婪的人类再没有新的状态可以用了,美帝国主义可能没有想到还有第三世界国家的人们也希望可以用到计算机吧! 等中国人们得到计算机时,已经没有可以利用的字节状态来表示汉字,况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民,我们不客气地把那些127号之后的奇异符号们直接取消掉, 规定:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,我们还把数学符号、罗马希腊的字母、日文的假名们都编进去了,连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。 中国人民看到这样很不错,于是就把这种汉字方案叫做 "GB2312"。GB2312 是对 ASCII 的中文扩展。 但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312 没有用到的码位找出来老实不客气地用上。 后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 GBK 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。 后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。 中国的程序员们看到这一系列汉字编码的标准是好的,于是通称他们叫做 "DBCS"(Double Byte Charecter Set 双字节字符集)。在DBCS系列标准里,最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里,因此他们写的程序为了支持中文处理,必须要注意字串里的每一个字节的值,如果这个值是大于127的,那么就认为一个双字节字符集里的字符出现了。那时候凡是受过加持,会编程的计算机僧侣们都要每天念下面这个咒语数百遍: "一个汉字算两个英文字符!一个汉字算两个英文字符……" 因为当时各个国家都像中国这样搞出一套自己的编码标准,结果互相之间谁也不懂谁的编码,谁也不支持别人的编码,连大陆和台湾这样只相隔了150海里,使用着同一种语言的兄弟地区,也分别采用了不同的 DBCS 编码方案——当时的中国人想让电脑显示汉字,就必须装上一个"汉字系统",专门用来处理汉字的显示、输入的问题,但是那个台湾的愚昧封建人士写的算命程序就必须加装另一套支持 BIG5 编码的什么"倚天汉字系统"才可以用,装错了字符系统,显示就会乱了套!这怎么办?而且世界民族之林中还有那些一时用不上电脑的穷苦人民,他们的文字又怎么办? 真是计算机的巴比伦塔命题啊! 正在这时,大天使加百列及时出现了——一个叫 ISO (国际标谁化组织)的国际组织决定着手解决这个问题。他们采用的方法很简单:废了所有的地区性编码方案,重新搞一个包括了地球上所有文化、所有字母和符号的编码!他们打算叫它"Universal Multiple-Octet Coded Character Set",简称 UCS, 俗称 "UNICODE"。 UNICODE 开始制订时,计算机的存储器容量极大地发展了,空间再也不成为问题了。于是 ISO 就直接规定必须用两个字节,也就是16位来统一表示所有的字符,对于ascii里的那些“半角”字符,UNICODE 包持其原编码不变,只是将其长度由原来的8位扩展为16位,而其他文化和语言的字符则全部重新统一编码。由于"半角"英文符号只需要用到低8位,所以其高8位永远是0,因此这种大气的方案在保存英文文本时会多浪费一倍的空间。 这时候,从旧社会里走过来的程序员开始发现一个奇怪的现象:他们的strlen函数靠不住了,一个汉字不再是相当于两个字符了,而是一个!是的,从 UNICODE 开始,无论是半角的英文字母,还是全角的汉字,它们都是统一的"一个字符"!同时,也都是统一的"两个字节",请注意"字符"和"字节"两个术语的不同,“字节”是一个8位的物理存贮单元,而“字符”则是一个文化相关的符号。在UNICODE 中,一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。 从前多种字符集存在时,那些做多语言软件的公司遇上过很大麻烦,他们为了在不同的国家销售同一套软件,就不得不在区域化软件时也加持那个双字节字符集咒语,不仅要处处小心不要搞错,还要把软件中的文字在不同的字符集中转来转去。UNICODE 对于他们来说是一个很好的一揽子解决方案,于是从 Windows NT 开始,MS 趁机把它们的操作系统改了一遍,把所有的核心代码都改成了用 UNICODE 方式工作的版本,从这时开始,WINDOWS 系统终于无需要加装各种本土语言系统,就可以显示全世界上所有文化的字符了。 但是,UNICODE 在制订时没有考虑与任何一种现有的编码方案保持兼容,这使得 GBK 与UNICODE 在汉字的内码编排上完全是不一样的,没有一种简单的算术方法可以把文本内容从UNICODE编码和另一种编码进行转换,这种转换必须通过查表来进行。 如前所述,UNICODE 是用两个字节来表示为一个字符,他总共可以组合出65535不同的字符,这大概已经可以覆盖世界上所有文化的符号。如果还不够也没有关系,ISO已经准备了UCS-4方案,说简单了就是四个字节来表示一个字符,这样我们就可以组合出21亿个不同的字符出来(最高位有其他用途),这大概可以用到银河联邦成立那一天吧! UNICODE 来到时,一起到来的还有计算机网络的兴起,UNICODE 如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTF(UCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,而是要过一些算法和规则来转换。 受到过网络编程加持的计算机僧侣们都知道,在网络里传递信息时有一个很重要的问题,就是对于数据高低位的解读方式,一些计算机是采用低位先发送的方法,例如我们PC机采用的 INTEL 架构,而另一些是采用高位先发送的方式,在网络中交换数据时,为了核对双方对于高低位的认识是否是一致的,采用了一种很简便的方法,就是在文本流的开始时向对方发送一个标志符——如果之后的文本是高位在位,那就发送"FEFF",反之,则发送"FFFE"。不信你可以用二进制方式打开一个UTF-X格式的文件,看看开头两个字节是不是这两个字节? 讲到这里,我们再顺便说说一个很著名的奇怪现象:当你在 windows 的记事本里新建一个文件,输入"联通"两个字之后,保存,关闭,然后再次打开,你会发现这两个字已经消失了,代之的是几个乱码!呵呵,有人说这就是联通之所以拼不过移动的原因。 其实这是因为GB2312编码与UTF8编码产生了编码冲撞的原因。 从网上引来一段从UNICODE到UTF8的转换规则: Unicode UTF-8 0000 - 007F 0xxxxxxx 0080 - 07FF 110xxxxx 10xxxxxx 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx 例如"汉"字的Unicode编码是6C49。6C49在0800-FFFF之间,所以要用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 1100 0100 1001,将这个比特流按三字节模板的分段方法分为0110 110001 001001,依次代替模板中的x,得到:1110-0110 10-110001 10-001001,即E6 B1 89,这就是其UTF8的编码。 而当你新建一个文本文件时,记事本的编码默认是ANSI, 如果你在ANSI的编码输入汉字,那么他实际就是GB系列的编码方式,在这种编码下,"联通"的内码是: c1 1100 0001 aa 1010 1010 cd 1100 1101 a8 1010 1000 注意到了吗?第一二个字节、第三四个字节的起始部分的都是"110"和"10",正好与UTF8规则里的两字节模板是一致的,于是再次打开记事本时,记事本就误认为这是一个UTF8编码的文件,让我们把第一个字节的110和第二个字节的10去掉,我们就得到了"00001 101010",再把各位对齐,补上前导的0,就得到了"0000 0000 0110 1010",不好意思,这是UNICODE的006A,也就是小写的字母"j",而之后的两字节用UTF8解码之后是0368,这个字符什么也不是。这就是只有"联通"两个字的文件没有办法在记事本里正常显示的原因。 而如果你在"联通"之后多输入几个字,其他的字的编码不见得又恰好是110和10开始的字节,这样再次打开时,记事本就不会坚持这是一个utf8编码的文件,而会用ANSI的方式解读之,这时乱码又不出现了。 好了,终于可以回答NICO的问题了,在数据库里,有n前缀的字串类型就是UNICODE类型,这种类型中,固定用两个字节来表示一个字符,无论这个字符是汉字还是英文字母,或是别的什么。 如果你要测试"abc汉字"这个串的长度,在没有n前缀的数据类型里,这个字串是7个字符的长度,因为一个汉字相当于两个字符。而在有n前缀的数据类型里,同样的测试串长度的函数将会告诉你是5个字符,因为一个汉字就是一个字符。

Wednesday, October 19, 2011

How to read those symbols?!

α 阿尔法 β 贝塔 γ 伽玛 δ 德尔塔 ε 伊普西隆 ζ 泽塔 η 伊塔 θ 西塔 ι 约塔 κ 卡帕 λ 兰姆达 μ 米欧 ν 纽 ξ 克西 ο 欧米克隆 π 派 ρ 柔 σ 西格玛 τ 陶 υ 玉普西隆 φ 弗爱 χ 凯 ψ 普赛

Friday, October 14, 2011

CUDA 随想之Thinking in CUDA

I think the biggest difference between programming with CUDA and traditional procedure-oriented language is the concurrent. As the traditional language, both OOP and POP, are executed step by step with one CPU. So the relationship(or order) among functions(objects of classes), data flows and data changes are very intuitive. For example, if you are programming a C program which helps you to process images. There is two ways to transfer data, input parameters and global variables. In some extreme cases, you only use parameters to transfer and share data. So the only thing you need to do is to lock your eye on the parameter, and keep in mind how it is copied, when it is transferred to other procedures and how the return values are merged. That is all and you will find the bug, sooner or later. However, in CUDA, it is a little different. As the GPU has a number of functional unit, you code are executed in the same time. It sounds like all your classmates, each of them holding a recipe, are trying to cook a complicated Chinese food. If your recipe is not well organized, the only thing you would get is 30 copies of the same dish. Or worse, one dish with 30 times more salt and none for the others. How to divide the task in CUDA is important. Here, I cannot tell you how to make your division better, but remind you that please handle it carefully.

The next thing needs attention is the memory copy. If you have used MEX between C++ and Matlab or some other interface between two different languages, you may understand this question better than me. There are two things you need to care, the data type and data size. We often use float2 in CUDA and copy it from device to a float pointer. Or we write 200 float1 in CUDA but copy only 100 back. The result would be extremely difficult to be examined. On one hand, you may do not have a debugger as powerful as GDB and Visual Studio debuger, on the other hand, you will be confusing about it is caused by your algorithm or other thing…

Good luck, CUDAerSmile

Wednesday, September 28, 2011

邮件常用语句

1. I am writing to confirm /enquire/inform you...我写信时要确认/询问/通知你。。。
2. I am writing to follow up on our earlier decision on the marketing campaign in Q2.
我写信来追踪我们之前对于第二季度营销活动的决定。
3. With reference to our telephone conversation today...关于我们今天在电话中的谈话。。。
4. In my previous e-mail on October 5...先前在10月5日所写的信。。。
5. As I mentioned earlier about...如我先前所提及关于。。。
6. as indicated in my previous e-mail...如我在先前的信中所提出。。。
7. As we discussed on the phone...如我们上次在电话中的讨论。。。
8. from our decision at the previous meeting...如我们在上次会议中的决定。。。
9. as you requested/per your requirement...按照你的要求。。。
10.In reply to your e-mail dated April 1,we decided...回答你在4月1日写的信,我们决定。。。
11.This is in response to your e-mail today.这是针对你今天早上来信的回复。
12. As mentioned before, we deem this product has strong unique selling points in china.
如先前所述,我们认为这个产品在中国有强有力且独一无二的销售点。
13. As a follow-up to our phone conversation yesterday, I wanted to get back to you about the pending issues of our agreement.追踪我们昨天在电话中所谈,我想答复你我们合约的一些待解决的议题。
14. I received your voice message regarding the subject. I’m wondering if you can elaborate i.e. provide more details.我收到你关于这个主题的留言。我想你是否可以再详尽说明,也就是再提供多一点细节。
15. Please be advised/informed that...请被告知。。。
16. Please note that...请注意。。。
17. We would like to inform you that...我们想要通知你。。。
18. I am convinced that...我确信。。。
19. We agree with you on...我们同意你在。。。
20. With effect from 4 Oct., 2008...从2008年10月4日开始生效。。。
21. We will have a meeting scheduled as noted below...我们将举行一个会议,时间表如下。
22. Be assured that individual statistics are not disclosed and this is for internal use only.请确保个人信息不会外泄且只供内部使用。
23. I am delighted to tell you that...我很高兴地告诉你。。。
24. We are pleased to learn that...我们很高兴得知。。。
25. We wish to notify you that...我们希望通知你。。。
26. Congratulation on your...恭喜您关于。。。
27. I am fine with the proposal.我对这份提桉没意见。
28.I am pleased to inform you that you have been accepted to join the workshop scheduled for 22-24 Nov,2008.我很高兴地告诉你,你已经被同意参加2008年11月22-24日的研讨会。
29. We are sorry to inform you that...我们很抱歉地通知你。。。
30. I’m afraid I have some bad news.我恐怕要带来一些坏消息。
31. There are a number of issues with our new system.我们的新系统有些问题。
32. Due to circumstances beyond our control...由于情况超出我们所能控制。。。
33. I don’t feel too optimistic about...我觉得不太乐观关于。。。
34. It would be difficult for us to accept...我们很难接受。。。
35. Unfortunately I have to say that, since receiving your enquiries on the subject, our view has not changed.很不幸地,我必须这么说,自从收到你关于这个主题的询问,我们的看法都没有改变。
36. We would be grateful if you could...我们会很感激如果你可以。。。
37. I could appreciate it if you could...我会很感激如果你可以。。。
38. Would you please send us…?可否请你寄给我们…?
39. We need your help.我们需要你的帮助。
40. We seek your assistance to cascade/reply this message to your staff.
我们请求你的帮助,将此信息传达给你们的员工。
41. We look forward to your clarification.我们期待你的澄清。
42.Your prompt attention to this matter will be appreciated.您能立即注意此事,我们将非常感激。
43. I would really appreciate meeting up if you can spare the time. Please let me know what suits you best.如果您能抽出时间,我希望能与你见面,请让我知道您最适合的时间。
44.Please give us your preliminary thoughts about this.请让我知道你对于这件事情初步的想法。
45. Would you please reply to this e-mail if you plan to attend?请您回信如果您计划参加?
46.Please advise if you agree with this approach.请告知是否你同意这个方法。
47. Could you please let me know the status of this project?请让我知道这个计划的进度?
48. If possible, I hope to receive a copy of your proposal when it is finished.
如果可能,当你完成提桉,我希望能收到一份复本。
49. I would appreciate it very much if you would send me your reply by next Monday.
如果能在下周一前收到您的答复,我将非常感激。
50. Hope this is OK with you. If not, let me know by e-mail ASAP.
希望您对此没有问题,如果不行,请利用电子邮件尽快让我知道。
51. Could you please send me your replies to the above questions by the end of June?
请您在6月份前答复我上述问题好吗?
52. May I have your reply by April 1, if possible?
如果可能,我可否在4月1日前收到您的答复?
53. If you wish, we would be happy to...如果你希望,我们很乐意。。。

54. Please let me know if there’s anything I can do to help.
请让我知道任何我可以帮得上忙的地方。
55.If there’s anything else I can do for you on/regarding this matter, please feel free to contact me at any time.对于这件事,如果还有任何我能帮得上忙的地方,请不要客气,随时与我联络。
56.If you want additional recommendations on this, please let us know and we can try to see if this is possible.如果关于此事你需要额外的建议,请让我们知道,我们会尝试看看是否可能。
57. I’m just writing to remind you of...我只是写信来提醒您。。。
58. May we remind you that...?我们想要提醒您。。。
59. I am enclosing...我附上。。。
60. Please find enclosed...请查阅附件。。。
61. Attached hereto...附件是关于。。。
62. Attached please find the most up-to-date information on/regarding/concerning…
附上关于某某的最新资料…
63. Attached please find the draft product plan for your review and comment.
附上产品计划书的草稿,请审查及评价。
64. If you have any further questions, please feel free to contact me.
如果你有任何问题,请不要客气与我联络。
65. I hope my clarification has been helpful.希望我的说明是有帮助的。
66. Please feel free to call me at any time, I will continually provide full support.
请随时跟我联络,我会持续地提供全程支援。

67. Please let me know if this is suitable.请让我知道这是否恰当。
68. Looking forward to seeing you soon.期待很快能见到你。
69. We look forward to hearing from you soon.

我们期待很快能得到您的回复。
70. Hope this is clear and we are happy to discuss this further if necessary.
希望上述说明很清楚,如有必要,我们很乐意再进一步讨论。
71. I look forward to receiving your reply soon.我期待很快能收到你的回复。
72. Looking forward to receiving your comments in due course.
期待在预期的时间收到你的反馈。
73. I’ll keep you posted.我会与你保持联络。
74. Please keep me informed on the matter.请随时让我知道这件事的发展。
75. For any comments/suggestions, please contact Nadia at 2552-7482.
任何评价或建议,请打电话2552-7482联络Nadia。
76. I would like to apologize for...我想就。。。道歉。。。
77. I apologize for the delay in...对于。。。的耽搁,我深感抱歉。
78. We are sorry for any inconvenience caused.对于产生任何不便,我们感到抱歉。
79. I am sorry for any inconvenience this has caused you.
对于造成你的任何不便,我感到抱歉。
80. I’m sorry about last time.关于上次的事我很抱歉。
81.We apologize for not replying you earlier.对于未能早一点回信给你,我们感到抱歉。
82. I’m really sorry about this.关于这件事,我真的很抱歉。
83. Sorry, I’m late in replying to your e-mail dated Monday, April 1.
抱歉,太迟回您在4月1日(星期一)发给我的邮件。
84. We apologize for the delay and hope that it doesn’t inconvenience you too much.
我们为耽搁道歉,希望不会给您带来太多的不便。
85.Hoping that this will not cause you too much trouble.希望不会为您带来太多的麻烦。
86.Sorry if my voice message is not clear enough.如果我的电话留言不够清楚,我深感抱歉.
87. Thank you for your help.谢谢你的帮助。
88. I appreciate very much that you...我非常感激你。。。
89. I truly appreciate it.我真的很感激。
90. Thank you for your participation.谢谢你的参加。
91. Thank you so much for inviting me.非常感谢你要请我。
92.Congratulations to all of you and thanks for your efforts.恭喜各位并谢谢各位的努力。
93. Your understanding and cooperation is greatly/highly appreciated.
很感激你的理解及合作。
94. Your prompt response will be most appreciated.很感激你快速的答复。
95. Once again, thank you all for your commitment and support.
再一次感谢你的承诺及支持。
96. Thanks for your input/clarification/message.谢谢你的投入/澄清/信息。
97. Any comments will be much appreciated.对于您的任何建议,我将非常感激。
98. Thank you very much for everything you’ve done for me.谢谢你为我做的一切。
99. I would appreciate your kindest understanding with/regarding this matter.
我很感激你对这件事情的理解。
100. Please convey my thanks to all the staff involved, they certainly did an excellent job.请表达我的谢意给那些有关的同仁,他们真的干得很好

Monday, September 19, 2011

读《脱亚论》有感

福泽谕吉的《脱亚论》在中国广为人知,在中国对《脱亚论》的主流看法是持批判态度的,认为福泽谕吉的主张是“对亚洲邻国持轻蔑态度,主张模仿欧美列强侵略亚洲邻国。”但是一般人多半是看到《脱亚论》的只言片语,看过《脱亚论》全文的人似乎并不多。因此在这里我特意把《脱亚论》的全文翻译出来,供有兴趣的人参考。

在翻译《脱亚论》的过程中,不得不查阅不少资料,因此这也成为一个很好的学习过程。我读完《脱亚论》全文的第一个感觉是:中国人在很大程度上,误解了福泽谕吉。首先,所谓福泽谕吉“对亚洲邻国持轻蔑态度”,这个看法本身就很有问题。为什么这么说?我们首先看一看福泽谕吉写《脱亚论》的背景。

福泽谕吉的这篇《脱亚论》写于1885年,当时这篇文章并无题目,是作为《时事新报》(现在日本《产经新闻》的前身)的社论发表的,《脱亚论》这个题目是后人出版福泽谕吉的著作时加上去的。福泽谕吉为什么想起来写这篇文章呢?原来那时在日本舆论界展开了一场思想争论:日本应该怎样与中国和朝鲜这两个邻国打交道?

历史上日本与中国的关系,很长一段时间都是册封与朝贡关系,也可以说是另外一种不平等关系。1853年,美国炮舰侵入长崎,迫使日本签订丧权辱国的《日美和亲条约》。此后英、俄、法等国接踵而来,强迫日本签订类似条约,其遭遇与中国非常类似。日本被迫“开国”后,有识之士提出学习西洋的强国之术,自强保国,1868年的明治维新就是在这种背景下发起的。

由于当时中国和日本、朝鲜同样被西洋列强侵略,都面临亡国灭族的危险,因此中日韩三国在“抵抗”西洋侵略方面有共同的利益。在这个背景下,日本有人提出“兴亚论”(后来又被称为“大亚细亚主义”),代表人物有日本当时著名的政治家和思想家,比如胜海舟、植木枝盛、大井宪太郎、樽井藤吉等。“兴亚论”认为日本与亚洲是唇亡齿寒的关系,日本的邻国一旦亡国,日本也会遭殃。所以他们提出唤醒亚洲(主要指中国和朝鲜),日本与中国和朝鲜结成同盟国,日中韩相互提携,共同抵抗西洋列强,这是日本的最善国策。

中国也同样产生过类似的亚洲联合起来抵抗西洋侵略的思想,比如梁启超的“ 亚粹主义”,章太炎的“亚洲和亲主义”,孙中山的“大亚洲主义”,李大钊的“新亚细亚主义”等。这个“兴亚论”后来又变成亚洲在日本领导下,共同抗击西洋列强的理论,比如“大东亚共荣圈”、“东亚新秩序”等。不过1880年代的“兴亚论”,还是主张日本以平等的关系与中国和朝鲜结盟抗击西洋,因为那时日本的国力还很弱,比起当时的大清国还有相当的差距。

对于这种“兴亚论”,福泽谕吉提出相反的思想理论,即“脱亚论”。针对“兴亚论”唤醒亚洲、共同对抗西洋侵略的设想,福泽反论说:中国和朝鲜死守陈规旧套,不思改进,不愿革新,所以日本不应该对中国和朝鲜的醒觉抱有希望(当然他也指出如果中国和朝鲜国内出现有识之士,进行大刀阔斧的改革维新,将另当别论)。福泽指出:陈腐守旧的中国和朝鲜,不但对日本毫无帮助,反而因为他们落后腐败的“坏名声”,会让西洋人误认为日本也是同样的落后腐败。因此他主张日本不要再犹豫,应该拒绝与中国和朝鲜这两个不文明国家(“坏朋友”)继续交往,而与欧洲的文明国家交往。

福泽指出中国和朝鲜这两个国家没有前途希望的关键是:中国和朝鲜对西洋文明采取被动的抗拒态度,中国和朝鲜想把自己置身于西洋文明之外,保持自己的独特文明。而维新后的日本对西洋文明采取主动接纳的态度,把自己也投身于西洋文明之中,与他们同呼吸共命运。福泽认为中国和朝鲜对西洋文明的抗拒不可能成功,因为西洋文明有像“麻疹”那样的传染性,对西洋文明抗拒的结果就是亡国,国土被西洋列强瓜分。后来的历史证明了福泽谕吉对中国和朝鲜的预见。要不是后来西洋列强改变了殖民主义思想,中国被列强瓜分几乎是肯定的。

读了福泽谕吉的《脱亚论》,我不由产生一种想法:中国在近代遭受的各种苦难凌辱,某种程度上是中国人自己“选择”的。一直到20世纪80年代,中国才开始意识到“对外开放”的重要性,才开始主动加入和参与西方文明圈,按照现在中国时髦的话叫做“与世界接轨”。中国的对外开放才搞了20多年,中国经济就取得了如此惊人的发展。现在中国人才自己体会到当年日本那样高速发展的秘诀,不过就是“对外开放”四个字。

其实日本人并没有隐瞒自己富国强兵的秘诀,早在120年前日本的思想家福泽谕吉就指出中国落后的结症就是拒绝西方文明,拒绝对外开放。可惜中国人直到100年后,才明白与西洋文明同呼吸共命运、共同品嚐文明之苦乐的重要性。假如中国在 100多年前就开始搞对外开放,及早与世界接轨,那么近代中国肯定会是另外一个样子,中国近代史就不会是充满屈辱和创伤的悲惨历史。所以我说:中国在近代遭受的各种苦难凌辱,某种程度上是中国人自己“选择”的。

如果评论一下日本当时的“兴亚论”和“脱亚论”哪个更正确,从日本的角度来看,还是“脱亚论”更正确一些,事实上日本政府也是选用了脱亚入欧的发展方针。设想假如当年日本政府选用“兴亚论”,等待中国、朝鲜的觉醒和自强,和中国、朝鲜站在一个战壕里,日本会有今天的发展吗?福泽谕吉的“脱亚论”,的确是极具远见的。

难怪现在福泽谕吉的头像印在日本最大面额的钞票上,而他的反对派却鲜为人知。对于日本人来说,日本有今天的发展,他是最值得感谢的人之一。

(之二)

中国近代史概括为两个字就是“反抗”。“抗英”、“抗日”、“抗美”;“反帝”、“反修”、现在还有“反日”,总而言之,中国近代史就是一部与外国抗争的历史,中国人近代以来一直怀着一种“仇外”心态。

说到“仇外”,当然有道理,中国被洋人侵略,被迫签订不平等条约等等,都是中国“仇外”的理由。但同样是遭受侵略、被迫签订不平等条约的日本,为什么却没有同样地“仇外”,相反,日本却还要和侵略压迫自己的西欧列强“交朋友”。在这里,福泽谕吉的《脱亚论》很好地说明了日本对于西洋人的看法。

正如福泽谕吉所说:“如果试图阻止文明的入侵,日本国的独立也不能保证,因为世界文明的喧闹,不允许一个东洋孤岛在此独睡。”他早在100多年前就看到西洋文明是一股不可阻挡的历史潮流,试图阻挡或者躲避这股潮流是愚蠢的,而自己也积极搭乘这股潮流才是明智之策。

中国对于西洋文明的潮流,一直采取对抗的姿态,从“以夷制夷”,“中体西用”,到“中国特色的社会主义”,都是试图把外国人赶走,或者把外国人拒之门外,总之就是“排外”两个字。鸦片战争以后,中国人尽管一直在学习西方,但中国学西方的目的,是“师夷技长以制夷”,用西方文明的枪炮来把西方人抗拒在国门之外,中国自己并不想加入西方文明圈。这和日本学习西方是为了“入欧”,加入西方文明圈的想法,从根本上就不同。

中国欢迎外国人来中国,欢迎外国人来投资办厂,那是最近20年的事,中国一直到现在才改变了“排外”的心态。以前中国总对外国人不信任,总觉得外国人来中国一定是“不怀好意”、“ 不安好心”,所以千方百计要把外国人赶走,以为赶走了外国人,中国人就“站起来”了,中国人就无比幸福了。1949年以后中共赶走了除了苏联以外的所有西方人,到1960年以后又把苏联人也赶走了。在文革时期,中国几乎是一个洋鬼子都没有了,现实了老佛爷、义和团等多年的奋斗目标,彻底赶走了所有的外国人。

可是中国却惊讶地发现,赶走外国人,把自己隔绝于西洋文明之外,并没有给中国人带来幸福,反而给中国带来了灾难。所以在文革之后,中国人痛定思痛,不再排外了,这次中国不但不赶外国人,反而来了个180度大转弯,开始请外国人到中国来了,真可谓“既知今日,何必当初”呢?福泽谕吉早在 100多年前就批评中国:“在遭遇如同麻疹那样流行的文明开化时,支、韩两国违背传染的天然规律,为了躲避传染,硬是把自己关闭在一个房间里,闭塞空气的流通。”中国人直到100年后的今天,用自己的亲身体验体会到“硬是把自己关闭在一个房间里,闭塞空气的流通”的痛苦之后,才明白“抗拒西洋文明是愚蠢的 ”这个道理。

上次我说了,如果中国早在100年前,认真读一读福泽谕吉的文章,早在100年前对外开放,早在100年前主动请外国人来中国,中国会是今天这样的命运吗?现在常听到中国人说“改革开放”的政策好,可是100年前提出“对外开放”的人,一定要被批为汉奸了。现在中国的奋斗目标是:2050年达到中等发达国家水平。如果中国提早100年搞改革开放,现在中国肯定会达到中等发达国家水平以上吧。

当然中国人的“仇外”心里还没有完全脱却,现在有人说“外国好”,大致还是要被骂为“汉奸”的。

(之三)

现在中国有一种流行的观点,认为日本明治维新后积极向西方学习,而当时的满清政府顽固守旧,不肯向西方学习,这是近代中国落后的结症。如果认真谈起来,这个观点只说对了一半。当年满清政府向西方学习还是抱着相当积极的态度,洋务运动就是明显的例子。

当初中国人认为中国败给西方列强,只是因为兵器不够精良,中国的国家体制并没有问题,这就是“军事救国论”,也称洋务运动。李鸿章说:“中国文武制度,事事远出于西人之上,独火器万不能及。……中国欲自强,则莫如学习外国利器,欲学习外国利器,则莫如觅制器之器,师其法,而不必尽用其人。”(李鸿章总理衙门函,同治三年)。

洋务运动是在“军事救国论”的基础上,试图学习西洋的军事技术实现自强的尝试。中国搞洋务运动开始比日本早,规模比日本大。1863年,李鸿章在上海购建了三所洋炮局;1865年,李鸿章购买了两家英美的机器厂,成立江南机器厂。清廷指定用上海关税的二成(约白银60多万两)作为其常年经费。这个厂以生产枪炮、子弹为主,兼修船舰,并附有翻译馆。1866年左宗棠在福州马尾创建福州船政局和马尾船厂,由福建海关税收的四成结款内拨付。1869年1月10日,马尾船厂制造的第一艘轮船下水。北洋、南洋、广东、福建水师的88艘军舰中,有30艘出自马尾船厂。马尾船厂造的排水量1560吨“扬武”号战舰,还参加了后来的甲午海战。

考虑到日本1868年才开始搞明治维新,中国洋务派学习西洋军事技术的自强运动是先于日本的。当时中国办现代化海军也是竭尽全力,在19世纪80年代,日本海军有军舰数量24艘,其中3000吨级战舰3艘,2000吨级战舰3艘,总吨位3万多吨。相比之下,当时中国北洋海军有军舰数量18艘,7000吨级2艘,2000吨级5艘,总吨位3万多吨。从军舰的质量水平来看,中国超过日本一筹。特别是2艘7000吨级定远舰、镇远舰居当时亚洲第一。

中国在甲午战争的失败,宣告军事强国的洋务运动彻底失败,人们认为日本打败中国就是因为采用了西洋式的国家体制,于是“体制救国论”,即改革国家体制来实现富国强兵的论调高涨,终于发生了戊戌变法。尽管戊戌变法失败了,但清廷 1901年以后实行的“新政”,基本上采用了戊戌变法的思路,对国家体制进行了重大改革,但是中国还是没有像日本那样实现富国强兵,为什么呢?

应该说在中日甲午战争前的30年间,中国和日本都在积极向西方学习,都积极引进西方的先进技术。但是两国学习西方的动机却完全不同。

日本学习西方是放弃以前日本的旧文明,全面引进西方的新文明,也就是所谓的全盘西化。中国学习西方的目的,却是为了保存中国的中华文明,中国富国强兵的目的,是要把中国建成一个抵抗西洋文明的堡垒。中国一方面要引进和学习西洋文明,一方面又要坚持中国以前的旧的中华文明,这件事本身就是矛盾的。就像郑观应在《盛世危言》(1893年)所说:“西人立国,育才于学堂,论证于议院,君民一体,上下同心,务实戒虚,谋定而后动,此其体也。轮船,火炮,洋枪,水雷,铁路,电线,此其用也。中国遗其体而求其用,无论竭蹶,常不相及;就令铁舰成行,铁路四达,果以足恃欤?”

读福泽谕吉《脱亚论》,让我感到震动的就是当时日本对西洋文明的接纳,而不是抵制。福泽谕吉《脱亚论》的中心思想也是让大家接纳西洋的先进文明。可是直到今天,中国对西洋文明还是抱着抵制的态度。中国今天的自强思路,也还是没有摆脱“中体西用”的思路,坚持在中华文明的基础上,学习西洋文明。

日本学习西洋文明,这本身就是它的目的;而中国学习西洋文明,却是一种权宜之策,或者是一个手段,其目的仍然是保持和坚持中华文明。但文化和政治制度是配套的,西洋国家的政治制度是建立在西洋文化或西洋文明的土壤中,把西洋政治制度从西洋文化中割裂开来,只学西洋的政治制度,不要西洋文明的文化土壤,即所谓“中体西用”,用中华思想来运作西洋的政治体制,必然很难搞好。

中国一直到现在也没有实现“现代化”,我以为其中最大的障碍之一,就是我们一直用中华思想来运作西方文明的东西。

Wednesday, September 14, 2011

Enable Visual Studio 2010 in Matlab 2008a

If you want to speed up your matlab code, MEX may be the first thing you should try. However, Matlab 2008a was released before Visual Studio 2010, so VS 2010 is not directly supported. You could try the following patch:

http://www.mathworks.com/support/solutions/en/data/1-D5W493/?solution=1-D5W493

And then run “mex –setup”. Everything should work.

Sunday, September 11, 2011

911乱写


8×8风波结束之后,邓小平有一段广为流传的讲话:
“也许这样一件坏事,会使我的事业前进的...我们前进的步子更稳,更好,甚至于更快,是我们的失误纠正的更快,使我们的长处发扬的更快,更好...”
那场风波对我们有多大影响,我不好说,可能你甚至不知道有那场风波!所以我觉得小平这句话是失策了,反正是没全部应验吧!不过在大洋彼岸,另一场风波——911事件——却在持续的影响这那里的人。
今天是911的十周年纪念日,美国官方与民间都组织了盛大的纪念活动!昨天跟几个美国人聊周末的计划,他们异口同声地说要去NYC参加祷告,他们反过来问我周末干什么!我没心没肺的说“中秋火锅party”...我当时说完就后悔了,心想要是为这被这几个人打一顿,你都没地方说理!不过还好,他们没打我,只是非常遗憾的说我们也想去,但还是祷告比较重要...
晚上在家我就想,要是国内汶川纪念日的时候,一群美日韩在学校大贴广告,号召一起吃烧烤,看球赛,不知会发生什么情况?我猜要是刚开学,一场血雨腥风的文攻武卫是少不了的,要是学期末,估计只会有几个大哥扔矿泉水瓶并喊“吵什么吵,没看见复习嘛!”
从西安的反日游行,抵制家乐福,声讨王千源,声讨扔鞋男......为什么搞这些跟狂欢没什么区别的事时,大家都这么亢奋;而面对三鹿喝死的孩子,豆腐渣校舍下的孩子,黑煤窑里的童工时,我们大多选择缄默和无视,有多少人会放弃自己的休息时间,娱乐事件,去真的做一些实实在在能影响周围人,哪怕是最平凡的人,的事情,做一些支持并缅怀他们的事!当然,我倒不觉得游行什么的不对,但打砸就不对了吧,即使你觉得必须打砸,那也不能区别对待吧,碰上警用丰田就绕道走,专砸那些20万以下,没权没势小市民的丰田,你这样很酷么,其实超级SB,而且是道德卑劣的超级SB!
最后,希望那些超级SB看看圣雄甘地和最近那个绝食反腐的阿三,再了解一下上个世纪的光复会!这些人选择的手段不同,但都把舍身放在前面,然后取义!我是没见过坐在人人上刷留言,砸商店,压马路的人能取义!

Friday, September 9, 2011

Nvidia Optimus为什么在Linux上是个大问题?

This article is a direct translation from relative pages from “nouveau” wiki. So, thanks to the author first:)
  • Nvidia Optimus
如果你的笔记本电脑有Optimus,说明你的电脑有一块Nividia的显卡和另一块其他品牌的显卡(只可能是Intel的?)。除了Nvidia GPU的PCOPY引擎是新技术外【1】,Optimus可以说就是双显卡笔记本电脑的另一个商业名词。
  • 为什么Optimus是个大问题
简单的说,一塌糊涂。
一个显卡需要有一个GPU,一些内存,这些内存可能是显卡专有的(例如独立显存),也可以直接是一块系统内存(大部分集成显卡就是这么做的),还需要一个输出(比如插口)来连接你的显示器。对于笔记本电脑来说,自带的屏幕也可以认为是一种显示器。
为什么Optimus会变成Linux的噩梦呢?因为你无法知道输出连着哪个GPU。换句话说,如果在不同的硬件(GPU)之间有个多路复用模块的话,这个多路复用模块是由软件控制的!
这个多路复用模块,如果存在的话,用来控制哪个GPU来驱动显示器,或自带的屏幕。如果一个GPU已经连接了显示器,那么这个多路复用模块还应该告诉另一个显卡该屏幕不可用。当我们外接显示器的时候,情况是类似的。当显示器与一个GPU相连,其他的GPU就不能再链接这个显示器了。一种恶心的情况是Intel GPU与自带的屏幕相连,Nvidia GPU与外接显示器相连。当然这种情况就不好处理了。最理想的情况是这个多路复用模块能选择哪个GPU来驱动所有的输出设备。
一般来说,你可以选择任何一种可能的组合(如上文提到的),因为怎么连接屏幕应该是自由的!我们应该有办法来检测链接的情况,当然更应该知道这个多路复用模块是否真的存在和这个模块在哪!但现实是这些相关的文档并没有开放,开发者无从知晓!
目前来说,检测链接情况是唯一的难点!当你用GPU执行渲染的时候麻烦就来了,我们无法将渲染的结果正常输出。或者说GPU根本无法输出。因为要想让一个渲染的图像正常显示,我们需要将这个结果复制到一块驱动显示设备的GPU能找到的地方(内存)。
这么说来我们只少了帧缓存复制这步么?当然不是,我们还缺少整个内核DRM驱动,X驱动和X服务器来支持Optimus。除了一些特例外,这专有的驱动在Linux上还不能支持!
另一方面,省电是Optimus的主要目的,转换GPU是相对容易的。如果多路复用模块存在,而且硬件制造商也清楚,你可能已经能选择在一次会话中专用哪个GPU了,或干脆把不用的那个不用的GPU关了。除了这外,其他所有情况都是很复杂的!
  • 现在什么能正常工作?
如果你笔记本电脑的多路复用模块是硬件实现的,内核switcheroo驱动在启动的时候能自动尝试转换可行的GPU驱动。这种转换还能做些改动,比如ASUS-Switcheroo,但他并没有提供什么额外的功能。如果某个变体碰巧能行,但原本的switcheroo不行,这说明原本的转换还有些问题。针对主流内核的补丁可能已经在开发了。
针对另一些情况,你只能停留在当前默认的配置,当然还是不能转换显卡,不能复制帧缓存。

【1】PCOPY引擎:
我们看下面这段话。
"We needed hardware support to quickly move the graphics data around in the system, so we created a fast copy engine. The Optimus Copy Engine is a new alternative to traditional DMA (Direct Memory Access) transfers between the GPU frame buffer memory and system memory used by the IGP. With Optimus we also removed multiplexers, called MUXs, so we use the integrated graphics as a display adapter or pass through."
“我们需要硬件支持系统内的图形信息快速拷贝,所以我们制造了一种快速的复制引擎。Optimis Copy Engine可以替代传统的DMA(内存直接访问单元)来执行GPU帧缓存与集成显卡使用的系统内存间的复制操作。在Optimus下,我们还移除了多路复用模块,所以我们用集成显卡来做显示器的接口或通路。”
--Sasha Ostojic
Sasha Ostojic是Nvidia的笔记本电脑软件高级总监,上面这段话出Nvidia的博客。

Thursday, September 8, 2011

英语学术论文常用句型

英语学术论文常用句型
    Beginning
    1. In this paper, we focus on the need for
    2. This paper proceeds as follow.
    3. The structure of the paper is as follows.
    4. In this paper, we shall first briefly introduce fuzzy sets and related concepts
    5. To begin with we will provide a brief background on the

    Introduction
    1. This will be followed by a description of the fuzzy nature of the problem and a detailed presentation of how the required membership functions are defined.
    2. Details on xx and xx are discussed in later sections.
    3. In the next section, after a statement of the basic problem, various situations involving possibility knowledge are investigated: first, an entirely possibility model is proposed; then the cases of a fuzzy service time with stochastic arrivals and non fuzzy service rule is studied; lastly, fuzzy service rule are considered.

    Review
    1. This review is followed by an introduction.
    2. A brief summary of some of the relevant concepts in xxx and xxx is presented in Section 2.
    3. In the next section, a brief review of the .... is given.
    4. In the next section, a short review of ... is given with special regard to ...
    5. Section 2 reviews relevant research related to xx.
    6. Section 1.1 briefly surveys the motivation for a methodology of action, while 1.2 looks at the difficulties posed by the complexity of systems and outlines the need for development of possibility methods.

    Body
    1. Section 1 defines the notion of robustness, and argues for its importance.
    2. Section 1 devoted to the basic aspects of the FLC decision making logic.
    3. Section 2 gives the background of the problem which includes xxx
    4. Section 2 discusses some problems with and approaches to, natural language understanding.
    5. Section 2 explains how flexibility which often ... can be expressed in terms of fuzzy time window
    6. Section 3 discusses the aspects of fuzzy set theory that are used in the ...
    7. Section 3 describes the system itself in a general way, including the ….. and also discusses how to evaluate system performance.
    8. Section 3 describes a new measure of xx.
    9. Section 3 demonstrates the use of fuzzy possibility theory in the analysis of xx.
    10. Section 3 is a fine description of fuzzy formulation of human decision.
    11. Section 3, is developed to the modeling and processing of fuzzy decision rules
    12. The main idea of the FLC is described in Section 3 while Section 4 describes the xx strategies.
    13. Section 3 and 4 show experimental studies for verifying the proposed model.
    14. Section 4 discusses a previous fuzzy set based approach to cost variance investigation.
    15. Section 4 gives a specific example of xxx.
    16. Section 4 is the experimental study to make a fuzzy model of memory process.
    17. Section 4 contains a discussion of the implication of the results of Section 2 and 3.
    18. Section 4 applies this fuzzy measure to the analysis of xx and illustrate its use on experimental data.
    19. Section 5 presents the primary results of the paper: a fuzzy set model ..
    20. Section 5 contains some conclusions plus some ideas for further work.
    21. Section 6 illustrates the model with an example.
    22. Various ways of justification and the reasons for their choice are discussed very briefly in Section 2.
    23. In Section 2 are presented the block diagram expression of a whole model of human DM system
    24. In Section 2 we shall list a collection of basic assumptions which a ... scheme must satisfy.
    25. In Section 2 of this paper, we present representation and uniqueness theorems for the fundamental measurement of fuzziness when the domain of discourse is order dense.
    26. In Section 3, we describe the preliminary results of an empirical study currently in progress to verify the measurement model and to construct membership functions.
    27. In Section 5 is analyzed the inference process through the two kinds of inference experiments...
This Section
    1. In this section, the characteristics and environment under which MRP is designed are described.
    2. We will provide in this section basic terminologies and notations which are necessary for the understanding of subsequent results.Next Section
    2. The next section describes the mathematics that goes into the computer implementation of such fuzzy logic statements.
    3. However, it is cumbersome for this purpose and in practical applications the formulae were rearranged and simplified as discussed in the next section.
    4. The three components will be described in the next two section, and an example of xx analysis of a computer information system will then illustrate their use.
    5. We can interpret the results of Experiments I and II as in the following sections.
    6. The next section summarizes the method in a from that is useful for arguments based on xx

    Summary
    1. This paper concludes with a discussion of future research consideration in section 5.
    2. Section 5 summarizes the results of this investigation.
    3. Section 5 gives the conclusions and future directions of research.
    4. Section 7 provides a summary and a discussion of some extensions of the paper.
    5. Finally, conclusions and future work are summarized
    6. The basic questions posed above are then discussed and conclusions are drawn.
    7. Section 7 is the conclusion of the paper.

    Chapter 0. Abstract
    1. A basic problem in the design of xx is presented by the choice of a xx rate for the measurement of experimental variables.
    2. This paper examines a new measure of xx in xx based on fuzzy mathematics which overcomes the difficulties found in other xx measures.
    3. This paper describes a system for the analysis of the xx.
    4. The method involves the construction of xx from fuzzy relations.
    5. The procedure is useful in analyzing how groups reach a decision.
    6. The technique used is to employ a newly developed and versatile xx algorithm.
    7. The usefulness of xx is also considered.
    8. A brief methodology used in xx is discussed.
    9. The analysis is useful in xx and xx problem.
    10. A model is developed for a xx analysis using fuzzy matrices.
    11. Algorithms to combine these estimates and produce a xx are presented and justified.
    12. The use of the method is discussed and an example is given.
    13. Results of an experimental applications of this xx analysis procedure are given to illustrate the proposed technique.
    14. This paper analyses problems in
    15. This paper outlines the functions carried out by ...
    16. This paper includes an illustration of the ...
    17. This paper provides an overview and information useful for approaching
    18. Emphasis is placed on the construction of a criterion function by which the xx in achieving a hierarchical system of objectives are evaluated.
    19. The main emphasis is placed on the problem of xx
    20. Our proposed model is verified through experimental study.
    21. The experimental results reveal interesting examples of fuzzy phases of: xx, xx
    22. The compatibility of a project in terms of cost, and xx are likewise represented by linguistic variables.
    23. A didactic example is included to illustrate the computational procedure

    Chapter 1. Introduction
    Time
    1. Over the course of the past 30 years, .. has emerged form intuitive
    2. Technological revolutions have recently hit the industrial world
    3. The advent of ... systems for has had a significant impact on the
    4. The development of ... is explored
    5. During the past decade, the theory of fuzzy sets has developed in a variety of directions
    6.The concept of xx was investigated quite intensively in recent years
    7. There has been a turning point in ... methodology in accordance with the advent of ...
    8. A major concern in ... today is to continue to improve...
    9. A xx is a latecomer in the part representation arena.
    10. At the time of this writing, there is still no standard way of xx
    11. Although a lot of effort is being spent on improving these weaknesses, the efficient and effective method has yet to be developed.
    12. The pioneer work can be traced to xx [1965].
    13. To date, none of the methods developed is perfect and all are far from ready to be used in commercial systems.

    Objective / Goal / Purpose
    1. The purpose of the inference engine can be outlined as follows:
    2. The ultimate goal of the xx system is to allow the non experts to utilize the existing knowledge in the area of manual handling of loads, and to provide intelligent, computer aided instruction for xxx.
    3. The paper concerns the development of a xx
    4. The scope of this research lies in
    5. The main theme of the paper is the application of rule based decision making.
    6. These objectives are to be met with such thoroughness and confidence as to permit ...
    7. The objectives of the ... operations study are as follows:
    8. The primary purpose/consideration/objective of
    9. The ultimate goal of this concept is to provide
    10. The main objective of such a ... system is to
    11. The aim of this paper is to provide methods to construct such probability distribution.
    12. In order to achieve these objectives, an xx must meet the following requirements:
    13. In order to take advantage of their similarity
    14. more research is still required before final goal of ... can be completed
    15. In this trial, the objective is to generate...
    16. for the sake of concentrating on ... research issues
    17. A major goal of this report is to extend the utilization of a recently developed procedure for the xx.
    18. For an illustrative purpose, four well known OR problems are studied in presence of fuzzy data: xx.
    19. A major thrust of the paper is to discuss approaches and strategies for structuring ..methods
    20. This illustration points out the need to specify
    21. The ultimate goal is both descriptive and prescriptive.
    22. Chapter 2. Literature Review
    23. A wealth of information is to be found in the statistics literature, for example, regarding xx
    24. A considerable amount of research has been done .. during the last decade
    25. A great number of studies report on the treatment of uncertainties associated with xx.
    26. There is considerable amount of literature on planning
    27. However, these studies do not provide much attention to uncertainty in xx.
    28. Since then, the subject has been extensively explored and it is still under investigation as well in
    methodological aspects as in concrete applications.
    29. Many research studies have been carried out on this topic.
    30. Problem of xx draws recently more and more attention of system analysis.
    31. Attempts to resolve this dilemma have resulted in the development of
    32. Many complex processes unfortunately, do not yield to this design procedure and have, therefore, not yet been automated.
    33. Most of the methods developed so far are deterministic and /or probabilistic in nature.
    34. The central issue in all these studies is to
    35. The problem of xx has been studied by other investigators, however, these studies have been based upon classical statistical approaches.
    36. Applied ... techniques to
    37. Characterized the ... system as
    38. Developed an algorithm to
    39. Developed a system called ... which
    40. Uses an iterative algorithm to deduce
    41. Emphasized the need to
    42. Identifies six key issues surrounding high technology
    43. A comprehensive study of the... has been undertaken
    44. Much work has been reported recently in these filed
    45. Proposed/Presented/State that/Described/Illustrated/
    Indicated/Has shown / showed/Address/Highlights
    46. Point out that the problem of
    47. A study on ...was done / developed by []
    48. Previous work, such as [] and [], deal only with
    49. The approach taken by [] is
    50. The system developed by [] consists
    51. A paper relevant to this research was published by []
    52. []'s model requires consideration of...
    53. []' model draws attention to evolution in human development
    54. []'s model focuses on...
    55. Little research has been conducted in applying ... to
    56. The published information that is relevant to this research...
    57. This study further shows that
    58. Their work is based on the principle of
    59. More history of ... can be found in xx et al. [1979].
    60. Studies have been completed to established
    61. The ...studies indicated that
    62. Though application of xx in the filed of xx has proliferated in recent years, effort in analyzing xx, especially xx, is lacking.
    Problem / Issue / Question
    63. Unfortunately, real-world engineering problems such as manufacturing planning do not fit well with this narrowly defined model. They tend to span broad activities and require consideration of multiple aspects.
    64. Remedy / solve / alleviate these problems
    67. ... is a difficult problem, yet to be adequately resolved
    68. Two major problems have yet to be addressed
    69. An unanswered question
    70. This problem in essence involves using x to obtain a solution.
    71. An additional research issue to be tackled is ....
    72. Some important issues in developing a ... system are discussed
    73. The three prime issues can be summarized:
    74. The situation leads to the problem of how to determine the ...
    75. There have been many attempts to
    76. It is expected to be serious barrier to
    77. It offers a simple solution in a limited domain for a complex

Monday, September 5, 2011

Viola Jokes


闪电和中提琴手的手指为何相同:从来不在同个地方按两次
怎样防止你的小提琴被盗 放在中提琴盒里
小提琴和中提琴的区别 中提琴烧得久一些 中提琴啤酒能装得多一些 你能给小提琴调音
我们都知道中提琴优于小提琴因为它烧得更久,不过为什么会烧得久呐 因为它通常都在盒子里
如何让一个中提琴声部演奏spiccato(跳弓) 在音符上都标solo
怎样让一个中提琴手演奏一段pianissimo tremolando(非常弱的颤音) 在音符上标solo
中提琴和棺材有什么区别 棺材里有死人
你会拿一个死掉的中提琴手怎么办 拖到声部后面一个位子上
中提琴和蹦床的区别 玩蹦床的时候要脱了鞋在上面跳
中提琴和洋葱的区别 剁碎(抨击)
中提琴的时候不会有人哭<——貌似双关吧
小二度的定义 两个中提琴一起演奏 ……【太恶毒了这个】
绝对音高的定义 不碰桶边的情况下成功将中提琴扔进垃圾桶
为什么中提琴会在别人屋外站很久 他们找不到钥匙,并且不知道什么时候该进
中提琴和缝纫女工的区别 缝纫女工会折褶边 ……【这个不太懂】
洗衣机和中提琴的区别 颤音
为什么很多人不假思索厌恶中提琴 省事儿
怎样辨别中提琴拉跑调了 弓子在动
卡农是怎样写出來的 两个中提琴试图齐奏一个段落
为什么拉中提琴会像尿裤子 两者都是悄无声息地给你温暖的赶脚……【好恶毒啊】
为什么中提琴的独奏像炸弹 等听到再想采取措施就为时已晚
为什么中提琴的独奏像早泄 因为等你知道要射,干啥都来不及了。。。【中提琴是有多不招人待见】
为什么中提琴手要把琴盒放在他们汽车的仪表板上 那样他们就能把车停在残疾人专用停车位上 要是有人把他们误认为是黑手党,他们至少还能留点面子
中提琴手为啥不玩躲猫猫 因为没人会想到去找他们
为什么中提琴手演奏的时候在笑 因为无知是一种幸福,并且这种无知不会伤害他们
为什么中提琴手不应该去登山 如果他们失踪了,恐怕很多年都不会有人发觉这一点
路边的死鬼和路中间被压碎的中提琴有什么区别 【这个不懂,求解】
怎样让小提琴听着像中提琴 坐在后面不演奏 低音区演奏(是说用G弦D弦吧),还一堆错音
把中提琴和女高音一块从悬崖上扔下去,哪个先落地?(两个答案) 答案1:中提琴。女高音半截会停下来问方向 答案2:管它的
一个指挥和一个中提琴站在路中间,你会先轧过哪个,为什么: 指挥,正事要紧,享乐再说
为什么中提琴喜欢恐怖主义分子 他们都跟弓法过不去(bowings谐音Boeings波音公司)
William Walton最受欢迎的中提琴协奏曲录音? 缺少中提琴solo的录音版本(Music Minus One, 详解见wiki http://en.wikipedia.org/wiki/Music_Minus_One
中提琴和诉讼案的相似之处 琴盒盖上和案子结束的时候,大家都会很开心 【case closed双关了】
中提琴的范围 【指声音传播的范围么?】 你脚能踢到的距离内
飞毛腿导弹与中提琴手的相似之处 都具攻击性和不准确性
为什么中提琴那么大只 只是视觉上的错觉。并非中提琴大只,而是中提琴手的脑袋太小了
链锯与中提琴的区别 如果非要的话,你在四重奏里也可以用用链锯的
音堆和弦(cluster chord)的定义 中提琴声部在C弦上演奏
为什么中提琴手看到《爱经》就坐立不安? 看那些位置啊……【体位把位,傻傻分不清】
如果迷失在沙漠里,你打算怎么办?去找优秀的中提琴手,糟糕的中提琴手还是绿洲:糟糕的中提琴手。另外两个都是你臆想出來的
为什么你不应该开MINI Cooper载三个中提琴驶离悬崖 至少能和一个相处融洽 【问题原文用shouldn‘t, 没有错么?】
拧灯泡需要多少个中提琴手 一个也不用,都不够小
为什么看到有人提着中提琴盒进银行,大家就吓得要死 他们以为这人提的是机枪,并且可能真的会用它
中提琴声部里第一个位子和最后一个有何区别 差一拍 差半音
为什么你在数字录音碟中听不到中提琴 录音技术发展到如此先进地步,所有无关杂音都被自动剔除了
见识过中提琴手自夸能拉32分音符么 乐队里其余的人都不相信,所以他拉了一个以示证明……【一个...= =】
为什么中提琴在德语里叫 bratsche 因为你一屁股坐上去它就会发出那样的声音
为什么中提琴手后背插把刀就不能演奏了 因为他不能靠在椅背上了
中提琴最嫉妒什么乐器 竖琴。只要空弦拨拉拨拉就可以了
中提琴试奏的别名 刮刮乐…… 【槽点不太清楚】
如何让一打中提琴手齐奏 毙掉11个 毙掉所有的 谁他妈想要一打中提琴
纽约市最近一次犯罪陡升是 中提琴演奏会上的
中提琴手的脑细胞怎么死的 孤独而死
怎么称呼只有俩脑细胞的中提琴手 怀孕(有前途的)
为什么中提琴的脑子只有豆粒大 酗酒的过
做一炉巧克力豆曲奇需要多少个中提琴手 10个。一个和面糊,另外9个剥M&M豆
披头士和皇家爱乐乐团的中提琴声部有何共通点 二者自1970年之后就没在一起演过
最长的中提琴笑话 哈罗德在意大利
几个中提琴手在热水浴缸里该叫什么 蔬菜汤
听说过不跑调的中提琴手么 我也没听说过
国际中提琴大赛的主要要求是什么 按记忆持琴……【这个不明白】
为什么中提琴和手风琴结婚了 【Upward mobility 这个不清楚是什么】
如何将小提琴作品改成中提琴的 用一个小节劈成2个(拍子慢一倍)
为什么埋中提琴手只有地下三英寸深 再往下都是好人了
如何保证一个中提琴手不溺水 把你的脚从他脑袋上拿开
注:下面这个笑话德语讲很有趣,但翻成英语就不太好玩了 Was sind die drei Lagen auf der Bratsche? Erste Lage, Notlage, und Niederlage. 中提琴的三个把位? 第一把位,紧急把位,挫败把位 ---------
How is lightning like a violist's fingers? Neither one strikes in the same place twice.
How do you keep your violin from getting stolen? Put it in a viola case
. What's the difference between a violin and a viola? The viola burns longer. The viola holds more beer. You can tune the violin.
We all know that a viola is better than a violin because it burns longer. But why does it burn longer? It's usually still in the case.
How do you get a viola section to play spiccato? Write a whole note with "solo" above it.
How do you get a violist to play a passage pianissimo tremolando? Mark it "solo."
What's the difference between a viola and a coffin? The coffin has the dead person on the inside.
What do you do with a dead violist? Move him back a desk.
What's the difference between a viola and a trampoline? You take your shoes off to jump on a trampoline.
What's the difference between a viola and an onion? No one cries when you cut up a viola.
What's the definition of a minor second? Two violists playing in unison.
What's the definiton of "perfect pitch?" Throwing a viola into a dumpster without hitting the rim.
Why do violists stand for long periods outside people's houses? They can't find the key and they don't know when to come in.
What's the difference between a seamstress and a violist?The seamstress tucks up the frills.
What's the difference between a washing machine and a violist?Vibrato.
Why do so many people take an instant dislike to the viola? It saves time.
How can you tell when a violist is playing out of tune? The bow is moving.
How was the canon invented? Two violists were trying to play the same passage together.
Why is playing the viola like peeing in your pants? They both give you a nice warm feeling without making any sound.
Why is a viola solo like a bomb? By the time you hear it, it's too late to do anything about it.
Why is a viola solo like premature ejaculation? Because even when you know it's coming, there's nothing you can do about it.
Why do violists leave their instrument cases on the dashboards of their cars? So they can park in "handicapped" parking places. If someone mistakes them for mafia, they might get some respect.
Why don't violists play hide and seek? Because no one will look for them.
Why do violists smile when they play? Because ignorance is bliss and what they don't know can't hurt them.
Why shouldn't violists take up mountaineering? Because if they get lost, it takes ages before anyone notices that they're missing.
What's the difference between a dead skunk in the road and a crushed viola in the road? Skid marks before the skunk.
How do you get a violin to sound like a viola? Sit in the back and don't play. Play in the low register with a lot of wrong notes. If you throw a violist and a soprano off a cliff, which one would hit the ground first? (two answers) The violist. The soprano would have to stop halfway down to ask directions. Who cares?
A conductor and a violist are standing in the middle of the road. which one do you run over first, and why? The conductor. Business before pleasure.
What's the most popular recording of the William Walton viola concerto? Music Minus One
What do a viola and a lawsuit have in common? Everyone is happy when the case is closed.
What is the range of a Viola? As far as you can kick it.
What do a SCUD missile and a viola player have in common? They're both offensive and inaccurate.
Why are violas so large? It's an optical illusion. It's not that the violas are large; just that the viola players' heads are so small.
What's the difference between a chain saw and a viola? If you absolutely had to, you could use a chain saw in a string quartet. What is the definition of a cluster chord? A viola section playing on the C string.
Why do violists get antsy when they see the Kama Sutra? All those positions! If you're lost in the desert, what do you aim for? A good viola player, a bad viola player or an oasis? The bad viola player. The other two are only figments of your imagination.
Why shouldn't you drive off a cliff in a mini with three violas in it? You could fit in at least one more. How many violists does it take to screw in a light bulb? None. They're not small enough to fit.
Why do people tremble with fear when someone comes into a bank carrying a violin case? They think he's carrying a machine gun and might be about to use it.
Why do people tremble with fear when someone comes into a bank carrying a viola case? They think he's carrying a viola and might be about to use it.
What's the difference between the first and last desk of a viola section? half a measure a semi-tone Why can't you hear a viola on a digital recording? Recording technology has reached such an advanced level of development that all extraneous noise is eliminated.
Did you hear about the violist who bragged that he could play 32nd notes? The rest of the orchestra didn't believe him, so he proved it by playing one.
Why is viola called "bratsche" in Germany? Because that's the sound it makes when you sit down on it.
Why can't a violist play with a knife in his back? Because he can't lean back in his chair. What instrument do violists envy most? The harp. You only ever have to play pizzicato on open strings.
What's another name for viola auditions? Scratch lottery. What is the difference between a violist and a prostitute? A prostitute knows more than two positions. Prostitutes have a better sense of rhythm.
What is the similarity between a violist and a prostitute? Both are paid to fake climaxes.
How do you get a dozen violists to play in tune? Shoot 11 of them. Shoot all of them.Who the hell wants a dozen violists?
What's the latest crime wave in New York City?Drive-by viola recitals.
How does aviolist's brain cell die? Alone. How do you call a violist with two brain cells? Pregnant.
Why do violists have pea-sized brains? Because alcohol has swelled them.
How many violists does it take to make a batch of chocolate chip cookies? Ten. One to stir the batter and nine to peel the M & M's.
What's the similarity between the Beatles and the viola section of the Royal Philharmonic Orchestra? Neither has played together since 1970.
What is the longest viola joke? Harold in Italy
What do you call a bunch of violists in a hot tub? Vegetable soup.
Did you hear about the violist who played in tune? Neither did I. What is the main reqirement at the "International Viola Competition?" Hold the viola from memory.
Why did the violist marry the accordion player? Upward mobility.
How do you transcribe a violin piece for viola? Divide the metronome marking by 2.
Why do you always bury a viola player three feet under? Because deep down they are all very nice people.
How do you keep a violist from drowning? Take your foot off his head. Note: the following joke is very funny in German, but doesn't translate well into English.
Was sind die drei Lagen auf der Bratsche? Erste Lage, Notlage, und Niederlage. (What are the three positions of the viola? First position, emergency, and defeat.) Viola Jokes (part 1) http://bit.ly/oeLLhd