简体   繁体   English

声明顺序对结构无关紧要?

[英]Order of declaration does not matter for a struct?

#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);
}

Running the above code gives the following errors 运行上面的代码将产生以下错误

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

But the book test your C skills says that the order of prototype declaration and structure declaration in the program does not matter. 但是测试您的C技能的书说,程序中原型声明和结构声明的顺序无关紧要。 I want to ask whether the order matters or not? 我想问一下命令是否重要?

Yes the order absolutely does matter. 是的,订单绝对重要。

Re-order your code such that the definition of struct emp appears before the function prototype for f . 重新排序代码,使struct emp的定义出现在f的函数原型之前。

#include <stdio.h>
#include <stdlib.h>

struct emp{
  char name[20];
  int age;
};

void f(struct emp);

...

gcc is actually trying to tell you that you did things in the wrong order, however the compiler messages are a little bit confusing if this is your first time reading through them. gcc实际上试图告诉您您以错误的顺序执行了操作,但是,如果这是您第一次阅读它们,则编译器消息会有些混乱。

These two warnings: 这两个警告:

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]

indicate that the type of 'struct emp' was not known at the time gcc compiled line 3 of your file. 表示在gcc编译文件的第3行时不知道'struct emp'的类型。 The compiler will typically try to infer a default type & size for the unknown struct emp and almost always guesses incorrectly because it has no idea how you will eventually declare struct emp . 编译器通常会尝试为未知的struct emp推断默认类型和大小,并且几乎总是猜错了,因为它不知道最终将如何声明struct emp

This error: 这个错误:

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

indicates that you are trying to call function 'f' with an actual parameter type that is different than the formal parameter type that gcc (incorrectly) inferred when it compiled line 3 of the file. 表示您正在尝试使用实际参数类型调用函数'f',该参数类型与gcc编译文件的第3行时(错误地)推断出的形式参数类型不同。

This error and associated note: 此错误和相关说明:

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

indicates that the formal parameter type on line 14 (which is now known to be the type struct emp you declared on lines 4 through 7) did not match the formal parameter type that gcc (again incorrectly) inferred on line 3. 表示第14行的形式参数类型(现在是您在第4到7行中声明的struct emp类型)与gcc(再次错误地)在第3行中推断出的形式参数类型不匹配。

Bottom line: define all of your types before the prototypes that refer to them, and you should be fine. 底线:在引用所有原型的原型之前定义所有类型,您应该没事。

You may also find your code is more readable if you use 如果您使用以下代码,则可能还会发现代码更具可读性

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

And then you can use emp_t rather than struct emp throughout the subsequent code. 然后,您可以在整个后续代码中使用emp_t而不是struct emp

There's another option - this change will fix it too: 还有另一个选项-此更改也将解决此问题:

#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;
};

In a complex project it's not always easy to resolve all the ordering issues, this can be helpful. 在复杂的项目中,解决所有订购问题并不总是那么容易,这可能会有所帮助。

Note that when f is actually f(struct emp*) --not f(struct emp)- then you may be able to define f() without including a definition of the struct layout. 注意,当f实际上是f(struct emp *)而不是f(struct emp)-时,您可以定义f()而不包含结构布局的定义。 This is because the compiler can work with pointers to structs that are named, but not defined - provided you only do certain things to them (store them, return them, pass them to other functions; compare them to NULL, or to other pointers to the same thing... cast them to other pointer types...) - but you can't do pointer arithmetic, or access members (obviously) or ask for sizeof(*p) if p is a pointer to an unspecified struct. 这是因为编译器可以使用指向已命名但未定义的结构的指针,前提是您仅对它们执行某些操作(存储它们,将它们返回,将它们传递给其他函数,将它们与NULL或与其他指针进行比较)。同样的事情...将它们强制转换为其他指针类型...)-但是您不能执行指针算术运算,也不能访问成员(显然),或者如果p是指向未指定结构的指针,则要求sizeof(* p)。 The compiler will let you know :-) 编译器会让您知道:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM