C 函数声明的顺序

C 函数声明的顺序,c,function,prototype,declaration,C,Function,Prototype,Declaration,下面是一个示例代码,它类似于我遇到的一个问题 #include <stdio.h> int cube_then_square(int x){ x = cube(x); return x*x; } int cube(int y){ return y*y*y; } int main(int argc, char *argv[]){ printf("5 cubed then

下面是一个示例代码,它类似于我遇到的一个问题

    #include <stdio.h>

    int cube_then_square(int x){
        x = cube(x);
        return x*x;
    }

    int cube(int y){
        return y*y*y;
    }

    int main(int argc, char *argv[]){
        printf("5 cubed then squared is: %d\n", cube_then_square(5));
        return 0;
    }
#包括
整数立方_然后_平方(整数x){
x=立方体(x);
返回x*x;
}
整数立方体(整数y){
返回y*y*y;
}
int main(int argc,char*argv[]){
printf(“5立方然后平方是:%d\n”,立方然后平方(5));
返回0;
}

所以编译器给了我一个立方体未声明的问题。那么,有人能解释一下这些函数在内存中的顺序吗,等等……以及它与将原型放在上面和在main之后实现有什么不同。谢谢。

编译器从上到下读取文件。当它到达函数时,它检查是否已经知道它。在本例中,它没有看到函数
cube(int)
,因此返回一个错误

你可以做两件事: 1.将函数
cube
移动到函数
cube\u之前,然后再移动正方形
。 2.在
cube\u然后\u square
之前创建转发声明:

int cube(int y);

编译器从上到下读取文件。当它到达函数时,它检查是否已经知道它。在本例中,它没有看到函数
cube(int)
,因此返回一个错误

你可以做两件事: 1.将函数
cube
移动到函数
cube\u之前,然后再移动正方形
。 2.在
cube\u然后\u square
之前创建转发声明:

int cube(int y);

在文件顶部的includes下,添加
intcube(inty)


在使用函数之前,必须先声明它。它还不需要定义,但在使用之前必须声明,因为编译器会按顺序检查行。

在文件顶部的includes下,添加
intcube(inty)


在使用函数之前,必须先声明它。它还不需要定义,但在使用之前必须声明,因为编译器会按顺序检查行。

要解决此问题,您可以在使用多维数据集之前声明它:

#include <stdio.h>

int cube(int y){
    return y*y*y;
}

int cube_then_square(int x){
    x = cube(x);
    return x*x;
}

int main(int argc, char *argv[]){
    printf("5 cubed then squared is: %d\n", cube_then_square(5));
    return 0;
}

要解决此问题,您可以在使用多维数据集之前声明它:

#include <stdio.h>

int cube(int y){
    return y*y*y;
}

int cube_then_square(int x){
    x = cube(x);
    return x*x;
}

int main(int argc, char *argv[]){
    printf("5 cubed then squared is: %d\n", cube_then_square(5));
    return 0;
}

隐式声明函数的警告是存在的,因为大多数现代C程序不使用隐式函数

#include <stdio.h>

cube1(int x){return x*x*x;}
main(){float y = 9.; printf("%d\n%d\n", cube1(y), cube2(y));}
cube2(int x){return x*x*x;}
旧的C89允许隐式声明所有内容。调用函数时,它会隐式声明为
int func()
。 这在这种情况下起作用,因为您隐式声明函数
int cube()
,并使用以下行:

x = cube(x);
然后定义函数
intcube(int)
intcube()
intcube(int)
具有兼容的类型,因此这是一个很好的调用

您真正遇到的问题是从隐式声明的函数调用不兼容的函数(这就是警告存在的真正原因)
intcube(float)
是一种不兼容的函数类型,它肯定存在,如果使用隐式声明的函数调用它,可能会出现一些非常奇怪的效果(读取未定义)。正如mafso所提到的,严格的C99不再允许隐式声明函数,这就是为什么许多编译器都会包含警告

请记住,隐式声明函数是一种不好的做法,但您应该知道这种情况下的存在

这里有一个小程序来演示隐式声明函数的弱点。它利用了c程序中的一些转换规则,这些规则会随着隐式声明的函数而突然消失

#include <stdio.h>

cube1(int x){return x*x*x;}
main(){float y = 9.; printf("%d\n%d\n", cube1(y), cube2(y));}
cube2(int x){return x*x*x;}
这些功能在asm中是相同的

00000000004004dc <cube1>:
  4004dc:   55                      push   %rbp
  4004dd:   48 89 e5                mov    %rsp,%rbp
  4004e0:   89 7d fc                mov    %edi,-0x4(%rbp)
  4004e3:   8b 45 fc                mov    -0x4(%rbp),%eax
  4004e6:   0f af 45 fc             imul   -0x4(%rbp),%eax
  4004ea:   0f af 45 fc             imul   -0x4(%rbp),%eax
  4004ee:   5d                      pop    %rbp
  4004ef:   c3                      retq   
0000000000400540 <cube2>:
  400540:   55                      push   %rbp
  400541:   48 89 e5                mov    %rsp,%rbp
  400544:   89 7d fc                mov    %edi,-0x4(%rbp)
  400547:   8b 45 fc                mov    -0x4(%rbp),%eax
  40054a:   0f af 45 fc             imul   -0x4(%rbp),%eax
  40054e:   0f af 45 fc             imul   -0x4(%rbp),%eax
  400552:   5d                      pop    %rbp
  400553:   c3                      retq  
0000000000 4004DC:
4004dc:55%推送rbp
4004dd:48 89 e5 mov%rsp,%rbp
4004e0:89 7d fc mov%edi,-0x4(%rbp)
4004e3:8b 45 fc mov-0x4(%rbp),%eax
4004e6:0f af 45 fc imul-0x4(%rbp),%eax
4004ea:0f af 45 fc imul-0x4(%rbp),%eax
4004ee:5d pop%rbp
4004ef:c3 retq
0000000000400540 :
400540:55%按需付费
400541:48 89 e5 mov%rsp,%rbp
400544:89 7d fc mov%edi,-0x4(%rbp)
400547:8b 45 fc mov-0x4(%rbp),%eax
40054a:0f af 45 fc imul-0x4(%rbp),%eax
40054e:0f af 45 fc imul-0x4(%rbp),%eax
400552:5d pop%rbp
400553:c3 retq

但是在调用站点,隐式调用从未执行从浮点到整数的预期转换。

隐式声明函数的警告存在,因为大多数现代C程序不使用隐式函数

#include <stdio.h>

cube1(int x){return x*x*x;}
main(){float y = 9.; printf("%d\n%d\n", cube1(y), cube2(y));}
cube2(int x){return x*x*x;}
旧的C89允许隐式声明所有内容。调用函数时,它会隐式声明为
int func()
。 这在这种情况下起作用,因为您隐式声明函数
int cube()
,并使用以下行:

x = cube(x);
然后定义函数
intcube(int)
intcube()
intcube(int)
具有兼容的类型,因此这是一个很好的调用

您真正遇到的问题是从隐式声明的函数调用不兼容的函数(这就是警告存在的真正原因)
intcube(float)
是一种不兼容的函数类型,它肯定存在,如果使用隐式声明的函数调用它,可能会出现一些非常奇怪的效果(读取未定义)。正如mafso所提到的,严格的C99不再允许隐式声明函数,这就是为什么许多编译器都会包含警告

请记住,隐式声明函数是一种不好的做法,但您应该知道这种情况下的存在

这里有一个小程序来演示隐式声明函数的弱点。它利用了一些对流的优势