C语言中fun1()和fun2(void)的区别

在一次C语言实训中我发现老师在对无参函数的书写中写成fun2(void)的形式,这引起了我的好奇心,我只知道fun1()和fun2(void)是两个无参函数,后者是C99中规定的,void的意思就是该函数不接受任何参数,但是我在使用的过程中除了对fun2传参会导致报错以外没有发现别的问题,所以就开始好奇为什么老师在实训时会特意在没有传参的函数里写上void。

经过谷歌搜索得到以下结论

(C) The difference between int main() and int main(void)

A common misconception for C programmers, is to assume that a function prototyped as follows takes no arguments:

int foo();

In fact, this function is deemed to take an unknown number of arguments. Using the keyword void within the brackets is the correct way to tell the compiler that the function takes NO arguments.

参考文章:https://faq.cprogramming.com/...

但是我还是不能理解到底为什么要这样定义,最后在抖音的一个博主(抖抖代码)那里得到了解答

以下是博主演示的代码:

#include
int main(void){
    void fun1();
    void fun2(void);
    fun1();
    fun2();
    return 0;
}
void fun1(){
    printf("doudou \n");
}
void fun2(){
    printf("douodu 2\n");
}
/*
得到输出为:
doudou 
douodu 2
*/

在没有传入任何参数的情况下两者都是被正常运行的。

但是如果对fun1和fun2分别进行传参,其结果如下

//fun1
#include
int main(void){
    void fun1();
    void fun2(void);
    fun1(888,999);
    // fun2();
    return 0;
}
void fun1(){
    printf("doudou \n");
}
void fun2(){
    printf("douodu 2\n");
}
//输出为
//doudou
#include
int main(void){
    void fun1();
    void fun2(void);
    // fun1(888,999);
    fun2(888,999);
    return 0;
}
void fun1(){
    printf("doudou \n");
}
void fun2(){
    printf("douodu 2\n");
}
/*输出为
test.c:20:5: error: too many arguments to function 'fun2'
     fun2(888,999);
     ^~~~
test.c:18:10: note: declared here
     void fun2(void);
 */

由此得出,在对fun1()和fun2(void)传参时,fun2会直接报错中断程序的运行。如果不含参的函数不带void并进行传参的话,表面上不会有任何影响,但是在Linux或者Unix平台中函数的参数会被推入堆栈中,所以只要读取参数所推入的寄存器便可获得传入的参数

#include 
int main(void)
{
    void fun1();
    fun1(888, 999);
    return 0;
}
void fun1()
{
    register int sp1 asm("di"); //关联第一个参数
    register int sp2 asm("si"); //关联第二个参数
    printf("%d,%d", sp1, sp2);
}

C语言中fun1()和fun2(void)的区别_第1张图片

C语言中fun1()和fun2(void)的区别_第2张图片

研究这个问题花费了我三个小时,三个小时的时间也许可以让我学完一种特性或者几个语法糖,但是对这个小细节的求解却让我乐在其中。编程的魅力让我无法自拔。

你可能感兴趣的:(c)