我目前正在编写自己的printf
实现,这里是代码:
int my_printf(const char *format, ...)
{
//Declare variable ou prog fonctionnel????
va_list args;
int numberValue;
unsigned int unsignedNumberValue;
double doubleValue;
char* stringValue;
char charValue;
va_start(args, format);
for(int i = 0; format[i]; i++){
//This case is the most called case, so we test it first to get the
//best perfs
if(format[i] != '%'){
my_put_char(format[i]);
}else{
if(format[i+1] == 'd' || format[i+1] == 'i'){
numberValue = va_arg(args, int);
my_put_nbr(numberValue);
}else if(format[i+1] == 'u'){
unsignedNumberValue = va_arg(args, unsigned int);
my_put_nbr_unsigned(unsignedNumberValue);
}else if(format[i+1] == 'o'){
numberValue = va_arg(args, int);
my_put_nbr_base(numberValue, 2);
}else if(format[i+1] == 'c'){
//char parameters are passed as integer as va_args
charValue = va_arg(args, int);
my_put_char(charValue);
}else if(format[i+1] == 's'){
stringValue = va_arg(args, char*);
my_puts(stringValue);
}else if(format[i+1] == 'f'){
doubleValue = va_arg(args, double);
my_put_double(doubleValue);
}else if(format[i+1] == '%'){
my_put_char('%');
}else{
//error option not handled
char* error = my_strcat("\nThe option you provided is not a valid option: %", &format[i + 1], 1);
write(2, error, sizeof(char) * my_strlen(error));
}
i++;
}
}
va_end(args);
return 0;
}
我想知道关于我的代码的两件事:
va_args
直接调用my_put
函数。但是这样做,它将分配并释放每个循环而不是一个声明(分配),这些声明可能不被使用,而在函数结束时则是一个空闲。在大过程中,我认为最好将返回值存储到变量中然后调用函数的“函数方式”。 (对于非常大的文本上的strlen
)my_put_nbr
,我不能重载它们吗?似乎它必须有不同的名称。答案 0 :(得分:0)
优化printf以提高速度毫无意义,因为占主导地位的执行时间将是字符I / O.即使是闪电般的快速格式处理也不会为您节省在途中发送角色所需的时间。
唯一值得一提的是尺寸:堆栈大小,通过尽可能少的输出函数来避免另一级函数调用和代码大小。
优化代码的第一件事就是将测试变成一个开关。有可能编译器会将它实现为表跳转,这比一堆测试更有效。你可以把#34;最可能的"首先是格式化,但除非您能够阅读用户的想法,否则很难预测他/她是否愿意显示整数或浮点数或字符。
传递可变数量的参数是最昂贵的操作,因此将vararg处理委托给每个原子格式化函数只会产生更庞大和更慢的代码。
相反,您最好将输出代码编写为内联函数,并希望编译器扩展它们以免您进行另一级函数调用。
对于各种可能的参数大小,要采用的方法是将所有值转换为最大可能的大小(32或64位整数,浮点数或双精度,具体取决于您要支持的内容)并且具有有限数量的函数显示(例如有符号整数/无符号整数/双) 因此,您将减少源代码和可执行代码的大小。