1、Stdarg.h介绍:
stdarg.h 是 C 编程语言中的一个头文件,它提供了一个机制,用于函数接受可变数量的参数。“stdarg” 这个名字代表 “standard arguments”(标准参数),这个头文件通常用于创建可以接受不同数量参数的函数,比如 printf 和 scanf 函数。
在 C 中,函数通常具有固定数量的参数,在函数声明时就已经定义好了。然而,有些情况下,你可能希望创建一个能够每次调用时接受不同数量参数的函数。这就是 stdarg.h 的用途。
2、Stdarg.h的基本原理:
(1)、宏定义:
- ’ va_list ':用于声明一个变量,用来保存参数列表;
- ’ va_start ':将 ’ va_list ’ 变量初始化,使其指向函数的固定参数后的第一个参数;
- ’ va_arg ':从 **’ va_list '**中获取下一个参数,需要指定参数的类型;
- ’ va_end ':用于清理和终止 ’ va_list '。
(2)、函数声明:
要使用可变参数功能,需要在参数列表中使用 … 省略号。例如:
#include <stdarg.h>
int my_printf(const char *format, ...);
(3)、函数定义:
在函数定义中,你可以使用 stdarg.h 中的宏来处理可变参数。以下是一个实现基本 my_printf 函数的简单示例:
#include <stdio.h>
#include <stdarg.h>
int my_printf(const char *format, ...) {
va_list args;
va_start(args, format);
while (*format != '\0') {
if (*format == '%') {
format++;
switch (*format) {
case 'd':
printf("%d ", va_arg(args, int));
break;
case 's':
printf("%s ", va_arg(args, char *));
break;
// 根据需要为其他格式说明符添加更多的情况
default:
putchar(*format);
}
} else {
putchar(*format);
}
format++;
}
va_end(args);
return 0;
}
(4)、使用函数:
在定义函数后,你可以像使用任何其他可变参数函数一样使用它:
int main() {
my_printf("你好,%s!答案是 %d。\n", "小明", 42);
return 0;
}
使用 stdarg.h 需要小心处理参数,以避免未定义的行为或与内存相关的问题。
3、在C语言中printf和scanf的函数原型和简单实现:
(1)、printf:
在 C 语言中,printf 函数用于格式化输出到标准输出(通常是终端窗口)。
- 函数原型:
int printf(const char *format, ...);
- 简单实现:
#include <stdio.h>
#include <stdarg.h>
int my_printf(const char *format, ...) {
va_list args;
va_start(args, format);
int count = 0; // 用于记录输出的字符数
while (*format != '\0') {
if (*format == '%') {
format++;
switch (*format) {
case 'd':
count += printf("%d", va_arg(args, int));
break;
case 's':
count += printf("%s", va_arg(args, char *));
break;
default:
putchar(*format);
count++;
}
} else {
putchar(*format);
count++;
}
format++;
}
va_end(args);
return count; // 返回输出的字符数
}
int main() {
int num = 42;
char str[] = "Hello, World!";
int printed = my_printf("Number: %d, String: %s\n", num, str);
printf("Total characters printed: %d\n", printed);
return 0;
}
(2)、scanf:
在 C 语言中,scanf 函数用于从标准输入(通常是终端窗口)读取格式化输入。
- 函数原型:
int scanf(const char *format, ...);
- 简单实现:
#include <stdio.h>
#include <stdarg.h>
int my_scanf(const char *format, ...) {
va_list args;
va_start(args, format);
int count = 0; // 用于记录成功读取的输入项数
while (*format != '\0') {
if (*format == '%') {
format++;
switch (*format) {
case 'd': {
int *num = va_arg(args, int *);
if (scanf("%d", num) == 1) {
count++;
}
break;
}
case 's': {
char *str = va_arg(args, char *);
if (scanf("%s", str) == 1) {
count++;
}
break;
}
default:
// 忽略格式说明符之外的字符
getchar(); // 清除非法字符
}
} else {
// 忽略格式说明符之外的字符
getchar(); // 清除非法字符
}
format++;
}
va_end(args);
return count; // 返回成功读取的输入项数
}
int main() {
int num;
char str[100];
printf("Enter a number: ");
int numRead = my_scanf("%d", &num);
printf("Number read: %d\n", num);
printf("Items read: %d\n", numRead);
printf("Enter a string: ");
int strRead = my_scanf("%s", str);
printf("String read: %s\n", str);
printf("Items read: %d\n", strRead);
return 0;
}