c语言printf函数原型,printf 函数原型

本文详细探讨了C语言中printf函数的可变参数用法,介绍了其工作原理、控制字符串解析以及va_list、va_start、va_arg和va_end等宏的用法。通过实例展示了如何自定义printf函数并实现格式化输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef char *va_list;

#define _AUPBND (sizeof (acpi_native_int) - 1)

#define _ADNBND (sizeof (acpi_native_int) - 1)

#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))

#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))

#define va_end(ap) (void) 0

#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

//start.c

];

int printf(char *fmt, ...)

{

va_list args;

int n;

va_start(args, fmt);

n = vsprintf(sprint_buf, fmt, args);

va_end(args);

write(stdout, sprint_buf, n);

return n;

}

int vsprintf(char *buf, const char *fmt, va_list args)

{

int len;

unsigned long num;

int i, base;

char *str;

char *s;

int flags; // Flags to number()

int field_width; // Width of output field

int precision; // Min. # of digits for integers; max number of chars for from string

int qualifier; // 'h', 'l', or 'L' for integer fields

for (str = buf; *fmt; fmt++)

{

if (*fmt != '%')

{

*str++ = *fmt;

continue;

}

// Process flags

flags = ;

repeat:

fmt++; // This also skips first '%'

switch (*fmt)

{

case '-': flags |= LEFT; goto repeat;

case '+': flags |= PLUS; goto repeat;

case ' ': flags |= SPACE; goto repeat;

case '#': flags |= SPECIAL; goto repeat;

': flags |= ZEROPAD; goto repeat;

}

// Get field width

field_width = -;

if (is_digit(*fmt))

field_width = skip_atoi(&fmt);

else if (*fmt == '*')

{

fmt++;

field_width = va_arg(args, int);

)

{

field_width = -field_width;

flags |= LEFT;

}

}

// Get the precision

precision = -;

if (*fmt == '.')

{

++fmt;

if (is_digit(*fmt))

precision = skip_atoi(&fmt);

else if (*fmt == '*')

{

++fmt;

precision = va_arg(args, int);

}

) precision = ;

}

// Get the conversion qualifier

qualifier = -;

if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')

{

qualifier = *fmt;

fmt++;

}

// Default base

;

switch (*fmt)

{

case 'c':

) *str++ = ' ';

*str++ = (unsigned char) va_arg(args, int);

) *str++ = ' ';

continue;

case 's':

s = va_arg(args, char *);

if (!s) s = "";

len = strnlen(s, precision);

if (!(flags & LEFT)) while (len < field_width--) *str++ = ' ';

; i < len; ++i) *str++ = *s++;

while (len < field_width--) *str++ = ' ';

continue;

case 'p':

)

{

field_width = * sizeof(void *);

flags |= ZEROPAD;

}

str = number(str, (unsigned , field_width, precision, flags);

continue;

case 'n':

if (qualifier == 'l')

{

long *ip = va_arg(args, long *);

*ip = (str - buf);

}

else

{

int *ip = va_arg(args, int *);

*ip = (str - buf);

}

continue;

case 'A':

flags |= LARGE;

case 'a':

if (qualifier == 'l')

str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);

else

str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);

continue;

// Integer number formats - set up the flags and "break"

case 'o':

;

break;

case 'X':

flags |= LARGE;

case 'x':

;

break;

case 'd':

case 'i':

flags |= SIGN;

case 'u':

break;

case 'E':

case 'G':

case 'e':

case 'f':

case 'g':

str = flt(str, va_arg(args, double), field_width, precision, *fmt, flags | SIGN);

continue;

default:

if (*fmt != '%') *str++ = '%';

if (*fmt)

*str++ = *fmt;

else

--fmt;

continue;

}

if (qualifier == 'l')

num = va_arg(args, unsigned long);

else if (qualifier == 'h')

{

if (flags & SIGN)

num = va_arg(args, short);

else

num = va_arg(args, unsigned short);

}

else if (flags & SIGN)

num = va_arg(args, int);

else

num = va_arg(args, unsigned int);

str = number(str, num, base, field_width, precision, flags);

}

