2009年7月16日星期四

classic words

"假如我是对的,相信你是会接受的,因为你是聪明而智慧的"。——芒格
无论你使用什么样的方法挑选股票或者股票共同基金,决定成败的关键在于一种能力---不受市场波动的干扰,坚持到投资获得成功的能力。决定股票挑选者命运的不是他们的头脑,而是他们的耐力。敏感的投资者,无论他有多聪明,往往经受不住命运不经意的打击,而被赶出股市。
------彼得.林奇
乱局即大局
索罗斯说过:金融市场天生就不稳定,国际金融市场更是如此,国际资金流动皆是有荣有枯,有多头也有空头。市场哪里乱哪里就可以赚到钱。辨识混乱,你就可能致富;越乱的局面,越是胆大心细的投资者有所表现的时候。
一项情形变的越遭,就会向上弹的越高。跌的越深,市场越乱就越可能出现大行情。很多情况常常是:市场乱,投资人跟着一起乱。所以我们常常可见到恐慌性卖压,投资人奋勇追高等新闻标题。乱局对冷静的客观投资人来说,正式天赐良机,因为这可能是大捡便宜货的机会,也是财富重新分配的时候。
不买落后股,不买平庸股,全心全力锁定领导股! -----[美国]威廉.欧奈尔
  
主流类中的股票,常能涨得惊天动地,但
其他平庸个股,连一丝涟漪都不会起!------[美国]威廉.欧奈尔
  
选择一个行业股票时,要选两家,但不是随便找两家,应选一家最好和一家最差的!----[美国]乔治.索罗斯
  
投资不仅仅是一种行为,更是一种带有哲学意味的东西! ------[美国]约翰.坎贝尔
  
不进行研究的投资,就象打扑克从不看牌一样,必然失败! ---[美国]彼得.林奇
  
不要懵懵懂懂的随意买股票,要在投资前扎实的做一些功课,才能成功!
-----[美国]威廉.欧奈尔
  
你永远不要犯同样的错误,因为还有好多其他错误你完全可以尝试!
——[英国]伯妮斯.科恩
  
风险来自你不知道自己正在做什么! ——[美国]沃伦.巴菲特
  
错误并不可耻,可耻的是错误已经显而易见了却还不去修正! ——[美国]乔治.索罗斯
    
经验显示,市场自己会说话,市场永远是对的,凡是轻视市场能力的人,终究会吃亏的!——[美国]威廉.欧奈尔
  
如果你没有做好承受痛苦的准备,那就离开吧,别指望会成为常胜将军,要想成功,必须冷酷!-----[美国]索罗斯
  
股票市场最惹人发笑的事情是;每一个同时买和同时卖的人都会自认为自己比对方聪明!----[美国]费瑟
  
始终遵守你自己的投资计划的规则,这将加强良好的自我控制!
----[英国]伯妮斯.科恩]
  
承担风险.无可指责,但同时记住千万不能孤注一掷! ---------[美国]乔治.索罗斯
  
股票市场是有经验的人获得更多金钱,有金钱的人获得更多经验的地方! ---[美国]
朱 尔
  
每个笨蛋都会从自己的教训中吸取经验,聪明人则从别人的经验中获益! ---[德国]
俾 斯 麦

股市长久的获利公式

众所周知,在投机市场能长久生存是很难的,能做到长久持续获利的投机者确实是凤毛麟角.市场上很多投机者,最后都带着疲惫的身心,受伤的钱囊,黯然地离开了市场.尤其是曾经如流星般辉煌的明星,他们升得很快,跌得也很惨.
  如何界定投机者在市场上的成功呢?
首先,是在一段较长时间内,其盈利交易的利润要大于亏损交易的损失.成功=盈利-亏损>0.
这个公式是如此简单,以至常常被人忽视.
  股市投资是一个长期的工作.职业.它不是百米冲刺,而是漫长的马拉松运动,不在于你一次能获得50%或者100%的盈利,而在于你能长久地在市场生存并获利.美国投资大师巴菲特每年的资金回报率为30%左右就奠定了其世界第二富翁的地位.巴林银行的利森,刚到新加坡时,其资金回报率很高,却酿成了巴林银行的破产.
  成功=盈利-亏损>0.成功公式要求投机者十分看重自己的本金,每次交易都不能遭受重大亏损,如果出现亏损,应该尽快地摆脱亏损头寸.相反,盈利的交易应尽可能地使利润扩大化.
  如何控制每次交易的亏损呢?
首先,投资者入市前不要考虑要赚多少钱,首先设想的是,如果判断错误怎么办,每次交易最多承受多大的风险,投入多少资金,亏损的资金占本金多少.这里有个经验指标,每次亏损不超过本金的3%.如果亏损了,下次亏损不超过剩下的本金的3%.这样即使你连续10次判断失误造成亏损,你还能保有近80%的本金,完全有资本重新再来.并且,连续10次亏损的概率是很小的.
  如何使利润最大化呢?
要牢记一个原则,就是不能让起先盈利的交易以亏损告终.当你趋势判断正确,并且在正确的时机中介入市场,你会很快享受盈利的快乐,这时,所考虑的不应是落袋为安,不要害怕市场突然下跌,往往这种害怕是你的情绪在作怪,你应该希望你的利润增长,应该欢喜地看着市场上扬.
同时,你的止盈点应靠近市场最近的低点,和市场一同上扬.永远不要考虑卖个最高价,所要考虑的仅仅是市场趋势反转时你的出场点.这时不要贪心,不要指望市场回到最高点再卖出.不要让盈利的交易亏损,这个原则的作用就在于此.
  要做到长久的获利,就必须牢记成功公式,减少进出市场的次数,能使你的判断成功率大增.要知道,你介入市场,不是要证明你有多能干,而是在低风险下获取利润.

2009年7月15日星期三

vim 简明完全手册

一、 对vim配置文件的编辑:
:scriptnames 发现配置文件的位置
:edit ~/.vimrc 编辑该配置文件
vim说明文件的阅读:
CTRL-] 跳转到当前光标所在单词对应的主题
CTRL-O 回到前一个位置
复制一个样板vimrc文件(unix):
:!cp -i $VIMRUNTIME/vimrc_example.vim ~/.vimrc
复制一个样板vimrc文件:
:set compatible?
查看vim配置文件的所在位置:
:scriptnames 或 :version
拷贝vimtutor,并重命名:
vim -u NONE -c `e $VIMRUNTIME/tutor/tutor.cn` -c `w! TUTORCOPY` -c `q`
vim -u NONE -c "set nocp" TUTORCOPY

