不知道什么原因,基本上所有的C语言入门书籍的第一个C语言实体,都是“Hello Word!”;我不知道这是不是行业的“潜规则”, 就像某些行业的潜规则一样,不过这个都不重要了,重要的是就是“她”把无数的程序员带进了计算机的世界;不管是合格的程序员,还是不合格的程序员(就像我似的)。
说来也奇怪,就那么些简单的字符经过不知道什么物理变化还是化学变化后,居然就能在计算机上显示出"Hello Word!"。
我记得我第一次摸电脑时,不知道怎么开机, 当然以为关机就像关电视一样......哈哈,到目前为止我还经常关电脑就像关电视机一样(当然这是在计算机当机之后);记得第一看计算机基础的时候, 说要在计算机上安装软件, 我以为就像在墙上安装电灯一样,需要把计算机的壳子打开,然后再把要安装的软件用螺丝拧到机壳上就完事了................
下面进入本次瞎掰的主题:
#include <stdio.h>
int main(int argc,char **argv)
{
printf("Hello Word!");
}
我至目前为止还不明白这些字母是怎么把字符显示到电脑屏幕上的,不知道这些字符是怎么驱动电子怎么运动的, 反正我在学校的时候知道如果用与非门的电子器件是可以驱动LED指示灯显示出一些信息的,就像目前流行的LED显示屏一样, 哈哈哈.....................实在是惭愧。
几乎所有的C语言教材,都会明确的指出,printf();这个不是C语言定义的基本组成元素,而是由系统或者编译器提供商提供的一个应用接口。一般其函数原型应该是这样的:
int printf(const char *,...);
这里有个问题,我们学习函数定义的时候,教材应该是这样说的:
函数修饰符 函数返回值类型 函数标识符(函数参数列表)
Exp:
stdcall int max(int x,int y);
就是函数形式参数在声明函数原型的时候必须指定函数参数的数据类型, 即: 函数修饰符 函数返回值类型 函数标识符(参数类型1,参数类型2);
但是我们的printf()函数的参数列表里面有一个: ... ; 那么在函数的参数列表里面具有(...) 是什么意思呢?
我上学的时候老师推荐的是谭的书,可以我从头翻到尾,又从尾部翻到头, 都没有发现怎么解释这个问题, 难怪有些人会在一些地方大骂谭的书不怎么样,想想还真不是空穴来风(这里说这个,完全没有任何别的意思,只是想说明,中国的教育界,真的很..............). 为了弄明白这个问题我苦苦的等了六年,整整六年(大一学C,毕业两年了);
在那本经典的书里面有这么一段话:
头文件<stdagr.h>提供了遍历未知数目和类型的函数表的功能。
假设函数F带有可变数目的实参,lastarg是他的最后一个命名的形式参数,那么在函数F内声明一个类型为va_list的变量ap,它将依次指向每个实际参数:
Exp: va_list ap;
在访问任何未命名的参数前,都必须用va_start宏初始化ap一次:
Exp: va_start(va_list ap,lastarg);
此后每执行宏va_arg都将产生一个与下一个未命名的参数具有相同类型和数值的值,它同时还修改ap; 以使得下一次执行宏va_arg是返回下一个参数:
Exp: type va_arg(va_list ap,type )
在所有的参数处理完毕后,且在退出F函数之前,必须调用一次va_end宏一次,如下所示:
Exp: void va_end(va_list ap);
下面我们简单的看看这个宏怎么使用:
我们模仿一个printf函数的实现:
unsigned int myprintf(const char *format,...)
{
va_list varg;
char *p,
chSave;
int iGetInPut;
double fGetInput;
va_start(varg,format); // 初始化参数
for(p=format;*p;P++)
{
if('%' != *p)
{
putchar(*p);
continue;
}
switch(*(p++) )
{
case d:
iGetInput=va_list(ap,int);
printf("%d",iGetInput);
break;
case f:
fGetInPut=va_list(ap,float);
printf("%f",fGetInPut);
break;
case s:
chGetInPut=va_list(ap,char);
putchar(chGetInPut);
break;
default:
putchar(*p);
break;
}
}
va_end(varg);
}
哈哈, 模仿的一个程序...............
至于怎么实现这个varg,那决定于系统和开发的编译器...............
为了实现变参数,需要进行判断..............判断每一个输入不定参数的类型............