问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C语言库函数如何编写?

发布网友 发布时间:2022-04-23 09:41

我来回答

2个回答

热心网友 时间:2023-10-31 21:03

/***
*printf.c - print formatted
*
* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines printf() - print formatted data
*
*******************************************************************************/

#include
#include
#include
#include
#include
#include
#include

/***
*int printf(format, ...) - print formatted data
*
*Purpose:
* Prints formatted data on stdout using the format string to
* format data and getting as many arguments as called for
* Uses temporary buffering to improve efficiency.
* _output does the real work here
*
*Entry:
* char *format - format string to control data format/number of arguments
* followed by list of arguments, number and type controlled by
* format string
*
*Exit:
* returns number of characters printed
*
*Exceptions:
*
*******************************************************************************/

int __cdecl printf (
const char *format,
...
)
/*
* stdout ''PRINT'', ''F''ormatted
*/
{
va_list arglist;
int buffing;
int retval;

va_start(arglist, format);

_ASSERTE(format != NULL);//断言宏。如果输出格式字符串指针为空,则在DEBUG版下断言,报告错误。

_lock_str2(1, stdout);

buffing = _stbuf(stdout);//stdout:指定输出到屏幕

retval = _output(stdout,format,arglist);

_ftbuf(buffing, stdout);

_unlock_str2(1, stdout);

return(retval);
}
以上为printf()的源代码
1、从含有可选参数函数中获得可选参数,以及操作这些参数
typedef char *va_list;
void va_start( va_list arg_ptr, prev_param );
type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
假定函数含有一个必选参数和多个可选参数,必选参数声明为普通数据类型,且能通过参数名来获得该变量的值。可选参数通过宏va_start、va_arg和va_end(定义在stdarg.h或varargs.h中)来进行操作,即通过设置指向第一个可选参数指针、返回当前参数、在返回参数后重新设置指针来操作所有的可选参数。
va_start:为获取可变数目参数的函数的参数提供一种便捷手段。设置arg_ptr为指向传给函数参数列表中的第一个可选参数的指针,且该参数必须是va_list类型。prev_param是在参数列表中第一个可选参数前的必选参数。
va_arg:返回由arg_ptr所指向的参数的值,且自增指向下一个参数的地址。type为当前参数的类型,用来计算该参数的长度,确定下一个参数的起始位置。它可以在函数中应用多次,直到得到函数的所有参数为止,但必须在宏va_start后面调用。
va_end:在获取所有的参数后,设置指针arg_ptr为NULL。
下面举例说明:
#include
#include
int average( int first, ... );
void main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}