会话保存了整个Vim的外观. 视图保持一个窗口的属性
:mkview [num] "保存当前窗口的视图,num可以是1-9"
:loadview [num] "载入上次保存的视图,num可以是1-9"
:mkview ~/.vim/main.vim "保存当前的文件的视图到文件"
:source ~/.vim/main.vim "载入已存在的试图文件"
:set viminfo=string "string指代你要保存的东西.
其语法是一个选项字符跟一个参数. 一对对的选项/参数以逗号分隔",可用选项有:
: 要保存的冒号命令历史记录数
@ 要保存的输入历史记录数
/ 要保存的搜索命令历史记录数
r 可移动介质, 对此不会保存其标记信息(可以多次使用)
! 以大写字母开始并且不含有任何小写字母的全局变量
h 开始时禁用°hlsearch°选项
% 缓冲区列表(只有没指定文件参数启动Vim时才会恢复这些信息)
c 使用°encoding°选项中的方法进行字符编码转换
n viminfo文件的名字(必需是最后一个选项)
在Vim中用":wviminfo"和":rviminfo"命令来保存和恢复这些信息,
:wviminfo! ~/tmp/viminfo "保存一个viminfo的信息"
:rviminfo! ~/tmp/viminfo
"读取一个viminfo的信息,这样可用把其他文件的viminfo那来用"
:mksession vimbook.vim "创建一个会话文件"
:source vimbook.vim "恢复一个会话状态"
vim -S vimbook.vim "启动Vim时恢复某个会话"
sessionoptions 选项的设置如下,如::set sessionoptions+=resize
"恢复Vim窗口的大小"
blank 空窗口
buffers 所有的缓冲区, 而不仅是当前窗口中的
curdir 当前目录
folds folds, 包括手工创建的
help 帮助窗口
options 所以的选项和键映射
winsize 窗口大小
========================================================================================
二、 在普通模式下
移动光标:
h 左 j 下 k 上 l 右
gj 下,长字符串行折行时只移动下一个屏幕显示行
gk 上,长字符串行折行时只移动下一个屏幕显示行
w (小)向后(右)移动一个word,光标在word的首字母处,如3w,向后移动3个word
b (小)向前(左)移动一个word,光标在word的首字母处,如3b,向前移动3个word
e (小)向后(右)移动一个word,光标在word的尾字母处,如3e,向后移动3个word
ge (小)向前(左)移动一个word,光标在word的尾字母处,如3ge,向前移动3个word
W
(大)向后(右)移动一个word,光标在word的首字母处,如3w,向后移动3个word,但忽略其他边界字符
B
(大)向前(左)移动一个word,光标在word的首字母处,如3b,向前移动3个word,但忽略其他边界字符
E
(大)向后(右)移动一个word,光标在word的尾字母处,如3e,向后移动3个word,但忽略其他边界字符
gE
(大)向前(左)移动一个word,光标在word的尾字母处,如3ge,向前移动3个word,但忽略其他边界字符
$ (shift
4)移动到当前行行尾,同<End>功能键,可以使用"2$"记数,移动到下一行的行尾
^ (shift 6)移动到当前行的第一个非空白字符上,不接收记数移动
0 (数字)移动到当前行的第一个字符上,同<Home>功能键,不接收记数移动
f
(小)向后(右)搜索某一单字符,光标在被搜索字符上,如"fy",搜索下一个字符y的所在,可用";"向后重复查讯,用","向前重复查讯
F
(大)向前(左)搜索某一单字符,光标在被搜索字符上,如"Fy",搜索上一个字符y的所在,可用";"向后重复查讯,用","向前重复查讯
t
(小)向后(右)搜索某一单字符,光标在被搜索字符前,如"ty",搜索下一个字符y的所在,可用";"向后重复查讯,用","向前重复查讯
T
(大)向前(左)搜索某一单字符,光标在被搜索字符前,如"Ty",搜索上一个字符y的所在,可用";"向后重复查讯,用","向前重复查讯
% 跳转到与当前光标下的括号相匹配的字符上记数+%
跳转到正文的某个部分,如"50%"将会把光标定位在文件的中间
gg 跳转到第一行
G 跳转到最后一行,可用"23G"等跳转到指定的行
H 跳转到本屏幕的开始
M 跳转到本屏幕的中间
L 跳转到本屏幕的结尾
zz 把当前行置为屏幕正中央
zt 把当前行置于屏幕顶端
zb 把当前行置于屏幕底端
删除字符:
x (小)删除一个字符,"4x"删除4个字符
d (小) 后跟任何一个位移命令,
它将删除从当前光标起到位移的终点处的文本内容,如:dd 删除一行字符,dw
删除一个word,"d4w"删除4个word,"d2e"删除2个word到词尾,"d$"删除自当前光标到行尾的内容.
c (小)删除一个word后并进入Insert模式,如:cc 删除一行后并插入一行(同"c$")
r 输入一个字符用以替换当前光标下的那个字符
J (大)删除一个换行符
u (小)撤销操作
CTRL-R 重做(反转撤消动作)
U (大)撤销上一次的操作,包括对自己的上次操作
快捷方式:
x 代表dl(删除当前光标下的字符)
X 代表dh(删除当前光标左边的字符)
D 代表d$(删除到行尾的内容)
C 代表c$(修改到行尾的内容)
s 代表cl(修改一个字符)
S 代表cc(修改一整行)
编辑命令:
i (小)在当前光标之前插入文本
a (小)在当前光标之后插入文本
o (小)当前行的下面插入新一行
O (大)当前行的上面插入新一行
9k 上移9行,其他命令也可用数字+命令的方式实现,重复的编辑操作
ZZ (大)保存当前文件并退出
放弃编辑:
:q! 放弃所有的修改并退出
:e! 放弃所有修改并重新载入该文件的原始内容
求助:
:help 得到帮助文件的起始点,等同于F1功能键
:help {subject} 得到某个特殊主题的帮助,如::help
CTRL-A,查看关于CTRL-A的帮助
:help `command` 得到关于某个选项的帮助,如:help `number`
:help E37 得到某个错误ID号的帮助
三、 小技巧:
交换两个字母,"xp"
光标在字母时中间,删除整个单词,"daw";
并可以用"."重复操作来删除整个单词。"daw"即"Delete A Word"
修改整句话,即删除整句后加入一个空行,不包含句子后面的空格(是"Inner
Sentence"的缩写),"cis"
修改整句话,即删除整句后加入一个空行,包含了句子后面的空格(是"a
Sentence"的缩写),"cas"
修改整句话,即删除整句后加入一个空行,包含了句子后面的空白,"das"
用v进入visual模式,用as可以选择一个句子。
%s/\<oldword\>/newword/gc
"把文件中所有的oldword替换成newword,如果没有'c'则就不进行提示,"g"标志则指示替换操作将一行中所有出现的目标字串都进行替"

在filename1中打开filename2,并比较filename1和filename2
:edit filename2
:vertical diffsplit filename2

简单映射:使用":map"命令,把一连串Vim命令以一个按键来表示。":map"不带参数则列出已定义的映射。
:map <F5> i{<Esc>ea}<Esc>
"在一个word的前后加上大括号"其中<Esc>和<F5>为手工键入,而不是键盘上的功能键。当把一个vim功能键变为映射
键后,就失去了原有的意义,至到映射被删除。

对字符串行进行排序:
第一种方法:
/^firstline
j
:.,/^$/-1!sort
说明:上面的命令首先会跳转到第一行, 即开头是"firstline"的行,
然后再下移一行, 用sort程序过滤自该行直至下一个空行.
第二种方法:
在Visual模式下选择要排序的行然后用"!sort"命令
反转行序:
:g/^/m 0
说明:g是命令global,m是命令move
对一串连续的行进行反转行序:
:`t+1,.g/^/m `t
说明:首先移到第一行并以"mt"标记该行.然后移到最后一行执行命令

统计文件全部内容的字数:
先键入"g",再用CTRL-g
统计文件部分内容的字数:
方法一:
将光标移到要统计部分的开头处执行"g CTRL-G"命令,
然后移到要统计部分的末尾再用一次"g CTRL-G".
计算两次命令得到的当前word位置之差, 就得到这部分内容的字数统计
方法二:
使用Visual模式, 选择要统计的部分. 然后用"g CTRL-G".

在编辑脚本或程序时查找帮助页:
光标移到要查找帮助的关键字上,然后键入"K"(大写),Vim会对光标所在的词执行"man"程序。
让man页与vim在一个窗口中显示:
首先运行man对应的文件类型plugin(可以把它放到vimrc文件里):
:source $VIMRUNTIME/ftplugin/man.vim
然后可以使用vim的"Man"命令对某些字符进行查讯帮助,如:"Man 3
echo"查找man页第三节中的echo,通过CTRL-W来切换当前窗口。

消除所有行尾的多余空格:
:%s/\s\+$//
说明:指定的行号范围是"%", 即应用于每一行中.
":substitute"命令要查找的字串是"\s\+$".这会查找位于行尾的一个或多个空白字符,":substitute"命令的"to"部分是空内容:"//".
即把此类的空白都替换为空。
查找一个word在何处被引用:
编辑所有包含了"frame. counter"的C文件
vim \VimBacktick{}grep -l frame_counter *.c\VimBacktick{}
说明:"-l"参数, 所以该命令将只是列出包含了该词的文件名而不显示匹配的行。

如果你想查找所有C程序中的"error string", 就可以用下面的命令:
:grep error_string *.c
说明:跳转到下一个匹配的行使用":cnext"命令.跳转到前一个匹配的行可以用":cprev"命令,
":clist"命令则可以一次列出所有的匹配
注:内置的":grep"命令用到了外部命令grep(Unix)或findstr(Windows).

在":"号命令行中:
CTRL-C或<Esc> 可以放弃所有已经键入的命令.
"CTRL-D"可以列出未用<tab>补全的命令。
"CTRL-P"可以向前返回已经输入过的命令,效果如同<Up>
"CTRL-N"可以向后返回已经输入过的命令,效果如同<Down>
q: 在屏幕底部打开一个命令行(小)窗口. 该窗口的内容是历史记录,
最后一行是空行。对命令行窗口作出的修改不会被保存. 历史记录不会因此被改写.

可以用CTRL-Z来挂起vim,并回到shell中,之后可用"fg"来回到vim中。

执行shell命令:
在Vim中:
:!{program} 执行{program},如!ls,!pwd,!shell等
:r !{program} 执行{program}并读取它的输出
:w !{program} 执行{program}并把当前缓冲区的内容作为它的输入
:[range]!{program} 以{program}过滤指定的行

vim -x exam.txt "加密文件exam.txt"
vim -x -n file.txt
"加密file.txt文件,并不生成交换文件,注:Vim会把所有东西都放到内存里"
:setlocal noswapfile "可在编辑过程中禁止使用交换文件"
:X "(大写)设置对文件的加密"
:set key= "停止对一个文件的加密,把`key`选项设置为一个空字串"
vim -b datafile "编辑一个二进制文件"
:set display=uhex
"设置以十六进制格式显示不可打印字符,"ga"命令可以来查明当前光标下字符的本来面目"
g CTRL-G "可以获知光标所在字符是整个文件中第几个字节"
2345go "转到第2345个字节去"
使用xxd程序编辑二进制文件的过程:
1 用vim -b datafile 打开二进制文件
2 用":%!xxd"进行十六进制格式的转储
3 编辑完毕后使用":%!xxd
-r"反向转换,逆向转换时只有其十六进制形式被认为是有效的.
对可打印形式的改变会被转换程序忽略

:hide edit two.txt
"在编辑另一个文件时而又想不保存当前的文件时,可用隐藏缓冲区的编辑"
:buffers 或:ls "列出整个缓冲区列表,"
列出的缓冲区列表说明如下:
u 未被列出的缓冲区|unlisted-buffer|[[译: 既然未被列出你又怎么知道? :ls! %
当前缓冲区
# 上一次的活动缓冲区
l 被载入并显示在某窗口中的缓冲区
h 被载入但隐藏的缓冲区.
= 只读的缓冲区
- 不可编辑的缓冲区, 其中°modifiable°选项被关闭
+ 有改动的缓冲区
:buffer [num] "在当前窗口编辑缓冲区"
:sbuffer [num] "打开一个并列的窗口编辑缓冲区"
:bdelete 3 "一个缓冲区从列表中去除"
:bnext "跳转到下一个缓冲区"
:bprevious "跳转到前一个缓冲区"
:bfirst "跳转到第一个缓冲区"
:blast "跳转到最后一个缓冲区"

:{range}center [width] 让一个范围的行居中
:{range}right [width] 让一个范围的行右对齐
:{range}left [margin] 让一个范围的行左对齐,[margin]指左边留白的宽度
左右对齐的方法:
1.使用宏包:runtime macros/justify.vim
2.使用外部程序:%!fmt

合并多行文本:
:g/./,/^$/join
说明:
:g/./ 一个全局命令, 查找那些至少有一个字符的行.
,/^$/ 指定一个范围, 从当前行开始(非空行)直到一个空行.
join ":join"命令把指定范围内的行连为一行.

重新格式化文件:
1.先修改所要修改的内容
2.用"v"命令进入Visual模式
3.选定所要重新格式化的内容后键入"gq"
4.其他格式化方式:"gqap"格式化一段文本(段以空行为分界).
包括当前光标之前的部分,"gggqG"格式化整个文件

dp "两个文件的不同被消除了,
当前窗口中引起不同的内容被放到另一窗口中缺少这段内容的地方去了.
"dp"是"diff put"的缩写"
将光标移到右边的窗口, 到"changed"插入的位置.键入命令:do
vim也会消除了该位置的不同之处,"do"意为"diff obtain"

将"Last, First"改为"First Last",使用命令:
:%s/\([^,]*\), \(.*\)/\2 \1/
说明:替换操作的命令参数形如"/from/to/".
斜杠是用来分隔"from"和"to"的.对于"from"部分对应的内容:
第一个部分位于\( \)之间, 对应"Last" \( \)
匹配除逗号外的任何东西[^,]
任意次重复*
匹配", " ,
第二个部分位于\( \)之间, 对应"First" \( \)
任意字符 "."
任意次重复 "*"
在 对应"to"的部分我们指定了"\2"和"\1". 这在Vim中被称作反向引用.
它们可以用来指代此前在\( \)中匹配的内容. "\2"指代在第二个"\(
\)"中匹配的内容, 也就是"First"部分, "\1"则指第一个\( \)中的内容,即"Last"
部分.

:iabbrev ad advertisement
每次键入"ad"时都自动扩展为"advertisement",可以用":iab"代替完整的命令名":iabbrev"
:abbreviations 命令可以列出当前定义的所有缩写
:unabbreviate + 缩写词替换词
命令可以用于删除一个缩写,但输入之后它还会再做一次替换才会生效。:abclear有同样的效果。
:abbreviate errword rightword 可以更正错误的输入
CTRL-V
命令可以保证你键入的下一个字符被原封不动地被录入(如特殊字符),支持ASCII,十六进制(前面加o),八进制输入(前面加x),16bit或32bit的数字(前面加u)
通过输入连续的三个键"CTRL-K加两个字母"可以键入键盘上没有的字符,用:digraphs可以查看可用的连字符
========================================================================================
CRTL-G 显示正在编辑的文件的详细信息
CTRL-U 使文本向下滚动半屏
CTRL-D 使文本向上滚动半屏
CTRL-E 使文本向上滚动一行
CTRL-Y 使文本向下滚动一行
CTRL-F 使文本向后滚动一整屏(实际上是整屏去两行)
CTRL-B 使文本向前滚动一整屏
CTRL-O 跳转到更早些时间停置光标的位置(提示: O意为older).
CTRL-I 跳回到后来停置光标的更新的位置(提示:
I在键盘上位于O前面,作用同<Tab>键)
"CTRL-P" 对于重复的输入,按下"CTRL-P",
Vim会根据已经输入的部分向前寻找,补全整个词
"CTRL-N" 对于重复的输入,按下"CTRL-N",
Vim会根据已经输入的部分向后寻找,补全整个词
CTRL-X CTRL-F 文件名
CTRL-X CTRL-L 整行内容
CTRL-X CTRL-D 宏定义(也包括那些在include文件里定义的宏)
CTRL-X CTRL-I 当前文件和被当前文件include的文件
CTRL-X CTRL-K 来自一个字典文件的word
CTRL-X CTRL-T 来自一个thesaurus的word
CTRL-X CTRL-] tags
CTRL-X CTRL-V Vim的命令行
用`complete`选项来定制Vim在补全word时所用的策略,使用`ignorecase`选项,在搜索匹配的word时忽略大小写的不同。`infercase`.
它使搜索
匹配的word时忽略剩余部分的大小写。
在插入模式下,CTRL-Y会复制上一行的字母内容到当前行的光标处。
在插入模式下,CTRL-E会复制下一行的字母内容到当前行的光标处。
========================================================================================
简单模式搜索:(使用正则表达式)
^ 字符匹配一行的开头,如"/^word"只匹配出现在一行开头的word
$ 字符匹配一行的末尾,如"/word$"只匹配出现在一行末尾的word
注:"/^the$",只会匹配到一行的内容仅包含"the"的情况. 有空白字符也不行
.
匹配除换行符外的任何单字符,如"/wo.d","."可以用"\."来匹配,在normal模式下也可用来做重复的动作,

标记跳转:
m{mark}
将当前光标下的位置名之为标记"mark".从a到z一共可以使用26个自定义的mark.
定义后的标记不在屏幕上显示,只在Vim内部记录所代表的位置
`{mark} mark就是你定义的标记的名字,如用"ma"标记"a"处,用"`a"跳转到标记a处
` 进行此次跳转之前的起跳点
``
上次编辑该文件时光标最后停留的位置,跳回到上一个的出发点,可以在两点之间来回跳转
[ 最后一次修改的起始位置
] 最后一次修改的结束位置
:marks 列出已经标记过的标记列表
:jumps 列出曾经跳转过的位置列表
/string
用于向下搜索一个字符串,用"n"可以继续查找下一个,用"N"可以继续查找上一个
?string
用于向上搜索一个字符串,用"n"可以继续查找下一个,用"N"可以继续查找上一个
* 把光标定位于某个word上,对当前光标所在的word向下搜索
# 把光标定位于某个word上
/\<word\> 精确搜索单词word
查找一个文件:把光标置于所要查找的文件名上,然后键入"gf".当这个文件并不在工作目录下时,Vim会用在`path`选项中定义的目录去查找它.
该选项的内容是一个以逗号分隔的目录名列表,格式为::set
path+=c:/prog/include.
或通过:find filename来查找。
或通过":sfind"命令来替代":find"命令,在新窗口中打开。
========================================================================================
set nocompatible "设置默认模式为普通vim模式"
set backspace=indent,eol,start
"在Insert模式下退格键何时可以删除光标之前的字符.
选项中以逗号分隔的三项内容分别指定了Vim可以删除位于行首
的空格, 断行, 以及开始进入Insert模式之前的位置"
:set ignorecase 忽略大小写匹配
:set noignorecase 大小写的精确匹配
:set number 在每行的前面显示一个行号
:set nonumber 关闭行号显示
:set ruler 开启右下角的光标位置显示
:set noruler 关闭右下角的光标位置显示
:set hlsearch 高亮显示搜索结果
:set nohlsearch 关闭高亮显示搜索结果
:nohlsearch 去掉当前的高亮显示
:set incsearch 在键入目标字符串的过程中就同时开始搜索
:set wrapscan 搜索过程在文件内部循环进行(默认)
:set nowrapscan 搜索过程在文件内部只进行一次
set autoindent "在开始一个新行时对该行施以上一行的缩进方式."
set history=50 "设置冒号命令和搜索命令的命令历史列表的长度"
set ruler "总是在Vim窗口的右下角显示当前光标的行列信息"
set showcmd "在Vim窗口的右下角显示一个完整的命令已经完成的部分"
set incsearch "在键入要搜索的字串的同时就开始搜索当前已经键入的部分"
map Q gq "定义了一个"Q"命令映射到"gq"操作符命令,进入Ex模式"
filetype on "自动识别文件类型"
plugin on
"用文件类型plugin脚本,对某种文件类型来说最常用的选项可以放在一个Vim中叫文件类型plugin的脚本里.请参考|write-filetype-plain|"
indent on "使用缩进定义文件,请参考jfiletype-indent-onj和°indentexpr°选项"
"autocmd FileType text setlocal textwidth=78 "
autocmd FileType text "是一个自动命令.
它所定义的是每当文件类型被设置为"text"时就自动执行它后面的命令."
setlocal textwidth=78
"在当前行已超过78个字符时,让Vim可以自动断行,这种设置只对当前的一个文件有效."
:options "打开选项帮助窗口"
:help `wrap` "获得选项关键字的详细解释"
:set iskeyword& "恢复一个选项值的默认设置"
:set nowrap "控制长行是否折到下一行显示的命令是"
:set sidescroll=10 "查看左右10个字符的上下文"
:set whichwrap=b,s
"控制移动光标移动到行首或行尾时的操作,光标位于行首时按退格键会往回移动到上一行的行尾.
同时在行尾按空格键也会移动到下 一行的行首"
:set whichwrap=b,s,<,> "左右箭头键在遇到行的边界时可以转行,在normal模式下"
:set whichwrap=b,s,<,>,[,]
"左右箭头键在遇到行的边界时可以转行,在Insert模式下"
:set list "设置制表符成为可见的字符"
:set listchars=tab:>-,trail:- "使制表符以">---"显示, 同时行尾空格以"-"显示"
:set iskeyword
iskeyword=@,48-57,_,192-255 >
"定义了一个word中可以包含哪些字符,"@"在这里代指所有的字母.
"48-57"指ASCII码从48到57的那些字符, 即0到9.
"192-255"是可打印拉丁字母,要去除一个字符使用操作符"-=",要添加一个字符使用操作符"+=""
:syntax enable "打开色彩"
:set background="/dark" "设置背景颜色为暗色(或light亮色)"
:colorscheme evening
"选择颜色方案(evening),其他颜色方案在$VIMRUNTIME/colors目录中"
:source $VIMRUNTIME/syntax/2html.vim "把当前文件转到HTML格式"
:set autowrite "每当需要时就自动保存,不需要过问"
:set noautowrite "每当需要保存时,就过问"
:set backup "生成备份文件"
:set backupext=.bak "重新命名备份文件的后缀为.bak" 备注:
如果°backup°选项是关闭的但°writebackup°选项是打开的,
Vim还会生成一个备份文件. 但是, 一旦该文件被成功地保存它就会被自动删除.
:set patchmode=.orig "对原始文件进行备份"
:set backupext=.old "指定对原始文件进行备份的后缀"
:write >> logfile "把当前文件的内容追加到logfile文件中"
:set fileformats=unix,dos "Vim能自动识别的格式的集合"
:set fileformat? "查看当前的文件格式,在vim中有三种格式,分别是:unix
<LF>;dos <CR><LF>和mac <CR>"
:edit ++fileformat=unix|dos|mac file.txt
"强制指定文件file.txt的格式为unix,dos或mac,++fileformat可荐絬为++ff"
把一个dos格式的文件转换成unix格式可以通过以下两步完成:
:set fileformat=unix
:write
:set showmatch
"键入"闭括号"时显示它与前面的哪个"开括号"匹配,对于大,中,小括号都适用"
:set matchtime=15
"设置键入某个闭括号时,等待时间的长短,时间单位是十分之一秒"
:set textwidth=30
限制每一行能有多少个字符。注:`wrap`选项使Vim能显示需要折行的过长的行,
但只是为了显示的需要, 并不在文件中实际插入一个换行符
:set autoindent "自动插入缩进"
>> "增加一行的缩进量"
<< "减少一行的缩进量"
:set shiftwidth=4
"设置缩进量增减的单位,但会得到一个8字符的缩进,可以通过:set
softtabstop=4来控制缩进"
:set tabstop=3 "设置制表符的字符长度"
:retab 8 "重置制表符的长度为8"

========================================================================================
多文本编辑:
:edit otherfilename "编辑另一个文件,但需要事先保存原文件"
:hide edit otherfilename "编辑另一个文件,不需要事先保存原文件"
vim one.c two.c three.c
"启动时就指定要编辑的多个文件,使用next,next!或wnext转到下一个文件,使用pervious或wpervious转到上一个文件,使用
last转到最后一个文件,使用first转到第一个文件使用args可以查看正在编辑的文件名"
:args 1.c 2.h 3.h "重新定义编辑的文件列表"
CTRL-^ "跳转到刚刚编辑过的文件"
`" "返回上次离开该文件时光标所在的位置"
`. "返回最后一次对文件做出改动处"
vim -R file 以只读方式打开文件,同"view file",但可以使用!强制执行。vim -
:saveas "把现有的文件另存为一个新文件"
:winheight "设置一个期望的最小的窗口高度. "
:winminheight "设置一个强制的最小高度"
:winwidth "指定期望的最小窗口宽度"
:winminwidth "强制的最小窗口宽度."
:equalalways
"在每次打开或关闭窗口Vim都自动让所有窗口均摊屏幕上可用的高度和宽度."
:split "分割一个窗口为两个,可以通过split
newfile在新窗口中打开newfile,可以使用CTRL-W来切换当前窗口,使用CTRL-w
+或-来改变窗口的大小,使用:close来关闭窗口,使用:only可以关闭除当前窗口外的其他窗口"
:new "打开一个新窗口并开始编辑一个新的缓冲区"
:vsplit "创建新窗口位于当前窗口的左边"
:vnew "用于垂直分隔窗口并在其中打开一个新的空缓冲区"
:set scrollbind "设置多窗口同步滚动"
:set noscrollbind "取消多窗口同步滚动"

CTRL-W j "切换窗口到下面的窗口"
CTRL-W k "切换窗口到上面的窗口"
CTRL-W h "切换窗口到左边的窗口"
CTRL-W l "切换窗口到右边的窗口"
CTRL-W t "切换窗口到顶部窗口"
CTRL-W b "切换窗口到底部窗口"

CTRL-W K "向上移动窗口"
CTRL-W J "向下移动窗口"
CTRL-W H "向左移动窗口"
CTRL-W L "向右移动窗口"

:qall "退出所有窗口"
:wall "保存所有窗口"
:wqall "保存并退出所有窗口"
:qall! "强制退出所有窗口"

vim -o(小) filename1,2,3... "为每个文件打开一个窗口,水平排列"
vim -o(大) filename1,2,3... "为每个文件打开一个窗口,竖直排列"
vimdiff filename1 filename2 ... "显示文件间的不同之处"
zo "展开层叠显示"
zc "收起层叠显示"
]c "直接向前定位到下一个不同之处"
[c "直接向后定位到下一个不同之处"
:diffupdate "重新比较两个文件"
========================================================================================
四、 visual 模式 (按"v"可以进入Visual模式)
CTRL-V 对矩形的文本块为对象进行操作
o (小)让光标置于被选中文本的对角,如果时单独一列,就是上下移动。提示: o
代表other end另一头)
O (大)让光标在同一行的左右两个角之间移动
p
(小)把放入缓存的内容放到当前光标后面(提示:p即put).3p,可以把三分放入当前光标后。
P (大)把放入缓存的内容放到当前光标前面.
y
(小)把文本复制到一个寄存器中,该寄存器为vim私有的。该命令是一个操作符命令,如:"yy"复制一整行,"y2w"复制两个word,包括后面的空白字符,"ye"复制一个word,不包括后面的空白字符,"y$"复制当前光标至行尾.
Y (大)复制一整行。
c (小)

========================================================================================
五、 replace模式(大写的"R"可以进入替换模式):
replace模式下的例外是按下回车键并不会把当前字符替换为回车, 而是插入一个回车
小节:
x 删除当前光标下的字符("dl"的快捷命令)
X 删除当前光标之前的字符("dh"的快捷命令)
D 删除自当前光标至行尾的内容("d$"的快捷命令)
dw 删除自当前光标至下一个word的开头
db 删除自当前光标至前一个word的开始
diw 删除当前光标所在的word(不包括空白字符)
daw 删除当前光标所在的word(包括空白字符)
dG 删除当前行至文件尾的内容
dgg 删除当前行至文件头的内容 (用"c"命令代替"d"这些命令就都变成更改命令)

~ 改变当前光标下字符的大小写, 并将光标移至下一个字符.
这不是一个操作符命令(除非你设置了°tildeop° 3选项),
所以你不能让它与一个位移命令搭配使用.
但它可以在Visual模式下改变所有被选中的文本的大小写.
I 将光标置于当前行第一个非空白字符处并进入Insert模式
A 当光标置于当前行尾并进入Insert模式
六、 其他东东
:edit . "编辑当前的目录,可用的选项有:
" <enter> : 打开一个文件或目录~
" o : 为文件或目录打开一个新的窗口~
" O : 在前一个被访问过的窗口中打开指定的文件/目录
" p : 预览文件/目录~
" i : 切换大小/日期的列表显示~
" s : 选择一个排序键r : 逆向排序~
" - : 进入父目录c : 进入目录
" R : 文件重命名D : 删除文件
" :help help-explorer得到更多信息~
<Enter> 使用当前的窗口
o 打开一个新窗口
O 使用最近使用过的其它窗口[[译: 如果只有当前窗口就打开新窗口]]
p 同O, 但同时还将光标定位于该窗口中
参考|preview-window|
i 切换显示文件的大小和日期/时间信息
s 光标所在的条目作为排序键进行排序. 首先用i命令打开
对文件大小和日期的显示. 然后将光标移到任一文件的大小
上按下s. 此时所有的文件都将按其大小进行排序. 光标置
于日期上时按s则会按其日期进行排序.
r 逆向排序当前的排序列表(either size or date)
c 将当前目录切换到当前光标所在的目录名. 接下来使用":edit"
命令时就无需附加路径名了
R 更改当前光标下的文件, Vim会提示你输入一个新的文件名[[译:
不支持目录更名]].
D 删除当前光标下的文件名. Vim也会提示你进行确认[[译: 不支持目录的删除]].
关于编程常用快捷键:
[ [ = 移动到前一个行首的'{'字符上, 等价于?^{
] ] = 移动到下一个行首的'{'字符上, 等价于/^{
[ ] = 移动到前一个行首的'}'字符上, 等价于?^}
] [ = 移动到下一个行首的'}'字符上, 等价于?^}
{ = 到前一个空行上
} = 到下一个空行上
gd = 到当前局部变量的定义处(当前的意思是光标停留其上的单词).
* = 到与当前单词相同的下一个单词上
# = 到与当前单词相同的上一个单词上
'' = 到上次光标停靠的行
ctags:
[/home/someuser/src]$ ctags * "以源程序目录下所有文件作为参数"
[/home/someuser/src]$ vi -t foo_bar
"在命令行上启动vi程序时通过-t选项加要跳转的程序元素名"
灾难恢复
vim -r
"Vim会读取交换文件(这正是存放你已编辑的文件的地方)以及你的原文件的一些信息."
|swap-file| "关于交换文件的位置和命名"
|preserve| "手工刷新交换文件"
|swapname| "查看原文件及其交换文件的名字"
`updatecount` "连续击键多少次后做一次同步"
`updatetime` "多长时间之后做一次同步"
`swapsync` "同步交换文件时是否同时做一次磁盘同步"
`directory` "列出存放交换文件的目录"
`maxmem` "尚未写入交换文件的内容所受的内存限制"
`maxmemtot` "同上, 但是针对所有文件."
========================================================================================
注意"o"和"O"在Visual模式与Normal模式下行为迥异, 在Normal模
式下它们是在当前行的下面或上面插入一个新行.
========================================================================================注:汉字的空格不被视为空白字符
要改变Vim对word边界的定义, 请查看°iskeyword°选项
用%处理哪些括号可以由`matchpairs`选项来定义与滚屏相关的命令, 请参考jQ
scj.若要一直保持当前行的前后都有一些内容显示在屏幕上,
请参考`scrolloff`选项.
问题:在使用*键时,但如果要匹配一小片包含了几个word的文本呢?如何避免手工键入?
答案: Visual select, yank, :let @/=@", n
在使用:set hlsearch时,如果排除函数外别处同名变量的干扰呢? 答: j/\%<3lj
限定
========================================================================================添加一个plugin
plugin是一个Vim会自动载入执行的脚本.
把一个脚本放入你的plugin目录即可。分为:全局的plugin,和文件类型plugin
全局的plugin:
在|standard-plugin-list|有一个此类plugin 的列表.
另外请参考|load-plugins|.在$VIMRUNTIME/macros下的脚本是全局的,且必需以".vim"为扩展名
文件类型plugin:
Vim的发布版中已经包括了针对不同文件类型的相应plugin, 你可以使用":filetype
plugin
on"命令开启对它的应用.在$VIMRUNTIME/ftplugin目录下的则是专用于特定文件类型的
一些帮助:
|filetype-plugins| 关于文件类型plugin的文档以及如何避免映射引起冲突的信息
|load-plugins| 关于Vim启动过程中何时载入全局plugin
|ftplugin-overrule| 如何强制改变全局plugin中的设置.
|write-plugin| 如何写一个plugin脚本.
|plugin-details| 关于如何使用plugin或者解决你的plugin出现的bug.
|new-filetype| 如何检测新文件类型
========================================================================================常用选项:
vnoremap p <Esc>:let current_reg = @"<CR>gvs<C-R>=current_reg<CR><Esc>
"让"p"可以在Visual模式下以此前yank的内容替换当前选择的文本块"
if has("vms")
set nobackup
else
set backup
endif 在覆盖一个文件之前备份该文件. 但是对VMS系统除外,
因为该系统已经为文件保存了老的版本. 备份文件名由当前文件名
加后辍"~"组成. 请参考|07.4|

if &t_Co > 2 || has("gui_running")
syntax on
set hlsearch
endif 打开语法高亮功能, 前提是当前系统支持彩色显示.
`hlsearch`告
诉Vim高亮显示所有与最后一次搜索目标串相匹配的文本

autocmd BufReadPost *
\ if line("°\"") > 0 && line("°\"") <= line("$") |
\ exe "normal g`\"" |
\ endif 检查是否定义了标记"2,
如果定义了就跳转到这个位置去.
每一行前面的反斜杠表示该行是前一行命令的延续. 它可以避免
脚本中有些行变得过长

深度理解 extern "C"

1.引言
  C++语言的创建初衷是"a better
C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言,C++保留了一部分过程式语言的特点(被世人称为"不彻底地面向对象"),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。
2.从标准头文件说起
某企业曾经给出如下的一道面试题:为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {

你的C/C++基本功是否扎实?

我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。
  分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。
1.找错题
  试题1:
void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}
  试题2:
void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1 = 'a';
 }
 strcpy( string, str1 );
}
  试题3:
