在Vista之后,debug信息可以用DbgPrintEx或KdPrintEx有条件地输出。(之前的2003 server或xp等,则是无条件输出,需要自己封装,设定debug信息级别)
DbgPrintEx在WinDBG中的信息级别按照如下方式定义:
If Level is equal to a number between 0 and 31, inclusive, it is
interpreted as a bit shift. The importance bit field is set to the value
1 << Level. Thus choosing a value between 0 and 31 for Level
results in a bit field with exactly one bit set. If Level is 0, the bit
field is equivalent to 0x00000001;if Level is 31, the bit field is
equivalent to 0x80000000.
If Level is a number between 32 and 0xFFFFFFFF inclusive, the
importance bit field is set to the value of Level itself.
而常用的Level则有:
#define DPFLTR_ERROR_LEVEL 0
#define DPFLTR_WARNING_LEVEL 1
#define DPFLTR_TRACE_LEVEL 2
#define DPFLTR_INFO_LEVEL 3
#define DPFLTR_MASK 0x8000000
在WinDBG中可以动态修改Debug信息的输出级别,方式如下:
kd> ed Kd_IHVVIDEO_Mask 0x8
即在WinDBG的命令模式下设置Kd_XXX_Mask,如上条命令中IHVVIDEO表示设置显卡driver的mask。
注意这里设定的mask还需要ORed WIN2000 system-wide mask(0x1)。
Debug信息的过滤方式:
1> 如果level小于等于31,判断(1<<level & Kd_IHVVIDEO_Mask)是否为0,不为0则输出
2> 如果level大于31,则直接判断(level & Kd_IHVVIDEO_Mask),从而决定是否输出
BTW:在WinDBG v6.6中似乎不行,但WinDBG v6.7中该方法可行
摘要: 1. More on List a) Functional Programming Tools: filter(function, sequence): returns a sequence consisting of those items from the sequence for which function(item) is true.如果sequence是string或tuple,则fi...
阅读全文
[Src: Python 2.5 Document]
1. if-statement
与C/C++不同的是,Python中 if 或 elif 要以 : 结尾

Code
>>> x = int(raw_input("Please enter an integer: "))
>>> if x < 0:
x = 0
print 'Negative changed to zero'
elif x == 0:
print 'Zero'
elif x == 1:
print 'Single'
else:
print 'More'

2. for-statement
iterates over the items of any sequence(a list or a string)

Code
>>> # Measure some strings:
a = ['cat', 'window', 'defenestrate']
>>> for x in a:
print x, len(x)
cat 3
window 6
defenestrate 12
若要修改序列中的内容,就只能在序列的副本上遍历。这里只能修改list的内容

Code
>>> for x in a[:]: # make a slice copy of the entire list
if len(x) > 6: a.insert(0, x)
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
3. range()
a) range(10) ==> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b) range(5, 10) ==> [5, 6, 7, 8, 9]
c) range(-10, -100, -30) ==> [-10, -40, -70]
4. else clause
Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.
即,当循环正常结束后,才会走到else语句中;如果循环被break掉,则跳过else

Code
>>> for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print n, 'equals', x, '*', n/x
break
else:
# loop fell through without finding a factor
print n, 'is a prime number'
5. pass-statement
空语句,语法要求
6. Defining functions
def func_name(parameter1, parameter2,...)
函数参数的解析顺序:local symbol table -> global symbol table -> built-in symbol table
通常情况下只能在函数中访问global的变量,但无法修改其值。除非用global显式声明
a) Default Argument Values
从左到右的顺序,如果某个参数设有默认值,则其后的所有参数都必须设有默认值,与C++类似

Code
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
while True:
ok = raw_input(prompt)
if ok in ('y', 'ye', 'yes'): return True
if ok in ('n', 'no', 'nop', 'nope'): return False
retries = retries - 1
if retries < 0: raise IOError, 'refusenik user'
print complaint
Default Value只会被赋值一次,因此可以对同一个函数,后续的调用会使用到前次调用的结果

Code
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
# result
[1]
[1, 2]
[1, 2, 3]
消除此种影响的方法:

Code
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
b) Keyword Arguments
允许以 "keyword = argument" 的方式传参。此时,传参的顺序不必遵守定义的顺序。No argument may receive a value more than once
注意:如果未以这种方式传参,则按照从左到右顺序赋值。一旦某个参数以keyword方式传参,则其后所有参数也必须采用此种方法

Code
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
# right
parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')
# wrong
parrot() # required argument missing
parrot(voltage=5.0, 'dead') # non-keyword argument following keyword
parrot(110, voltage=220) # duplicate value for argument
parrot(actor='John Cleese') # unknown keyword
**parameter: 接受一个dictionary(包含一组keyword arguments)
*parameter: the positional arguments beyond the formal parameter list。不能接受keyword arguments参数
如果两者一起使用,则*parameter必须出现在**parameter之前

Code
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, '?'
print "-- I'm sorry, we're all out of", kind
for arg in arguments: print arg
print '-'*40
keys = keywords.keys()
keys.sort()
for kw in keys: print kw, ':', keywords[kw]
#test
cheeseshop('Limburger', "It's very runny, sir.",
"It's really very, VERY runny, sir.",
client='John Cleese',
shopkeeper='Michael Palin',
sketch='Cheese Shop Sketch')
#resule
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
c) Arbitrary Argument Lists

