-1
#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技能的书说,程序中原型声明和结构声明的顺序无关紧要。我想问订单是否重要?

4

2 回答 2

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”的类型。编译器通常会尝试推断未知的默认类型和大小,struct emp并且几乎总是猜错,因为它不知道您最终将如何声明struct emp

这个错误:

hello2.c:10:2: error: type of formal parameter 1 is incomplete

表示您正在尝试使用与 gcc 在编译文件第 3 行时(错误地)推断的形式参数类型不同的实际参数类型调用函数“f”。

此错误和相关说明:

hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here

表示第 14 行的形参类型(现在已知是struct emp您在第 4 到第 7 行声明的类型)与 gcc 在第 3 行(再次错误地)推断的形参类型不匹配。

底线:在引用它们的原型之前定义所有类型,你应该没问题。

如果您使用,您可能还会发现您的代码更具可读性

typedef struct {
   char name[20];
   int  age;
} emp_t;

然后您可以使用emp_t而不是struct emp贯穿后续代码。

于 2013-07-13T05:47:55.030 回答
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() 而不包括结构布局的定义。这是因为编译器可以使用指向已命名但未定义的结构的指针 - 前提是您只对它们执行某些操作(存储它们、返回它们、将它们传递给其他函数;将它们与 NULL 或其他指向同样的事情......将它们转换为其他指针类型......) - 但是如果 p 是指向未指定结构的指针,则您不能进行指针算术或访问成员(显然)或要求 sizeof(*p) 。编译器会让你知道:-)

于 2013-12-06T00:18:21.687 回答