*str = '/0';

return str - buf;

}

考察printf函数返回值

最近偶然间见了这样一道题:  #include int main() { ; printf("%d\n",printf("%d", ...

【C语言】浅谈可变参数与printf函数

一.何谓可变参数 int printf( const char* format, ...); 这是使用过C语言的人所再熟悉不过的printf函数原型,它的参数中就有固定参数format和可变参数(用& ...

实现简单的printf函数

首先,要介绍一下printf实现的原理 printf函数原型如下: int printf(const char* format,...); 返回值是int,返回输出的字符个数. 例如: int mai ...

printf 函数的实现原理

/* * ===================================================================================== * * Filen ...

s3c2440——实现裸机的简易printf函数

在单片机开发中,我们借助于vsprintf函数,可以自己实现一个printf函数,但是,那是IDE帮我们做了一些事情. 刚开始在ARM9裸机上自己写printf的实现的时候,包含对应头文件也会提示vs ...

C语言中可变参数的原理——printf&lpar;&rpar;函数

函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: 使用过C语言的人所再熟悉不过 ...

关于 printf&lpar;&rpar; 函数的三张表格

函数原型: printf(Control-String, item1, item2, ...); 表一  转换说明符及作为结果的打印输出 转 换 说 明 输    出 %a 浮点数.十六进制数字和p- ...

C语言函数的声明以及函数原型

C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错.但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明.所谓声明(Declaration),就是告诉编译器我 ...

关于printf函数的所思所想

缘起大一下学期,C语言程序设计徐小青老师的随口一提,经娄嘉鹏老师提醒,我觉得应该自己整理清楚这一问题.涉及网上资料将会标明出处. 关于printf函数的所思所想 * printf的定义 printf( ...

随机推荐

我为什么反对推荐新人编程C&sol;C&plus;&plus;语言入门?

虽然我接触编程以及计算机时间比较早,但是正式打算转入程序员这个行当差不多是大学第四年的事情 从03年接触计算机,07年开始接触计算机编程, 期间接触过的技术包括 缓冲区溢出(看高手写的shellcod ...

html和css中的技巧

1:标签不要忘记带点 2:div是否成对的出现. 3.body 前面不能加点 4.在写css时记住一定要带上class的命名这样就不会出现重复的 5.出现文字的时候下面有下划线或虚线的时候,用padd ...

排序算法FOUR&colon;堆排序HeapSort

/** *堆排序思路:O(nlogn) * 用最大堆,传入一个数组,先用数组建堆,维护堆的性质 * 再把第一个数与堆最后一个数调换,因为第一个数是最大的 * 把堆的大小减小一 * 再 在堆的大小上维护 ...

如何从代码层防御10大安全威胁中的 Xpath Injection?

普遍性和可检测性: Xpath 注入是 OWASP TOP10 安全威胁中 A1 Injection 中的一种,注入漏洞发生在应用程序将不可信的数据发送到解释器时.虽然注入漏洞很容易通过审查代码发现, ...

jQuery&period;extend&lpar;&rpar;源码解读

// extend方法为jQuery对象和init对象的prototype扩展方法// 同时具有独立的扩展普通对象的功能jQuery.extend = jQuery.fn.extend = funct ...

Hibernate实体类注解解释

Hibernate注解1.@Entity(name="EntityName")必须,name为可选,对应数据库中一的个表2.@Table(name="",cat ...

Django Channels 入门指南

http://www.oschina.NET/translate/in_deep_with_django_channels_the_future_of_real_time_apps_in_django ...

Python批量修改寄存器的值

在写代码过程中,我们修改代码中寄存器的值,但是有时寄存器的数据较多,手动修改容易出现错误而且花费的时间长 这是一段寄存器的配置值: 0x00, 0x34  0x35, 0x25  0x10, 0xd4 ...

题解-APIO2010 特别行动队

题目 洛谷 & bzoj 简要题意:给定一个长为\(n\)的序列\(\{s_i\}\)与常数\(a,b,c\),序列的一个连续子段\(s_i\)到\(s_j\)的贡献为\(at^2+bt+c\ ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值