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不再允许隐式声明函数,这就是为什么许多编译器都会包含警告
请记住,隐式声明函数是一种不好的做法,但您应该知道这种情况下的存在
这里有一个小程序来演示隐式声明函数的弱点。它利用了一些对流的优势