vprintf函数源码(vprintf函数的用法)
本文目录一览:
- 1、C语言中printf是库函数,那么printf的代码到底在哪里呢?
- 2、printf函数的实现方式
- 3、急求printf函数原代码(汇编,api实现的都可以)
- 4、求: 用c语言实现进程控制的源码
- 5、printf函数源码是什么意思
C语言中printf是库函数,那么printf的代码到底在哪里呢?
书上说vprintf函数源码的没错vprintf函数源码,lib文件中存放的就是被调用系统函数的目标代码vprintf函数源码,但是和声明文件一样不是一个函数一个文件,而是一批函数放在一个文件里。并且文件是二进制的格式,vprintf函数源码你也查看不了。
对于.h头文件你理解的没错,头文件是只是函数的声明,里面不放函数的具体代码,具体代码比如VC是在C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src 目录下,你可以找到printf.c文件的源码,如果你是想看源码就看这个。我看了其它人的回复,C编译器的不同位置放的是不同的函数部分,以VC为例,include放的是调用函数的声明部分,并且只有声明部分;src目录放的是函数的源码;lib放的是函数的编译后目标文件,但是是打捆放的,代码只有在链接时,才会将库函数进行连接,并生成最后的EXE可执行文件。
printf函数的实现方式
其实printf和getchar()类似,它们都是一个”外壳“,真正实现功能的不是它本身,而是通过调用别的函数。
getchar() is equivalent to getc(stdin).
printf有一家子print函数
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - formatted output conversion
它们的声明在不同的header file里面
#include stdio.h
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
#include stdarg.h
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
snprintf(), vsnprintf():
这两个函数是C99新加的,编译的时候 注意 -std=c99
实现之前还是“复习”一下printf比较好,就当是铺垫
有意思的是printf的declaration。
int printf(const char *format, ...);
返回值是int,第一个参数是const字符串指针,第二个参数是个...
先看看返回值int有哪些情况
Return value
Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output to strings).
嗯哼。。。返回的是成功打印的字符的个数,这里不包括NULL
demo:
#includestdio.h
int main()
{
int counter = 0;
counter = printf("hello world! %d\n",10);
printf("counter is %d\n",counter);
return 0;
}
jasonleaster@ubuntu:~$ ./a.out
hello world! 10
counter is 16
接着,第一个参数是一个指针,指向const字符串
Format of the format string
The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of
zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications,
each of which results in fetching zero or more subsequent arguments. Each conversion specification is introduced by the character %,
and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an optional minimum field width,
an optional precision and an optional length modifier.
很少人会用下面这种用法
printf("%*d",10,5);
我第一次遇到的时候,可以说是“惊愕”,究竟会打印什么东西。折腾了好久,最后搞定了。总结在这里
Format of the format string
The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments. Each conversion specification is introduced by the character %, and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an optional minimum field width, an optional precision and an optional length modifier.
The arguments must correspond properly (after type promotion) with the conversion specifier. By default, the arguments are used in the order given, where each '*' and each conversion specifier asks for the next argument (and it is an error if insufficiently many arguments are given). One can also specify explicitly which argument is taken, at each place where an argument is required, by writing "%m$" instead of '%' and "*m$" instead of '*', where the decimal integer m denotes the position in the argument list of the
desired argument, indexed starting from 1. Thus,
printf("%*d", width, num);
and
printf("%2$*1$d", width, num);
are equivalent. The second style allows repeated references to the same argument. The C99 standard does not include the style using '$', which comes from the Single UNIX Specification. If the style using '$' is used, it must be used throughout for all conversions taking an argument and all width and precision arguments, but it may be mixed with "%%" formats which do not consume an argument.
There may be no gaps in the numbers of arguments specified using '$'; for example, if arguments 1 and 3 are specified, argument 2
must also be specified somewhere in the format string.
第三个参数 ...
嗯,这家伙有点屌,叫做变长参数。把这个搞定,C总会有点长进的
这个stdarg.h 我在现在的GCC和现在的linux 3.0版本的内核里面找了好久,都木有,估计是封装到被的地方了。。。。
__builtin_va_start(v,l) 线索就死在这个地方。。。之后就找不到__builtin_va_start的定义了
还是看早起内核的实现吧
0.12内核里面的stdarg.h
#ifndef _STDARG_H
#define _STDARG_H
typedef char *va_list;
/* Amount of space required in an argument list for an arg of type TYPE.
TYPE may alternatively be an expression whose type is used. */
#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
#ifndef __sparc__
#define va_start(AP, LASTARG) \
(AP = ((char *) (LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), \
AP = ((char *) (LASTARG) + __va_rounded_size (LASTARG)))
#endif
void va_end (va_list); /* Defined in gnulib */
#define va_end(AP)
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))
#endif /* _STDARG_H */
va_list 是一个指向字符串的指针
分析上面的宏定义#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
这个用来得到TYPE元素类型的字节大小,若不足4字节(例如short 和char),那么认为这个元素的大小为4字节,简单的说就是检测元素的大小,不足4字节的当作4字节看待。。。#define va_start(AP, LASTARG) \
(AP = ((char *) (LASTARG) + __va_rounded_size (LASTARG)))
AP一般都是va_list,LASTARG则是 指向参数变长函数的格式化字符串的指针.
va_start的作用就很明显了。取得变长参数列表的第一个参数的地址。
va_end 则是把指针va_list 置0 (通过google知道的,这个va_end真没找到定义,代码里面就一句#define 我无能为力啊。。。)
不过知道用va_start 和va_end 就OK啦
下面先来个变长参数的demo
/*****************************************************************************
code writer : EOF
code date : 2014.04.26
e-mail:jasonleaster@gmail.com
code purpose:
just a demo for varible parameter function.
usage: va_sum(a number,anohter number...,0);
va_sum(1,2,3,4,5,0); return 15
******************************************************************************/
#include stdarg.h
#include stdio.h
int va_sum(int* a,...);
int main()
{
int number = 1;
int foo = 0;
foo = va_sum(number,2,3,4,5,0);
return 0;
}
int va_sum(int* a,...)
{
int counter = 0;
int element = 0;
va_list arg;
va_start(arg,a);
while((element = va_arg(arg,int)) != 0)
{
counter += element;
}
va_end(arg);
return counter;
}
#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))
急求printf函数原代码(汇编,api实现的都可以)
#include cruntime.h
#include stdio.h
#include dbgint.h
#include stdarg.h
#include file2.h
#include internal.h
#include mtdll.h
int __cdecl printf (
const char *format,
...
)
{
va_list arglist;
int buffing;
int retval;
va_start(arglist, format);
_ASSERTE(format != NULL);
_lock_str2(1, stdout);
buffing = _stbuf(stdout);
retval = _output(stdout,format,arglist);
_ftbuf(buffing, stdout);
_unlock_str2(1, stdout);
return(retval);
}
求: 用c语言实现进程控制的源码
createthread(...)等等有一系列windowsAPI
你愿意用吗?
pv操作是利用信号量等的变量实现的,也有专门的api函数用于操作信号量等
printf函数源码是什么意思
就是println()这个函数实现的方法啊 SUN已经写好了 你要这个源码干嘛?
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush (s.indexOf('\n') = 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
private void newLine() {
try {
synchronized (this) {
ensureOpen();
textOut.newLine();
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}
太多了 不贴了。。