当前位置:首页 » 操作系统 » printf源码

printf源码

发布时间: 2022-05-12 13:07:19

⑴ 求c语言中的库函数的源代码 如printf()函数,我要它的源代码

在stdio.h中。如果是数学函数如sin()等的,在math.h中。而string类的函数则在string.h中。自己看吧

⑵ 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:
#include<stdio.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 introced 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);
我第一次遇到的时候,可以说是“惊愕”,究竟会打印什么东西。折腾了好久,最后搞定了。总结在这里
http://blog.csdn.net/cinmyheart/article/details/10116359

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 introced 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:[email protected]
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))))

⑶ 关于c语言printf 与scanf问题 漏洞

这个是可以实现的,这样就行。#include#include#include#includeintmain(){intn;printf("请输入数字:【】\b\b");scanf("%d",&n);}\b是退格符号。因为“【】”是中文符号,所以占得字节数与英文字符不一样。你自己可以调一下格式。而且这儿还有一个关键的问题,就是当“【】”内的内容够长时,就会把后面的括号“】”覆盖掉。你可以自己试一下

⑷ C语言中如何使用printf来输出C语言中的程序源代码

里面的双引号加转义符\
printf("for(i=1;i<=100;i++) \
scanf(\"%d\",&a);");

⑸ C语言中printf这个函数的代码实现从哪里可以看到,这个函数是如何实现的

printf格式化char*,int,float等的格式是固定的第一个p是char*,第二个*p对应int
字符串传地址,整型直接传值就可以
第一个可以改成输出单个字符
1234char s[10]="abc";char *p=s;printf("%c\n",*p);printf("%c\n",*(p+1));

⑹ 请问到哪里可以找C语言的库函数的代码,例如PRINTF函数的代码

这个你找不到,我曾经在学习过程中也找过,只能在include文件夹下找到对于函数的定义,但函数体部分不可见.你可以到LINUX系统下找找,LINUX是完全开放源代码的.

⑺ printf的问题

首先,总结性地回答:
windows和linux和Dos三种操作系统的printf源码应该是略有区别的。
其次,介绍一下printf的底层显示函数。
printf是在屏幕上打印一个字符串的函数。
(注:数字其实也是按照字符的形式显示在屏幕上的。)
因为printf其实是解析format格式,例如%d,\n,等等。

真正在屏幕上显示的函数是决定与操作系统底层的。
也就是都是调用底层的显示策略函数实现的在屏幕的指定位置进行显示。

例如:stdio.h中的printf.c的源码中:
printChar函数就是顶层的显示策略函数。

code]int putchar (int c) {
switch ((unsigned char) c) {
case '\n' :
newLine ();
break;
case '\r' :
carriageReturn ();
break;
case '\f' :
clearScreen ();
break;
case '\t' :
printChar (32); printChar (32); /* 32 = space */
printChar (32); printChar (32);
printChar (32); printChar (32);
printChar (32); printChar (32);
break;
case '\b':
backspace ();
break;
case '\a':
beep ();
break;
default :
printChar ((unsigned char) c);
}
return c;
}[/code]

接下来看printChar也就是输出部分最低层的操作咯

[code]void printChar (const byte ch) {
*(word *)(VIDEO + y * 160 + x * 2) = ch | (fill_color << 8);
x++;
if (x >= WIDTH)
newLine ();
setVideoCursor (y, x);
}[/code]这里VIDEO表示显存地址也就是0xB8000.通过 y * 160 + x 屏幕(x,y)坐标在显存中的位置.这里需要知道,一个字符显示需要两个字节,一个是ASCII码,第二个是字符属性代码也就是颜色代码.因此才必须 y * 80 * 2 + x = y * 160 + x.那么ch | (fill_color << 8)也自然就是写入字符及属性代码用的了.每写一个字符光标位置加1,如果大于屏幕宽度WIDTH就换行.最后通过setVideoCursor设置新的光标位置.完成了整个printChar过程.

⑻ C语言中printf是库函数,那么printf的代码到底在哪里呢

在安装目录下有个叫Include的文件夹,里面有很多.H的文件,用记事本打开STDIO.H的文件就是STDIO.H的代码,里面包含了printf,scanf等函数的代码。

⑼ 为什么学完C语言,我还是看不懂printf的源代码

你学的知识语法,知识入门,真正的高手是能驾驭它,为自己所用。看不懂也很正常,也没必要这么气累,需要继续努力前进

⑽ 急求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);
}

热点内容
sql注入的过程 发布:2024-10-09 16:24:25 浏览:194
命令行ftp初始账号密码 发布:2024-10-09 16:24:24 浏览:290
脚本怎么归档 发布:2024-10-09 16:08:07 浏览:296
云平台搭建服务器 发布:2024-10-09 16:03:47 浏览:636
用阿里云搭建正向代理服务器 发布:2024-10-09 15:53:07 浏览:506
手机qq空间缓存清理缓存 发布:2024-10-09 15:51:49 浏览:353
pc泰拉瑞亚服务器ip 发布:2024-10-09 15:45:18 浏览:798
安卓怎么延时 发布:2024-10-09 15:37:51 浏览:453
android音源 发布:2024-10-09 14:55:19 浏览:121
预编译sql怎么模糊查询 发布:2024-10-09 14:31:24 浏览:219