void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}
  解答:
  试题1字符串str1需要11个字节才能存放下(包括末尾的'\0'),而string只有10个字节的空间,strcpy会导致数组越界;
  对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,
str1)调用使得从str1[url=]内存[/url]起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;
  对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) <
10),因为strlen的结果未统计'\0'所占用的1个字节。
  剖析:
  考查对基本功的掌握:
  (1)字符串以'\0'结尾;
  (2)对数组越界把握的敏感度;
  (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:
2. 编写一个标准strcpy函数
2分
void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != '\0' );
}
4分
void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2分
{
  while( (*strDest++ = * strSrc++) != '\0' );
} 
7分
void strcpy(char *strDest, const char *strSrc)
{
 //对源地址和目的地址加非0断言,加3分
 assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != '\0' );
}
10分
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != '\0' );
  return address;
}
  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!
  (4)对strlen的掌握,它没有包括字符串末尾的'\0'。
  读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:
int strlen( const char *str ) //输入参数const
{
 assert( strt != NULL ); //断言字符串地址非0
 int len;
 while( (*str++) != '\0' )
 {
  len++;
 }
 return len;
}
试题4:
void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}
void Test( void )
{
 char *str = NULL;
 GetMemory( str );
 strcpy( str, "hello world" );
 printf( str );
}
试题5:
char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}
void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}
试题6:
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}
void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}
试题7:
void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它语句
}
  解答:
  试题4传入中GetMemory( char *p
)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = NULL;
GetMemory( str );
  后的str仍然为NULL;
  试题5中