int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
返回值为:
Average is: 3
Average is: 8
Average is: 0
综上所述,在printf()函数中,可以只输出一个字符串,也可按照一定的形式输出含有多个可选参数的字符串信息。因此,首先就要通过这些宏来获取所有的可选参数。在上面的源码可以看出printf()中,只使用了宏at_start,将可选参数的首地址赋给了arglist。
2、锁定字符串及输出字符串到屏幕
#define _lock_str2(i,s) _lock_file2(i,s)
void __cdecl _lock_file2(int, void *);
#define _unlock_str2(i,s) _unlock_file2(i,s)
void __cdecl _unlock_file2(int, void *);
int __cdecl _stbuf(FILE *);
void __cdecl _ftbuf(int, FILE *);
int __cdecl _output(FILE *, const char *, va_list);
在output函数中,读取格式字符串中的每一个字符,然后对其进行处理,处理方式根据每一个字符所代表的意义来进行,如:普通字符直接利用函数WRITE_CHAR(ch, &charsout);输出到控制台。
其中的主要部分是对转换说明符(d,c,s,f)的处理,现在将对其中的部分代码进行详细说明,这里只说明最基本的转换说明符,对这些须基本的转换说明符进行修饰的修饰符,程序中单独进行处理。下面是函数output()(output.c)部分源代码:
case ST_TYPE:
//表示当前处理的字符的类型为转换说明符。
...
switch (ch) {
//下面对参数的获取都是利用宏va_arg( va_list arg_ptr, type );来进行的。
case ''c'': {
//从参数表中获取单个字符,输出到缓冲字符串中,此时,type=int
buffer[0] = (char) get_int_arg(&argptr); /* get char to print */
text = buffer;
textlen = 1; /* print just a single character */
}
break;

case ''s'': {
//从参数表中获取字符串,输出到缓冲字符串中,此时,type=char*
int i;
char *p; /* temps */
text = get_ptr_arg(&argptr);
...
}
break;

case ''w'': {
//对宽字符进行处理
...
} /* case ''w'' */
break;
...
case ''e'':
case ''f'':
case ''g'': {
//对浮点数进行操作
...
#if !LONGDOUBLE_IS_DOUBLE
/* do the conversion */
if (flags & FL_LONGDOUBLE) {
_cldcvt((LONGDOUBLE*)argptr, text, ch, precision, capexp);
va_arg(argptr, LONGDOUBLE);
//对长双精度型进行处理,此时,type=long double
}
else
#endif /* !LONGDOUBLE_IS_DOUBLE */
{

//对双精度型进行处理,此时,type=double
_cfltcvt((DOUBLE*)argptr, text, ch, precision, capexp);
va_arg(argptr, DOUBLE);
}
...
break;
//对整型变量处理
case ''d'':
case ''i'':
...
goto COMMON_INT;

case ''u'':
radix = 10;
goto COMMON_INT;

case ''p'':
...
goto COMMON_INT;

case ''o'':
...

注:对于浮点型double和long double,有相应的转换说明符(%f表示双精度型,%lf表示长双精度型),而float却没有。其中的原因是,在K&RC下,float值用于表达式或用作参数前,会自动转换成double类型。而ANSI C一般不会自动把float转换成double。有些程序已假定其中的float参数会被转换成double,为了保护大量这样的程序,所有printf()函数的float参数还是被自动转换成double型。因此,在K&RC或ANSI C下,都无需用特定的转换说明符来显示float型。
综上所述,转换说明符必须与待打印字符的类型。通常,用户有种选择。例如,如要打印一个int类型的值。则只可以使用%d,%x或%o。所有这些说明符都表示要打印一个int类型的值;它们只不过提供了一个数值的几种不同表示。类似一,可以用%f、%g和%e来表示double类型的值。但如果转换说明与类型不匹配,将会出现意想不到的结果。为什么呢?问题就在于C向函数传递信息的方式。
这个失败的根本细节与具体实现相关。它决定了系统中的参数以何方式传递。函数调用如下:
float n1;
double n2;
long n3;
long n4;
...
printf("%ld,%ld,%ld,%ld",n1,n2,n3,n4);
这个调用告诉计算机,要把变量n1,n2,n3和n4的值交给计算机,它把这些变量放进称作栈(stack)的内存区域中,来完成这一任务。计算机把这些值放进栈中,其根据是变量的类型而不是转换说明符,比如n1,把8个字节放入栈中(float被转换成double),类似地,为n2放了8字节,其后给n3和n4各放了4个字节。接着,控制的对象转移到printf();此函数从栈中读数,不过在这一过程中,它是在转换说明符的指导下,读取数值的。说明符%ld指定printf()应读4个字节(va_arg( va_list arg_ptr, type )中type=long),因此printf()读入栈中的4个字节,作为它的第一个值。但是这只是n1的前半部分,这个值被看成一个long整数。下一个说明符%ld读入4个字节,这正是n1的后半部分,这个值被看成第二个long整数。类似地,第三、第四次又读入n2的前后两部分。因此,尽管我们对n3和n4使用了正确的说明符,printf()仍然会产生错误。

热心网友 时间:2023-10-31 21:04

自己可以编写一个头文件的,而且编写好之后放到编译器安装目录下的include目录里面,在以后编写程序的时候就可以#include <filename.h>了。比如编写一个头文件:
color.h:

#include <Windows.h>
void SetColor (size_t num)
{
HANDLE Consolehwnd;
Consolehwnd = GetStdHandle (STD_OUTPUT_HANDLE);
SetConsoleTextAttribute (Consolehwnd, num);
}
在以后的程序中#inlcude <color.h>是可以的。但是注意只能在自己的编译器中运行哦。
C语言中,如何自己定义一个库函数?

1、存为xx.h文件放在自创的文件夹下,声明#include“xx.h” 2、还可以存为xx.h文件直接与系统库文件放一起,声明#include&lt;xx.h&gt;(这样会快些)

c语言库函数用什么编写的?

C语言的标准库函数一般都是用C语言编写的。Linux系统上可以参考glibc的源码,清一色的c源码。Windows系统上可以参考VC6的C标准库源码。

C语言库函数如何编写?

1、从含有可选参数函数中获得可选参数,以及操作这些参数typedef char *va_list;void va_start( va_list arg_ptr, prev_param ); type va_arg( va_list arg_ptr, type );void va_end( va_list arg_ptr );假定函数含有一个必选参数和多个可选参数,必选参数声明为普通数据类型,且能通过参数名来获得该...

C语言:如何自己做库函数?

void lib_func();int main(int argc, char *argv[]){ lib_func();} 第三步:命令 cl /c libdemo.c '编译libdemo.c 生成libdemo.obj lib libdemo.obj '生成libdemo.lib 库文件 cl /c main.c '编译main.c link main.obj libdemo.lib '生成main.exe --- 呵呵 加点...

关于c语言中如何创建自己的库函数能不能再详细的解释一下,谢谢了...

被写入了lib文件里。在lib文件里,包含了函数名与函数地址组成的结构体,通过它编译器可以找到lib文件里需要的二进制代码并以静态联编的方式写入我们调用它的exe文件里。这种代码是被塞进exe文件里而无需修改,并在程序执行时被用到。为了让库被别人调用,我们可以写一个头文件.h,包含函数原型及声明。

C语言 库函数的实现???

C语言的库函数大多数是用C语言编的,只有少数与硬件有直接联系的核心部分才用汇编.所谓库函数并不深奥,库函数也是由一个一个函数(子程序)组成的,如同我们自己程序里,有时也写很多子程序.如果我们把一些可以反复使用的子程序拿出来,集中到一起,编译成一个my.obj文件,今后写新程序时我们不另写这些子...

c语言的编程步骤有哪些呢?

引入头文件:根据程序需要,引入相应的头文件,以便使用所需的函数和库。定义全局变量:在程序的开头,可以定义全局变量,这些变量可以在整个程序中使用。定义函数:编写自定义函数,以实现程序的不同功能。函数是 C 语言的基本组织单位。编写主函数:在主函数 main 中编写程序的主要逻辑。主函数是程序的...

c语言中库函数sin是如何编写的?

利用泰勒公式 include&lt;stdio.h&gt; int main(int argc, char* argv[]){ double x=0.52;//仅仅举例说明 double y;y=x-x*x*x/(3*2);printf("%f\n",y);return 0;}

C语言中,定义自定义库函数时该如何写对应的头文件

1 功能类似或相关的一组函数写在同一个头文件中;2 头文件命名应简单,尽量短,但可以通过文件名得知内部函数功能;3 头文件名由数字、字母、下划线组成,不要有空白字符或其它符号;4 为防止头文件重复引用,或嵌套引用,头文件应使用条件编译包含;5 头文件中,应遵循先类型定义,后函数声明的顺序;...

一个关于创建C语言函数库的问题?

静态链接库(Static Libary)用VS2008做一个静态链接库先 打开VS2008,选择控制台应用程序,下一步里面选择lib 新建static_lib.h 和static_lib.cpp 两个文件,这两个文件的内容如下:static_lib.h:int add(int x,int y);int substract(int x , int y); static_lib.cpp:#include "static_...

C语言中的库函数有哪些 C语言标准库函数fread C语言日期函数库 c语言库函数大全 c语言常用的库函数表 c语言标准库函数大全 常用c语言标准库函数 c语言合并字符串的库函数是 c语言库函数在线
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
空压机压力自动开关两根线接错了会如何 8立方螺杆空压机线路接错会影起抱死吗 油五行属什么 ...密度 如果 用网箱养 一个6平方的网 可以放多少苗?还有莲池好养吗... 红枣,苟杞,海蛇,黄氏,党参,牛鞭,可以泡酒吗 230千瓦等于多少度电 230个千瓦得用多大的电缆 加急问题。请教发电机组230千瓦价格是多少? 230千瓦要用多大电缆 ...300千瓦的柴油发电机组无法带动总装机容量230千瓦的机电设备_百度知 ... c语言中库函数原理 怎么炸茄子酥脆不软? 什么是C 库函数啊 C语言库函fgets(str,n,fp)的功能是 在C中,什么是标准库函数? C语言的库函数放在什么地方(在什么目录里)? C语言库函数 c语言里面的库函数是什么一个概念? 如何学习C语言的库函数? C语言中什么是库函数? 华为手机微信视频通话怎么才能设置美颜? 华为手机美颜怎么设置? 华为手机怎样设置微信通话美颜 wifi有辐射吗? 无线网络的辐射和手机的辐射哪个大? win10系统检测不到无线网络,点击连接网络时出现如下图? 用什么煮饭才会更加的美味? win10 搜索不到wifi ,显示可用网络里面什么都没没有百度里面的所有方式都试过了 没用 攸县有一个专门吃鱼,吃柴火鱼的地方是在那个地方?听说很好吃 win10连接wifi 网络不可用怎么办 C语言的库函数该如何学下? 什么是c语言库函数 初学c语言,函数库和库函数有什么区别,都是什么意思? c语言库函数怎么用? c语言中的库函数是如何使用的,最好有例子 如何使用微信小程序功能? 微信小程序如何使用? 微信小程序怎么用?有什么用途? 使用微信小程序带来的好处有哪些? 微信小程序如何使用呢? 我是一名初中生,晚上总是失眠到底是为什么 学生经常失眠是怎么回事? 孩子高三,夜里经常失眠,这是什么原因呢? 为什么会经常失眠,主要原因是什么? 我是一名高三学生,晚上老是失眠睡不着,一点动静都会惊醒,这是怎么回事... 大学生睡眠不足的原因 目前大学生失眠的原因有哪些 晚上经常失眠是什么原因? 中学生晚上失眠是什么原因 导致大学生失眠的因素有哪些