#include <stdio.h>
#include <stdlib.h>
void f(struct emp);
struct emp{
char name[20];
int age;
};
int main(){
struct emp e = {"nikunj", 23} ;
f(e);
return 0;
}
void f(struct emp e){
printf("%s %d\n", e.name, e.age);
}
运行上面的代码会出现以下错误
nikunjbanka@ubuntu:~$ gcc hello2.c -o main.out
hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
hello2.c: In function ‘main’:
hello2.c:10:2: error: type of formal parameter 1 is incomplete
hello2.c: At top level:
hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here
但本书测试你的C技能说明程序中原型声明和结构声明的顺序并不重要。我想问一下订单是否重要?
答案 0 :(得分:4)
是的,订单绝对重要。
重新排序您的代码,使struct emp
的定义出现在f
的函数原型之前。
#include <stdio.h>
#include <stdlib.h>
struct emp{
char name[20];
int age;
};
void f(struct emp);
...
gcc实际上是在试图告诉你,你做的事情的顺序是错误的,但如果这是你第一次阅读它们的话,编译器的消息会有点混乱。
这两个警告:
hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
表示在gcc编译文件的第3行时,'struct emp'的类型是未知的。编译器通常会尝试推断默认类型&amp;未知struct emp
的大小,几乎总是猜错,因为它不知道你最终会如何宣告struct emp
。
此错误:
hello2.c:10:2: error: type of formal parameter 1 is incomplete
表示你试图调用函数'f',其实际参数类型与编译文件第3行时gcc(错误)推断的形式参数类型不同。
此错误及相关注释:
hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here
表示第14行的形式参数类型(现在已知为第4行到第7行声明的类型struct emp
)与gcc(再次错误地)在线推断的形式参数类型不匹配3。
底线:在引用它们的原型之前定义所有类型,你应该没问题。
如果您使用
,您可能还会发现您的代码更具可读性typedef struct {
char name[20];
int age;
} emp_t;
然后,您可以在后续代码中使用emp_t
而不是struct emp
。
答案 1 :(得分:0)
还有另一种选择 - 这种改变也会解决它:
#include <stdio.h>
#include <stdlib.h>
struct emp; /* <--- add this line */
void f(struct emp); /* <-- now this refers to that */
struct emp{ /* <-- and this defines the same thing */
char name[20]; /* and you didn't need to move things around. */
int age;
};
在复杂的项目中,解决所有订购问题并不总是很容易,这可能会有所帮助。
注意,当f实际上是f(struct emp *) - not f(struct emp) - 那么你可以定义f()而不包括struct layout的定义。 这是因为编译器可以使用指向已定义但尚未定义的结构的指针 - 前提是您只对它们执行某些操作(存储它们,返回它们,将它们传递给其他函数;将它们与NULL进行比较,或者与其他指针进行比较)同样的事情......将它们转换为其他指针类型...) - 但是如果p是指向未指定结构的指针,则不能进行指针运算,或访问成员(显然)或者请求sizeof(* p)。编译器会通知你: - )