簡體   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