C - 这些 printf 如何为输出提供任何值?函数不返回任何内容


#include <stdio.h>
int fun1(void);
int fun2(void);
int fun3(void);
int x;  //global variable
void main(){
x=10;
printf("x = %dn",x);
printf("x = %dn",fun1());
printf("x = %dn",fun2());
printf("x = %dn",fun3());
}

fun1(void){
x = x+10; //global
}
fun2(void){
int x;
x = 1;  //local
return x;
}
fun3(void){
x = x+10;  //local
}

输出:

x = 10
x = 20
x = 1
x = 30

在典型的C函数中,将传递的参数在编译时是已知的。它们在函数定义和函数声明(如果有的话)中声明。

编译器在此基础上生成代码,并进行编译时检查,以便如果您传递了一个意外的参数或错误的类型之一,编译器将注意并输出错误或警告。

但是printf不是这样工作的。

printf这样的函数在每次调用时都能够处理不同数量和类型的参数,而不需要知道这些参数在编译时是什么。

这些被称为variadic函数,而不是显式地声明它们的参数,它们使用宏,如va_start,va_arg,va_end,以便在运行时获取参数。下面是这些宏的手册页:

https://linux.die.net/man/3/va_arg

通过在格式字符串中使用%d,您已经向printf函数承诺,在格式字符串之后传递的第一个参数将是整数。但是在您的代码中,您没有这样做。你的代码违背了它对printf的承诺,但printf没有办法知道…它只会使用va_arg宏从内存位置获取一个整数值。

因为你没有把整型放在它应该在的地方,它抓取的值将是碰巧在那个内存位置的任何值,这可能是完全的垃圾。

在C规范中,这就是所谓的"未定义行为"。它的意思很简单,就是不支持这样做,而且C语言根本不能保证如果这样做会发生什么。

在高级语言中,例如在Python中,有更多的运行时检查,并且打印函数可以在运行时确定您传递了多少参数及其类型。但在c中不是这样。您必须确保传递给printf的参数的数量和类型与格式字符串中指示的完全匹配,并且顺序相同。

在你的代码中,因为你的格式字符串表明将传递一个整数,但你没有传递一个整数,你不能指望它能正确工作,它只是"未定义的行为"。

相关内容

  • 没有找到相关文章

最新更新