Code
def fprintf(file, format, *args):
file.write(format % args)
d) Unpacking Argument Lists
如果参数已经存于list或tuple中,则用*来展开参数
如果参数存于dictionary中,则用**

Code
# *-operator
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]
# **-operator
>>> def parrot(voltage, state='a stiff', action='voom'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it.",
print "E's", state, "!"

>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
e) Lambda Forms
(与函数编程语言类似的功能?)像个函数

Code
>>> def make_incrementor(n):
return lambda x: x + n

>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
字符串以双引号"或单引号'为边界,期间可用\。以"""引起来的字符串以其自有的格式保存,无需加\n之类的转义字符。字符串不可以通过下标来修改
这里是中字符串的索引方式:

Code
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
List的简单应用:

Code
// a[i:j] 输出的范围为 [i,j)
a[:] // 整个字符串
a[2:] // 从a[2]到a[len-1]
a[:0] = a // 把a拷贝到a[0]之前,即a'=[a[0],a[1]
a[len-1],a[0],a[1]
a[len-1]]
a[len:] = a // 把a拷贝到a[len-1]之后
a[:i] = [] // 从a中删除a[0..i-1]
a[i:j] = a // 用a替换a[i..j]
List可以嵌套:

Code
>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
multiple assignment:

Code
>>> a, b = 0, 1
在赋值前,会先按照从左到右的顺序检查右边表达式。
1. 将所有Lucky Number按照(4,4),(4,7),(7,4),(7,7)分类,分别计算不重复的数的个数存于矩阵中:
---------------
| (4,4) | (4,7) |
--------------- ====> A
| (7,4) | (7,7) |
---------------
2. 求长度为length的Lucky Sequence的个数。这里应用矩阵乘法即可达到求解的目的。
(如:(4,4) = (4,4)*(4,4) + (4,7)*(7,4))
length = 1: return A
length = 2: return A * A
......
length = n: return A*A*...*A (即A^n)
若length为偶数:
A*A*A*...*A => (A*A)*(A*A)*...*(A*A)
=> (A^2)*(A^2)*...*(A^2)
=> (A^4)*(A^4)*...*(A^4)
=> ......
=> (A^(n/2)) * (A^(n/2))
=> A^n
若length为奇数:
A*A*A*...*A => A*(A*A*A*...*A) => ...
=> A*(A^((n-1)/2) * A^((n-1)/2))
由此可得:
1
private long[,] pow(long[,] a, int k)
{
2
if(k == 0)
{
3
//单位矩阵
4
long[,] res = new long[2,2];
5
res[0,0] = 1;
6
res[1,1] = 1;
7
return res;
8
}
9
if(k % 2 == 0)
{
10
return pow(mul(a,a), k/2);
11
} else
{
12
return mul(a, pow(a, k-1));
13
}
14
}
15
// long[,] mul(long[,], long[,]);// 矩阵乘法
最后将矩阵各个元素累加即是最后结果
用矩阵乘法来求解,code能写的非常漂亮。可惜,“我只猜中了故事开头,却没猜到故事的结局”。
摘要: 1.最简单的办法就是用递归来实现。以生成由4,7,9三个数组成,且不超过MAX_NUMBER、不小于MIN_NUMBER的数的个数:intnumber(longx){if(x>MAX_NUMBER)return0;if(x>MIN_NUMBER)cout<<x<<endl;returnnumber(x*10+4)+number(x*10+7)+number(x*...
阅读全文
摘要: 朋友发来了一个链接,看来原来是很久之前写的一篇关于“判断一个整数的二进制位中有多少个1”的Blog,yjdlut问了关于第三种判断方法的原理。这里先把原文中的第三种方法列出来: 循环: x = x & ( x - 1 ); count++; 直到x为0为止。该方法的时间复杂度是O(m)在此,不妨把x的二进制位表示为 x=an-1an-2...a0。按从低位到高位的顺...
阅读全文
摘要: Calling Convention是指程序在函数调用时传递参数和获取返回值所采用的方法:通过寄存器、或通过栈、或者是两者的混合。在Visual C++中,用于指定Calling Convention的修饰符主要有:__cdecl, __stdcall, __fastcall等。它们各自的特征如下:C Calling Convention __cdecl: 1> 参数按从右到左的顺序传递,放...
阅读全文
摘要: 前些一段时间在看WinCE的Code时发现在宏定义中有用到##,如下所示#defineGPEBLT_FUNCNAME(basename)(SCODE(GPE::*)(structGPEBltParms*))&GPE::##basename在#define中,标准只定义了#和##两种操作。#用来把参数转换成字符串,##则用来连接两个前后两个参数,把它们变成一个字符串。1#defineToSt...
阅读全文
摘要: 条件断点:断点指令 + “j(Excecute If-Else) 和 gc (Go from Conditional Breakpoint)”形如:bp Address "j (Condition) 'OptionalCommands'; 'gc' "这里仅简单说明该如何写后面的条件语句1. 非结构体变量: Code highlighting produced by Act...
阅读全文