Zhang Jiuan’ Notes

宏中#和##的用法

宏中”#”和”##”的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#i nclude
#i nclude
using namespace std;
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
int main()
{
printf(STR(vck)); // 输出字符串”vck”
printf(”%d\n”, CONS(2,3)); // 2e3 输出:2000
return 0;
}
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开.
1, 非’#’和’##’的情况
#define TOW (2)
#define MUL(a,b) (a*b)
printf(”%d*%d=%d\n”, [...]

编写Vim 脚本

*41.1* 简介 *vim-script-intro* *script*你最初接触到 Vim 脚本是在 vimrc 文件里。当 Vim 启动时它将读取该文件的内容并执行其中的命令。你可以在其中设置选项。你也可以在其中使用任何冒号命令 (以 “:” 开头的命令;这些命令有时也被称作 Ex 命令或命令行命令)。 语法文件其实也是 Vim 脚本。专为某种文件类型设定选项的文件也是。一个很复杂的宏可以被单独的定义在一个 Vim 脚本文件中。你可以自己想到其它的应用。让我们从一个简单的例子开始: :let i = 1 :while i < 5 : echo “count is” i : let i += 1 :endwhile 备注: 那些 “:” 字符并非必须。只有在你键入命令时才需要,在编写 Vim 脚本时可以 去掉。在这里用一是为了清楚,二是为了区别于普通模式命令。 备注: 你可以拷贝这里的示例文本,然后用 :@” 执行。本例的输出是: count is 1 count is [...]

康晓宁:网站那些事 互联网架构如何设计/优化

【Csdn 10月24日 现场报道】10月24日,有Csdn和《程序员》联合主办的代表业界最高水平的技术盛会SD2.0大会进行到了最后一天,在上午,互联网架构师康晓宁向关注架构设计的与会技术人员分享了他多年来的实践心得。

康晓宁的讲演主题很有趣,叫做网站那些事儿,他希望以一种轻松的方式同大家一起交流在架构设计的实践经验。他认为网站只不过是一种特殊的软件,即互联网时代的软件。由于面对的最终用户和市场不同,它的开发呈现出快,猛,糙的特点。对互联网架构师提出更高的需求。
这种高,并不代表需要多么高新的技术,而是架构师针对需求,制定出来合理的架构的能力要求更高。
互联网架构是个年轻的技术领域,互联网架构师面临诸多烦恼。例如,多个层面上的设计,知识面不足;架构设计开发经常要同紧张的时间赛跑;新技术方案和优化手段众多,难以抉择。
随后就是本场课程最有价值的内容康晓宁总结自多年架构实践的互联网架构设计/优化原则。这些原则受到与会学员的极大欢迎。
讲师介绍:康晓宁,Googel软件工程师,清华大学计算机系硕士,曾任清华大学BBS 水木清华站技术站务,供职于数家国内大型网站,从事一线开发和运维工作。
If you enjoyed this post, make sure you subscribe to my RSS feed!

《Linux内核修炼之道》精华分享与讨论(11)——设备模型(上)

对于驱动开发来说,设备模型的理解是根本,毫不夸张得说,理解了设备模型,再去看那些五花八门的驱动程序,你会发现自己站在了另一个高度,从而有了一种俯视的感觉,就像凤姐俯视知音和故事会,韩峰同志俯视女下属。
顾名而思义就知道设备模型是关于设备的模型,既不是任小强们的房模,也不是张导的炮模。对咱们写驱动的和不写驱动的人来说,设备的概念就是总线和与其相连的各种设备了。电脑城的IT工作者都会知道设备是通过总线连到计算机上的,而且还需要对应的驱动才能用,可是总线是如何发现设备的,设备又是如何和驱动对应起来的,它们经过怎样的艰辛才找到命里注定的那个他,它们的关系如何,白头偕老型的还是朝三暮四型的,这些问题就不是他们关心的了,而是咱们需要关心的。在房市股市千锤百炼的咱们还能够惊喜的发现,这些疑问的中心思想中心词汇就是总线、设备和驱动,没错,它们就是咱们这里要聊的Linux设备模型的名角。
总线、设备、驱动,也就是bus、device、driver,既然是名角,在内核里都会有它们自己专属的结构,在include/linux/device.h里定义。
52 struct bus_type {
53 const char * name;
54 struct module * owner;
55
56 struct kset [...]

不定参数的应用 function(fmt, …)

不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多。除了格式化输出之外,我实在没看到多少应用。主要原因是这种技术比较麻烦,副作用也比较多,而一般情况下重载函数也足以替换它。尽管如此,既然大家对它比较感兴趣,我就简单总结一下它的使用和需要注意的常见问题。
原理
刚学C语言的时候,一般人都会首先接触printf函数。通过这个函数,你可以打印不定个数的变量到屏幕,如:
printf(”%d”, 3);
printf(”%d,%d”,3,4);
上述代码看似简单,实际上却需要我们解决许多问题。在我们设计printf的时候,我们是不知道到底会传入几个参数的。在这种未知的情况下,我们需要解决下面几个问题:
怎么告诉printf我们会传入几个参数
printf怎么去访问这些参数
函数调用完成后,系统怎么把参数从传递用的堆栈中释放
为了解决这些问题,我们首先要解释cdecl调用约定(参见论调用约定),所有使用不定参数的函数必须是使用cdecl(全局函数)或者this call(类成员函数)调用约定。该约定对于参数传递规定如下:
参数从右向左入栈(也就是如果你调用f(a,b,c),则c先入栈,然后是b,最后是a入栈)
调用者负责清理堆栈
其中第二点直接解决了前面三个问题中的第三个问题。我们来详细说说其他两个问题。
确定参数的个数
在一个函数中,一般有如下prolog代码:
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,48h
执行上述代码之后,func(a,b,c)函数所处的堆栈上下文就变成如下布局:
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/arong1234/archive/2008/05/18/2456455.aspx

其中,ebp指向保存旧的ebp的堆栈内存的下一个字的地址,ebp+8指向eip地址,ebp+12则指向函数调用的第一个参数,而ebp和esp之间是用于临时变量(也就是堆栈变量)的空间。
注意,由于上述prolog代码的存在,我们很容易通过ebp得到第一个参数的地址,对于不定参数列表之前的类型固定的参数,我们也可以根据类型信息得到其实际的位置(例如,第一个参数的位置偏移第一个参数的大小,就是第二个参数的地址)。
注意不定参数函数有个限制,就是不定参数的列表必须在整个函数的参数列表的最后。我们不可以定义如下的函数:
void func(int a, …, int c)
所有类型固定的参数都必须出现在参数列表的开始。这样根据前面的论述,我们就可以得到所有类型固定的参数。
在设计具有不定参数列表的函数的时候,我们有两种方法来确定到底多少参数会被传递进来。
方法1是在类型固定的参数中指明后面有多少个参数以及他们的类型。printf就是采用的这种方法,它的format参数指明后面每个参数的类型。
方法2是指定一个结束参数。这种情况一般是不定参数拥有同样的类型,我们可以指定一个特定的值来表示参数列表结束。下面这个sum函数就是一个例子:
int sumi(int c, …)
…{
va_list ap;
[...]

收购后Java之父首次公开亮相 称Oracle掌管Java令人放心

在Oracle收购Sun Microsystems之后,Java之父James Gosling首度在公开场合露面,他一如既往保持着对Java的高度关注,并表示Java在Oracle的掌管下令人放心,随后他还透露了Java的发展方向。
Gosling是在TheServerSide Java Symposium上发表这份公开说明的,当时他的报告主题是Java Today and Tomorrow。他表示目睹了Oracle掌舵Java的方向之后,他深受鼓舞,Java的未来不需要担忧,关于Java的运营以及其技术的发展仍在向着有利的方向继续。
Gosling还公布了一份最新的Java报告,比如JRE (Java Runtime Environment)的每周下载量为1500万;共有100亿个Java-enabled的应用;10亿个Java-enabled的桌面;一亿个Java-enabled的TV设备;26亿个Java-enabled的移动设备;55亿个Java智能卡以及超过650万名Java开发者。
尽管目前大家看到的大多是Oracle在企业端Java的努力,但Gosling表示,Oracle同样也在致力于Java在桌面端、嵌入式、移动领域、高性能计算机及其他系统方面的发展。他说,所有这一切的原则是网络,网络将这些应用和功能链接。
谈到企业端Java,Gosling表示Java EE 6 (Java Platform, Enterprise Edition 6)将是下一代企业软件的基础, Java社区及许多开发者在2009年11月促使了Java EE 6 specification的认可,并发布和升级了一些Java API,Gosling对此表示感谢。
Gosling表示,Java EE 6以模块化为中心,引入了profiles的概念,但是有两个profiles,一个是full profile,另一个是Web profile。Web profile是第一个被定义的Java EE profile,对于现代Web应用开发它是一个功能全面的中型堆栈。
Gosling还提到了Java EE 6 specification中新增的依赖注入(dependency injection)特性。依赖注入可以允许你在代码中注入依赖,你将可以使用JDK 5 [Java Development Kit 5]中的注释特性来析出模板代码[boilerplate],从而EJB [Enterprise JavaBeans]的麻烦一扫而光。有趣的是,就在几年前这些问题还是Java社区内争论的焦点呢。
同时,Gosling宣布了GlassFish应用服务器的升级新版本为Version 3,它也是Java EE 6的参考实现(reference implementation)。GlassFish是全球最流行的下载型应用服务器,每个月的下载量为100万。
另外,Gosling表示Oracle也在积极推进NetBeans IDE,使它积极运用到企业端、移动领域和桌面端开发。
Java很棒的一点是他是一个two-level specification,既是Java语言,同时它的魔力在于VM [virtual machine]以及它可以支持包括Scala, Ruby, Groovy, Python, PHP, JavaScript, JavaFX在内的上百种其他语言。
展望Java语言接下来的五到十年,Gosling表示开发者应当寻求稳定的、逐渐增强的语言,因为这样的语言能够促进开发者的进步。
Sun曾在2009年的时候高调宣布了Java [...]

几个内存相关面试题(c/c++)

void GetMemory(char *p)
{
p=(char*)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str,”helloworld”);
printf(str);
}
请问运行Test函数会有什么样的结果?
答:程序崩溃。因为GetMemory并不能传递动态内存,Test函数中的str一直都是NULL。strcpy(str,”helloworld”);将使程序崩溃。
char *GetMemory(void)
{
char p[]=”helloworld”;
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
请问运行Test函数会有什么样的结果?
答:可能是乱码。因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,但其原先的内容已经被清除,新内容不可知。
void GetMemory2(char **p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, “hello”);
printf(str);
}
请问运行Test函数会有什么样的结果?
答:(1)能够输出hello(2)内存泄漏
以上都是关于内存的问题,我想问第一个为什么说GetMemory不能传递动态内存,而第三个 GetMemory2(char **p, int num)却可以;还有第二个说GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,总之我不懂,最好懂得人能一句一句的解释。
If you enjoyed this post, make sure you subscribe to my RSS feed!

linux下的 rm 命令-i选项

有时候使用rm命令的时候觉得有个删除提示比较保险;但真的加上了,
在使用的大多数时候又觉得比较麻烦。这其实可通过rm的-i选项来控制的.
以下是用rm –help命令查出来的
用法:rm [选项]… 文件…
删除 (unlink) 文件。
-f, –force 强制删除。忽略不存在的文件,不提示确认
-i 在删除前需要确认
-I 在删除超过三个文件或者递归删除前要求确认。此选项比-i 提
示内容更少,但同样可以阻止大多数错误发生
–interactive[=WHEN] 根据指定的WHEN 进行确认提示:never,once (-I),
或者always (-i)。如果此参数不加WHEN 则总是提示
–one-file-system 递归删除一个层级时,跳过所有不符合命令行参
数的文件系统上的文件
[...]

asmlinkage, linux源代码

asmlinkage long sys_nice(int increment)
“asmlinkage” 是在 i386 system call 实作中相当重要的一个 gcc 标签(tag)。
当 system call handler 要呼叫相对应的 system call routine 时,便将一般用途暂存器的值 push 到 stack 里,因此 system call routine 就要由 stack 来读取 system call handler 传递的参数。这就是 asmlinkage 标签的用意。
system call handler 是 assembly code,system call routine(例如:sys_nice)是 C code,当 assembly code 呼叫 C function,并且是以 stack 方式传参数(parameter)时,在 C [...]

自动化测试中Python与C/C++的混合使用

背景
项目的 自动化测试中已经使用了基于Python 脚本的框架,自动化过程中最关键的问题就是如何实现桩模块。运用 Python 强大的功能,实现任何桩模块都是可能的,但是是否必须完全使用 Python 实现模块逻辑,成本是一个决定性因素。在桩模块逻辑简单的情况下,使用 Python 模拟模块逻辑不但使自动化测试的结构清晰,也具有更好的灵活性,但是如果桩模块逻辑复杂,实现起来可能要耗费很大的成本,也容易由于桩模块逻辑与实际不符导致测试结果不可信。在这种情况下,如果能够借用 RD 开发的某些代码段 / 库,将会对测试自动化带来很多效益。
另外,在Python 中调用 C/C++ 代码的方法也可能应用于 C/C++ 库的测试中,这种测试方法的可行性还有待研究。
以下总结出几种在Python 中调用 C/C++ 代码的方法
使用ctypes 模块调用 C 动态库
从Python2.5 开始, Python 开始提供 ctypes 模块来提供对 C 语言编译的动态库文件的调用。注意, 这里特指C 的动态库 ,用C++ 编译的动态库 ctypes 虽然能够加载,但调用时的函数名已经由于 C++ 的重载特性被加以修改,难以调用。 使用 ctypes 调用 C 动态库的好处在于不用进行额外的开发,可以直接使用编译好的动态库。 ctypes 提供了完整的 C 类型封装,也支持自定义类型,大大减少在调用过程中的工作量。 ctypes 的使用很简单,只需熟悉 python 封装与 C [...]

返回顶部