繁体   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);
}

运行上面的代码将产生以下错误

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

是的,订单绝对重要。

重新排序代码,使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

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

此错误和相关说明:

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

还有另一个选项-此更改也将解决此问题:

#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 *)而不是f(struct emp)-时,您可以定义f()而不包含结构布局的定义。 这是因为编译器可以使用指向已命名但未定义的结构的指针,前提是您仅对它们执行某些操作(存储它们,将它们返回,将它们传递给其他函数,将它们与NULL或与其他指针进行比较)。同样的事情...将它们强制转换为其他指针类型...)-但是您不能执行指针算术运算,也不能访问成员(显然),或者如果p是指向未指定结构的指针,则要求sizeof(* p)。 编译器会让您知道:-)

暂无
暂无

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

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