char p[] = "hello world";
return p;
  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
  试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
  后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
 ...//进行申请内存失败处理
}
  试题7存在与试题6同样的问题,在执行
char *str = (char *) malloc(100);
  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个"野"指针,应加上:
str = NULL;
  试题6的Test函数中也未对malloc的内存进行释放。
  剖析:
  试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。
  对内存操作的考查主要集中在:
  (1)指针的理解;
  (2)变量的生存期及作用范围;
  (3)良好的动态内存申请和释放习惯。
  再看看下面的一段程序有什么错误:
swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}
  在swap函数中,p是一个"野"指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误"Access
Violation"。该程序应该改为:
swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}
3.内功题
  试题1:分别给出BOOL,int,float,指针变量与"零值"比较的 if
语句(假设变量名为var)
  解答:
   BOOL型变量:if(!var)
   int型变量: if(var==0)
   float型变量:
   const float EPSINON = 0.00001;
   if ((x >= - EPSINON) && (x <= EPSINON)
   指针变量:  if(var==NULL)
  剖析:
  考查对0值判断的"内功",BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。
 一般的,如果想让if判断一个变量的"真"、"假",应直接使用if(var)、if(!var),表明其为"逻辑"判断;如果用if判断一个数值型变量(short、int、long等),应该用if(var==0),表明是与0进行"数值"上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。
  浮点型变量并不精确,所以不可将float变量用"=="或"!="与数字比较,应该设法转化成">="或"<="形式。如果写成if
(x == 0.0),则判为错,得0分。
  试题2:以下为Windows NT下的32位C++程序,请计算sizeof的值
void Func ( char str[100] )
{
 sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
  解答:
sizeof( str ) = 4
sizeof ( p ) = 4
  剖析:
  Func ( char str[100]
)函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。
  数组名的本质如下:
  (1)数组名指代一种数据结构,这种数据结构就是数组;
  例如:
char str[10];
cout << sizeof(str) << endl;
  输出结果为10,str指代数据结构char[10]。
  (2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;
char str[10];
str++; //编译出错,提示str不是左值 
  (3)数组名作为函数形参时,沦为普通指针。
  Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof(
str ) 、sizeof ( p ) 都为4。
  试题3:写一个"标准"宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?
least = MIN(*p++, b);
  解答:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
  MIN(*p++, b)会产生宏的副作用
  剖析:
  这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的"参数"也不是真的参数,在宏展开的时候对"参数"进行的是一对一的替换。
  程序员对宏定义的使用要非常小心,特别要注意两个问题:
  (1)谨慎地将宏定义中的"参数"和整个宏用用括弧括起来。所以,严格地讲,下述解答:
#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )
  都应判0分;
  (2)防止宏的副作用。
  宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++,
b)的作用结果是:
((*p++) <= (b) ? (*p++) : (*p++))
  这个表达式会产生副作用,指针p会作三次++自增操作。
  除此之外,另一个应该判0分的解答是:
#define MIN(A,B) ((A) <= (B) ? (A) : (B));
  这个解答在宏定义的后面加";",显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。
补充:
#include <filename.h> 和 #include "filename.h" 有什么区别?
答:对于#include <filename.h> ,编译器从标准库路径开始搜索 filename.h
对于#include "filename.h" ,编译器从用户的工作路径开始搜索 filename.h
  试题4:为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {

豹豹:由基金排行榜及沪深300指数所想到的(二)

三、市场先生愚蠢乎?
巴老的确不相信"市场永远有效"这种提法,但他也总是小心翼翼的等待最佳击球机会,他剔除掉了投资决策的主观性和感性因素,让"价格-价值缺口"、"价格/价值方程"来代替他决策。他认为,如果随随便便的击球,投资业绩注定不理想。为了等待一次有把握的机会,他甚至长期关注几十年才介入,这种理性和耐心,也注定不大可能再出现"下一个巴菲特"。
可是,行为金融学的兴起,倒让很多"价值投资者"自负起来了,甚至认为"市场先生经常很愚蠢",经常嘲笑市场先生。行为金融学上有一条推论:
前提:投资人是不理性的
公理:市场是无数投资人的加总
结论:因此,市场是不理性的
这种逻辑似乎很常见,但是,这恰恰是行为金融学的一个bug,市场是一个非线性的系统,不是简单的线性加总,无数投资人是不理性的,市场上存在噪音交易,而市场的多样性、互动作用起来,市场总体而言,仍有可能是很理性的、很有效率的。
我认为,真正的价值投资者,恰恰要高度重视市场先生,缜密的审视自己的投资过程,试图先将自己驳倒,先自己去"证伪",从多个角度找出自己投资分析上的漏洞,而不要轻言"市场是愚蠢的"、"市场定价错了"。
在一个复杂的适应性系统里面,会有很多悖论,如我们中学时代历史教科书上批判的"美国的西进运动",英国的"圈地运动"乃至中国隋朝的大运河,这是典型的"动机与实际情形背离",就历史的当局者而言,结局是悲惨的,而就人类长久而言,也有大功。再比如,经济学上的合成谬误、囚徒困境,也验证了非合作博弈中的"个体理性、群体非理性"。在一个多样性的、互动的世界里,静态的、线性的结论往往是很轻率的。
这个世界远不是我们想象的那么简单,也不会是太简单的逻辑。同样,市场多数时候往往是很聪明的。很多轻言市场愚蠢的投资人,往往付出了惨重的代价。当然了,这里也不是说"市场永远正确",更不是主张要搞趋势投资。这里只是讨论一种逻辑思维方式。
四、向指数学习什么?
比尔·米勒过去多年击败指数,他经常琢磨S&P500的结构及成分增减。普通基金很难战胜指数,包括我们个人投资,在单边上涨市里面,也容易败给指数。
其实呢,指数有几个典型的特征:1、代表性强
里面的成分股,多是各行业的绩优龙头股,代表性强;2、汰弱留强
指数不会因为某只股票表现好而删减它的份额,而是增加权重不足行业的股票;
3、低周转率 当然,指数是一个满仓的概念; 4、流动性好
主动投资型基金,则容易反其道而行之,认为自己能找到表现更好的股票,过度自信,周转率高,而且受人性法则及市值法则左右,股价表现过好时,往往会卖出,而烂股票则容易捂着。很多个人投资者也每每是高周转、高换手率,在保留股票方面,容易将表现好的股票卖了而保留令人失望的烂股票。
要战胜市场,最关键的就是3条:
1、恪守安全边际的法则,坚持"价值"投资
"低风险、高收益的机会,才称得上是机会";这是战胜市场的最关键。"有效的抑制亏损",是压倒一切的战略任务。
最重要的是购买"价格-价值缺口"大的廉价资产组合,而不是不管低估没有,去买一堆公认的"好股票"。
2、精选个股,坚持"集中"投资
一定要坚持相对的集中投资,在"价格-价值缺口"大、公司基本面坚实、自己最了解、风险最小的股票上,重仓出击;
3、低换手率,杜绝过度交易及波段操作,坚持长期投资
这里的"长期",只是相对的概念,价值实现及价值成长均是要时间的,像短短几天、几周时间就换股,肯定不是严肃的态度,当然了,也并不是说一定要超长期投资,这里重点是强调一种良好的交易习惯及面对市场价格波动的良好态度。对于基本面坚实、估值合理、且能持续成长的股票,是应该坚持长捂不放的。
事实上,多数人在09年想战胜沪深300指数,就有些困难,不过下半年我认为不大可能再有目前的表现了。
五、多多关注投资过程
算到现在,来到市场也2年了,一来就赶上个牛尾巴,撞上了大熊。不过,综合起来看,08、09年某些方面跟自己比还是有些许进步,具体的实证组合的performance如下:
08年 09年
mine -10.1 90
沪深300指数 -47.6 87.0
注:08年取的是加权平均的点位
由于是小资金的实证组合,可以坚持"集中投资",2年下来,居然都战胜了沪深300,但是08年仍然是亏损的,有些分析事后看比较草率。09年也只是微弱的优势战胜了沪深300。个人投资呢,其实压力比较小,而且没有仓位的限制,偶尔取得好一点的成绩并不难,甚至可以说只要坚持理性投资,个人投资组合要战胜大部分基金经理还是比较容易的。
其实这些基金经理也并不容易,在一个规则很复杂、限制较多又受短期压力制约的投资世界里,要管理大资金并取得好的成绩、坚持理性投资,真的不容易,一个在基金的兄弟也常跟我说"你不要将基金经理想象的得太简单了,哪一天你自己坐在这个位置上,你会发现不好做,要打败市场真的很难"。这真的是实情,在一个复杂的环境里管理一个受限制的大资金,并不容易。
现在值得考虑的是"投资过程",而不是目前的一点performance,很多垃圾股其实涨幅更大,这又是一轮"猪都被吹到天上跑"的行情,很多人说"撑死胆大的",这种情形,恰恰值得警惕,不要轻易的认为自己分析严谨,很可能是市场行情好、运气好造成的"偶然成功"而已,尽管从目前来看检验投资组合,我认为估值仍比较安全,承担的风险并不大,但是,现在要紧的是关注投资过程而不是短期结果。没有高质量的投资过程的话,只要重复的投资下去,是注定不可能有好的成绩的。
当然了,仅仅强调以沪深300为benchmark并不够,重要的是"不要亏损+持续战胜沪深300",要充分认识到复利的艰难、长期投资的艰难及市场先生的强大和聪慧,严密的检查投资过程的严谨性,用决策树分析模式再详细审核关键的投资思路的漏洞,多关注"价格-价值缺口"的估算的严谨性。多多关注投资过程,我们要的是长期的、必然的投资成功而不是基于运气和冒险、取巧的一时成功。
豹豹于2009年7月12日中午

豹豹:由基金排行榜及沪深300指数所想到的(一)

08年A股市场的"吃人"行情让不少老手也是目瞪口呆,当然了,迄今近9个月来的"吃肉"行情又让不少人赚得笑逐颜开的。就投资经历而言,应该说过去这几年的投资经历是我们一生投资生涯中难得的一课,也是一次极好的学习机会。深入总结牛熊转换的一些投资规律,对于我们以后更好的做好投资,是非常重要的。
"熊市不亏/微亏/少亏+牛市/上涨市大赚",这是战胜市场的一个公式。努力追求绝对回报绝对没有错,但我认为,还得有一个benchmark,比如说:盈利30%好还是不好呢?这取决于环境,如果是大牛市,这个成绩可能很臭;反之,如果是极差的环境之中,这个成绩可能很惊艳。比较好的业绩基准,就是沪深300指数,它汇集了沪深两市的精华。
这次反弹以来,走出了不少表现惊艳的基金,如公募中的一些指数基金,典型的如易方达深证100ETF(159901)、融通深证100ETF(161604),偏股型基金如中邮核心优选(590001)、华夏复兴(000031);私募信托中,更有几只产品在09年的收益率达到了100%以上。
沪深300指数09年迄今的收益率是87%,全部公募基金中,能达此成绩以上的只有3只:易方达深证100ETF(159901)、中邮核心优选(590001)、华夏复兴(000031);私募信托产品,不完全统计也有3、4只的样子。在普涨的行情中,要战胜沪深300指数,的确很难很难。
如果将时间推进到2008年,将这一两年的表现串起来看,结论又有所不同,能有稳定表现的基金相当少,如果扣住"熊市少亏+牛市平均成绩"这2条标准同时符合的话,无论是公募还是私募,能做得到的基金都相当少。
不说易方达深证100ETF(159901),这是典型的大起大落型的指数基金。拿今年以来相当惊艳的中邮核心优选(590001)来看,其实检验一下完整的投资脉络,今年的惊艳并不是什么值得开心的事情。我们可以将08、09年的表现串起来看:
08年 09年
中邮核心优选(590001) -61.6 91.7
沪深300指数 -66.0 87.0
这只基金表现做到了"上涨市大赚",但并没有做得到"熊市不亏、微亏、少亏",我们知道重大的亏损对长期复利的损害是极大的。
公募基金中,真正值得注意的是华夏复兴股票(000031),将08、09年的表现串起来看:
08年 09年
华夏复兴股票(000031) -38.4 87.8
沪深300指数 -66.0 87.0
这只基金在08年亏损38.4%,尽管算不上很好,但在公募基金中很难得,而09年的表现则相当不错。这2年来的综合表现是相当优秀的。有意思的是,08年公募基金中的冠军泰达荷银成长(166201)在08年的收益率是-32.3%,是表现最好的股票型基金,但在09年的收益率只有31%,落后于沪深300不少。公募基金极少有表现稳定的,可谓"各领风骚两三年"而已。
私募信托中,09年的反弹明星,其实呢,问题也比较严重。比如说景良能量、新价值2,这2只信托均是08年成立的,单看09年的表现,相当惊人,均达到了100%以上,但是检验一下08年的表现,发现问题比较严重,2者的净值,一度达到了0.4-0.5元,亏损近半。最终算下来,这2只反弹明星的信托,1年多下来,也才赚得20%的绝对回报。
私募信托中,表现出色的当属从容投资的吕俊先生,拿他的从容优势1来看:
08年 09年
从容优势1 -4.2 55.2
沪深300指数 -55.3 87.0
(注:这里假如这只信托未在后来接收过资金,因此起点值只计算信托成立当日的沪深300指数)
吕俊先生在08年的表现相当惊人,亏损才4.2%,远远少于同期指数,今年虽然略逊于沪深300,但总体而言,远远战胜了沪深300。同样,武当投资的田荣华先生、星石投资的江晖先生也是表现出色。其实呢,"抑制重大亏损"这一条远比牛市里面多赚几十个点要重要得多、可贵得多。
一两年的净值表现还不足以说明全部问题,这里只是有感于媒体的喧嚣,说什么"反弹冠军"、"09年冠军",其实"连续的、稳定的表现"才是最重要的。
回首这次牛熊转换,有不少值得我们深入反思的问题:
一、价值投资"知易"乎?
经常听到的一种说法是"价值投资'知易'行难",价值投资真的是"知易"乎?现在很多人都标榜自己是"价值投资者"。像前几年"买入并持有"、"买入伟大公司"均被解读为价值投资,甚至被解读为价值投资的全部。很多人还说很多伟大公司的股价能涨了上千倍,可是,这种提法明显有两个隐蔽前提:1)假定自己目光如炬一定能看清未来,绝对能认定这些公司是能涨上很多倍的伟大公司,因此,无论是多高的价格买入都能赚;2)伟大公司在漫长的岁月长河中、在众多的公司中,尽管是小概率事件,而自己聪慧无比,一定能将小概率的事情找出来。
事实上,"伟大公司"事后很多年才能看得清,事前、事中的判断是很复杂的、难度很大的。看对的概率大,还是看错了的概率大?看错了怎么办呢?能不作保守估计吗?
巴老反复强调的"用40美分买1美元"、"不要亏损"、格老所强调的"全面的、严谨的分析"、"本金的安全"、"满意的回报",这些提法倒被人忽略了,卡拉曼更是一针见血的指出"一个投资人,不可能仅凭阅读一两本书就成为合格的价值投资者"。而"涨上千倍"、"伟大公司"、"投资很简单"的提法则多少反映了社会的浮躁。
我倒更相信两点:1、好的投资者,追求真理胜于追求财富本身,投资就是他们的生命,他们是基于对投资的热爱而非对财富的憧憬而喜欢投资的。追求真理是第1位的,财富、名利只是"追求真理"的副产品;2、好的投资人,是保守的投资人,他们宁愿放弃伟大的成功机会,也不会去犯致命的错误。他们的心态是超然的,更不会有狂热的想法和浪漫的幻想。他们深知市场可能犯错误,而自己可能更愚蠢。
我有一个武断的判断:价值投资是"知难行易"。真正"知"的人,行动起来其实并不难;行动起来经常出错的人,大多是自以为"知"其实并不知。
二、再谈期望值准则、概率思维与安全边际
投资是一个典型的玩概率的领域,在投资世界里,最确定的事情就是"不确定性",幻想找到物理学、工程学那样的确定性再去决策,那是不可能的。概率思维、决策树分析模式,是最起码的思维能力。
可是,这样的思维能力,很多自称是"价值投资者"的人显得很稀缺,包括宏观经济形势、需求状况、产业竞争乃至公司的产量、销量、价格、成本、现金流等很多问题,事实有多种概率,如:至少可以分成"繁荣"、"一般"、"萧条"等情况,分别进行估算。但很多人自称是"死多头"、"死空头",完全是一根筋的思考问题,看多时看得死多,完全不考虑那几个变量如果作悲观的估计会如何、预期落空了会怎么办;死空头则一根筋的看跌。
很多人只看到了巴菲特长期持有有些公司,而不去分析深层次的原因。巴老经常打桥牌来增强自己的概率感、巴老主管保险公司进行大量的概率估计,包括巴老回顾买入富国银行时,作了几种概率分析及最糟糕时的概率分析,这种概率思维的训练则没有多少人提。
在网络股时代,巴老诚实的承认"一家公司的内在价值如果在2-200亿美元的话,我完全不知道它到底是2亿美元,还是200亿美元",巴老在抛完中石油之后坦率的承认"油价在75美元每桶时,我比较中性了,尽管不是说它一定会跌",相信很多"价值投资者"们如果面对"2-200亿美元"的情况,在40亿美元乃至100亿美元市值时大多会选择买入而不是逆向思维一下"错了怎么办"。
投资世界是整个世界的一部分,投资决策是全部决策的一部分。我们并不能看清未来,更遑论"自己一定能看清未来",保持对世界、对人生的谦卑,预留误判的空间,是很有必要的。凡事只作最乐观的估计,而不去权衡各种可能性和概率,不权衡期望值,放在任何领域都不能成功,更别说在投资这个高度竞争、高度有效的市场领域之内。
记得赵丹阳先生曾提过一种提法"低风险、高收益的机会,才叫机会",这可谓抓住了投资的精髓。所谓的安全边际,其实呢,就是保证:
向上的空间大、概率大
向下的空间小、概率小
安全边际的精髓,就是保证"正期望"决策,立于不败之地,仅此而已。在一个高度依赖于概率的领域,没有这种思维能力,是很可怕的,不管在口头上标榜自己是怎样的"价值投资者"。我武断的认为:不具备概率思维、决策树分析能力的投资人,也不可能是真正的价值投资者,也难以取得长期的投资成功。
丢掉了安全边际,也就丢掉了价值投资的灵魂,正期望决策就荡然无存,就长期而言,投资迟早演化成而必败。