摘要: 在C语言中,函数参数的传递方式有值传和址传.值传是把实参的一个专用的、临时的复制值给被调函数中相应的形参被调用函数使用、修改这个传来的复制值,不会影响实参的值.址传则是把变量(实参)的地址传给被调函数.被调函数通过这个地址找到该变量的存放位置,直接对该地址中存放的变量的内容进行存取操作.因此,在被调用函数中可以修改实参的值.这也是函数参数址传的优点.无论是值传还是址传,都要求实参的数目及类型与形参要完全一致.在一般的程序设计语言中,函数参数的数目及类型是不可变的.即函数被设计之后,只能接收已固定个数和固定类型的实参.这样在编译时,函数形参的存储空间便于确定.但是在C语言中,不但参数的类型可变, 阅读全文
posted @ 2011-07-06 19:10 hnrainll 阅读(451) 评论(0) 推荐(0) 编辑
摘要: 1 函数声明 首先,要实现类似printf()的变参函数,函数的最后一个参数要用 ... 表示,如 int log(char * arg1, ...)这样编译器才能知道这个函数是变参函数。这个参数与变参函数的内部实现完全没有关系,只是让编译器在编译调用此类函数的语句时不计较参数多少老老实实地把全部参数压栈而不报错,当然...之前至少要有一个普通的参数,这是由实现手段限制的。2 函数实现 C语言通过几个宏实现变参的寻址。下面是linux2.18内核源码里这几个宏的定义,相信符合C89,C99标准的C语言基本都是这样定义的。 typedef char *va_list;/* Storage ali 阅读全文
posted @ 2011-07-06 19:09 hnrainll 阅读(5897) 评论(0) 推荐(1) 编辑
摘要: 在c/c++标准库中,变参函数很特别。printf, fprintf, sprintf等都属于变参函数。如果自己要写类似的参数可变的函数,通常会用到下面三个函数: #include <stdarg.h>void va_start(va_list ap, last);type va_arg(va_list ap, type);void va_end(va_list ap);一般的用法是这样:va_list args; //声明变量va_start(args, fmt); //开始解析。args指向fmt后面的参数TYPE var = va_arg(args, TYPE); //取下一 阅读全文
posted @ 2011-07-06 19:05 hnrainll 阅读(1369) 评论(0) 推荐(0) 编辑
摘要: C语言中的移位操作,内容不多。不过有些地方你不注意,就疏忽了。 先做两个小题先。 (1)unsigned char x=3; x>1是多少? (2)char x=3; x>1是多少? (3)char x=-3; x>1是多少? 3写成二进制数是00000011;-3写成二进制数是(补码)11111101。 程序执行的时候,操作的是数值的编码表示,也就是数值在内存中的二进制表示。比如说,程序取-3的时候,就去取11111101。 (1)对无符号数3来说,x>1往右边移一位,由于是无符号数,所以逻辑右移,最右边一位移掉,最左边移进来的位补零,变成00000001,所以结果是 阅读全文
posted @ 2011-07-06 14:06 hnrainll 阅读(628) 评论(0) 推荐(0) 编辑
摘要: 在C语言中,涉及位移的运算符有2个,>>表示右移,<<则表示左移。而汇编指令中,SHL和SHR表示逻辑左移和逻辑右移,SAR和SAL表示算术左移和算术右移。其中,逻辑左移和算术左移都是寄存器二进制位整体向左移动,并在右边补0。而右移则不同,逻辑右移是整体向右移,并在左边补0,而算术左移则是根据原符号位的值补与其相同的值。那么如何在C语言中分别实现逻辑和算术位移呢?根据C标准,如果在位移运算符左边的变量是有符号数,如int,char,short等,编译产生的汇编指令是算术位移指令,如果该变量是无符号数,如unsigned int,unsigned char等,编译产生的汇 阅读全文
posted @ 2011-07-06 12:05 hnrainll 阅读(5840) 评论(0) 推荐(0) 编辑
摘要: 引自 http://topic.csdn.net/t/20010521/10/128376.htmlint型变量有时候占4个字节(在Win32),有时候占2个字节(在DOS) 这个int类型的大小到底是跟编译器有关,还是跟CPU有关,还是跟操作系统有关?所谓的16位32位64位系统是由cpu决定的,由机器指令的寻址、寄存器位数决定的 os受cpu的限制,但在32位的cpu下16位的os也可以跑(就向上面提到的所谓纯dos) 很多os是向前兼容的,就是使以前的程序也能运行,如果编译器本身是16位时代做的,那么os会提供一个模拟16位的子环境供这个编译器使用 int和void*长度应该是一样的(1 阅读全文
posted @ 2011-07-06 11:06 hnrainll 阅读(28071) 评论(2) 推荐(0) 编辑