【问题标题】:How does the following function definition work?以下函数定义如何工作?
【发布时间】:2012-01-17 07:25:37
【问题描述】:
#include <stdio.h>
void main() {
    extern int fun(float);
    int a=fun(3.5);
    printf("%d",a);
}

int fun(aa)
float aa;
{
    return ((int)aa);
}

上面提到的代码块在我的 Visual Studio 8 编译器上编译得很好,尽管输出是一个垃圾值。但是当我在 gcc-4.3.4 上编译相同的代码时,我得到了以下编译错误:

prog.c:2:警告:“main”的返回类型不是“int”
prog.c:8:错误:“有趣”的类型冲突
prog.c:3: 错误:之前的‘fun’声明在这里

当它具有以下属性时它将如何工作:

  1. 在函数体开始之前有一个变量声明。
  2. 函数定义没有变量的参数类型。

【问题讨论】:

  • 这是旧的 C 函数声明。看看:stackoverflow.com/questions/4581586/…
  • 我认为这个问题没有任何问题,为什么这被投票支持关闭,因为它没有建设性? OP 问的 Q 有一个明确的内容,如果你不理解 Q,你无权决定它是否具有建设性,所以不要这样做。这充其量可能是重复的,但没有一票接近。
  • 我同意@als 的观点,这似乎是一个合理的问题,并有一个很好的详细接受的答案。

标签: c


【解决方案1】:

这是函数定义的K & R style。它不符合标准,因此 gcc 中的编译器错误(由 Ideone 使用)。

它适用于 Visual Studio,因为 Visual Studio 允许您更改默认编码样式。

【讨论】:

    【解决方案2】:

    函数是用 K&R 风格编写的,你的原型不正确。其实还有其他问题……

    #include <stdio.h>
    void main() {
        extern int fun(float);
        int a=fun(3.5);
        printf("%d",a);
    }
    
    int fun(aa)
    float aa;
    {
        return ((int)aa);
    }
    

    main() 的返回类型是int,至少在标准 C 中是这样。您的打印语句应该包含换行符。

    如果函数fun() 是用原型编写的,你的原型就可以了:

    int fun(float aa) { ... }
    

    但是,该函数是用 K&R 风格编写的,因此该函数需要传递一个 double,它将转换为 float

    int fun(double aa_arg) { float aa = aa_arg; ... }
    

    在 K&R C 中,所有 float 值都作为 double 传递。这就是你得到垃圾的原因;你对你的编译器撒谎(可能是在不知情的情况下),它通过对你执行 GIGO 得到了自己的回报。

    FWIW:GCC 4.6.1 拒绝编译您的代码(即使没有任何警告设置)。它抱怨:

    f1.c: In function ‘main’:
    f1.c:2: warning: return type of ‘main’ is not ‘int’
    f1.c: At top level:
    f1.c:9: error: conflicting types for ‘fun’
    f1.c:3: error: previous declaration of ‘fun’ was here
    

    您可以通过多种不同方式解决此问题:

    #include <stdio.h>
    int main(void)
    {
        extern int fun(float);
        int a = fun(3.5);
        printf("%d\n", a);
        return(0);
    }
    
    int fun(float aa)
    {
        return ((int)aa);
    }
    

    或者:

    #include <stdio.h>
    int main(void)
    {
        extern int fun(double);
        int a = fun(3.5);
        printf("%d\n", a);
        return(0);
    }
    
    int fun(double aa)
    {
        return ((int)aa);
    }
    

    或者:

    #include <stdio.h>
    int main(void)
    {
        extern int fun(double);
        int a = fun(3.5);
        printf("%d\n", a);
        return(0);
    }
    
    int fun(aa)
    double aa;
    {
        return ((int)aa);
    }
    

    或者:

    #include <stdio.h>
    int main(void)
    {
        extern int fun(double);
        int a = fun(3.5);
        printf("%d\n", a);
        return(0);
    }
    
    int fun(aa)
    float aa;
    {
        return ((int)aa);
    }
    

    或者:

    #include <stdio.h>
    int main(void)
    {
        extern int fun();
        int a = fun(3.5);
        printf("%d\n", a);
        return(0);
    }
    
    int fun(aa)
    float aa;
    {
        return ((int)aa);
    }
    

    我相信这些都是正确的,它们都应该在没有警告的情况下编译(除非您要求编译器抱怨旧式 (K&R) 函数定义等)。

    将 GCC 设置为相当繁琐,我收到警告:

    /usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f2.c -o f2  
    f2.c:12: warning: no previous prototype for ‘fun’
    /usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f3.c -o f3  
    f3.c:12: warning: no previous prototype for ‘fun’
    /usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f4.c -o f4  
    f4.c:12: warning: function declaration isn’t a prototype
    f4.c: In function ‘fun’:
    f4.c:13: warning: old-style function definition
    /usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f5.c -o f5  
    f5.c:12: warning: function declaration isn’t a prototype
    f5.c: In function ‘fun’:
    f5.c:13: warning: old-style function definition
    /usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition f6.c -o f6  
    f6.c: In function ‘main’:
    f6.c:5: warning: function declaration isn’t a prototype
    f6.c: At top level:
    f6.c:12: warning: function declaration isn’t a prototype
    f6.c: In function ‘fun’:
    f6.c:13: warning: old-style function definition
    

    【讨论】:

    • 嗨,这就是我所理解的 - 所以在 K&R C 中,我们不能声明一个函数来接收浮点数据类型(或整数系列中的 short、char),因为它们被提升为 double 和 int,为了克服这个我们正在使用 ANSI C 标准,我们可以期望浮点数作为参数:int fun(float aa)。如果我错了,请纠正我。谢谢
    猜你喜欢
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多