2010-04-14 34 views
28

Tôi đang thực hiện một trò chơi bài trong C. Có rất nhiều loại thẻ và mỗi loại có một loạt thông tin, bao gồm một số hành động cần phải được viết riêng lẻ liên kết với nó.Khởi tạo Static Array of Structs trong C

Cho một struct như thế này (và tôi không chắc chắn tôi phải đúng cú pháp cho các con trỏ hàm)

struct CARD { 
    int value; 
    int cost; 
    // This is a pointer to a function that carries out actions unique 
    // to this card 
    int (*do_actions) (struct GAME_STATE *state, int choice1, int choice2); 
}; 

Tôi muốn khởi tạo một mảng tĩnh trong số này, một cho mỗi thẻ. Tôi đoán điều này sẽ giống như thế này

int do_card0(struct GAME_STATE *state, int choice1, int choice2) 
{ 
    // Operate on state here 
} 

int do_card1(struct GAME_STATE *state, int choice1, int choice2) 
{ 
    // Operate on state here 
} 

extern static struct cardDefinitions[] = { 
    {0, 1, do_card0}, 
    {1, 3, do_card1} 
}; 
  1. Sẽ làm việc này, và tôi sẽ về vấn đề này một cách đúng đắn ở tất cả? Tôi đang cố gắng tránh số lượng lớn các câu lệnh chuyển đổi.

  2. Tôi có cần định nghĩa các hàm 'do_cardN' trước hay không, hoặc có cách nào đó để xác định nội tuyến trong khởi tạo cấu trúc (ví dụ như hàm lambda trong python) không?

  3. Tôi cần quyền truy cập chỉ đọc vào thẻDefinitions từ một tệp khác - là 'extern static' có đúng không?

Tôi biết đây là rất nhiều câu hỏi được cuộn thành một nhưng tôi thực sự mơ hồ về cách thực hiện điều này.

Cảm ơn.

Edit:

Để được rõ ràng, mục tiêu của tôi là để có thể làm điều gì đó như

int cost = cardDefinitions[cardNumber].cost; 

hoặc

int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2); 

Thay vì sử dụng báo cáo chuyển đổi rất lớn ở khắp mọi nơi.

Trả lời

33

Cách tiếp cận của bạn là chính xác.

  1. này sẽ làm việc, và là một cách tốt để tránh switch báo cáo khổng lồ.
  2. Bạn không thể xác định hàm nội tuyến trong C, chúng phải có tên duy nhất.
  3. extern là những gì bạn muốn, chứ không phải static. Thay đổi cơ thể của bạn sẽ được này:

    struct CARD cardDefinitions[] = { 
        {0, 1, do_card0}, 
        {1, 3, do_card1} 
    }; 
    

    sau đó trong một tập tin tiêu đề thích hợp:

    extern struct CARD cardDefinitions[]; 
    
+3

Bạn có thể có các hàm "nội tuyến" trong C. Từ bạn đang tìm kiếm là "các hàm ẩn danh". Hơn nữa, tôi sẽ thêm {0, 0, NULL} làm phần tử cuối cùng của mảng, do đó bạn không cần phải lưu trữ kích thước của nó một cách riêng biệt. – Philip

+0

@Philip Vâng, những "nội tuyến" đó hoàn toàn không liên quan đến những gì anh ấy nói, nhưng có, bạn nói đúng. Và tôi thích "sizeof (cardDefinitions)/sizeof (cardDefinitions [0])" lừa cho các trường hợp như thế này –

+0

@Michael: Thủ thuật này không hoạt động nếu bạn khai báo "extern struct CARDDefinitions [];". – Philip

1
  1. Điều đó sẽ hoạt động tốt. Có vẻ như bạn có rất nhiều chức năng nếu bạn làm một thẻ cho mỗi thẻ, nhưng có thể trò chơi cụ thể này yêu cầu cấp độ kiểm soát đó

  2. Bạn không thể xác định nội tuyến, nhưng bạn có thể thực hiện tờ khai.Bạn cần phải thực hiện &func_name trong quá trình khởi tạo cấu trúc mặc dù

  3. Không; extern có nghĩa là một biến được khai báo trong một tệp khác, do đó, không có ý nghĩa gì khi có một biến ngoài mà bạn đang khai báo tại vị trí đó. Ngoài ra, static có nghĩa là biến chỉ có thể truy cập từ tệp hiện tại, điều này ngược lại với những gì bạn muốn. Tỉ số giờ là read-only sẽ đòi hỏi một hàm getter, nhưng nếu bạn chỉ muốn làm cho nó truy cập từ một tập tin khai báo nó thường ở đây (struct cardDefinitions[] = {...}) và trong các tập tin khác sử dụng một extern (extern struct cardDefinitions[];)

+3

Bạn không cần phải thực hiện '& func_name'. Hoặc 'func_name' hoặc' & func_name' là tốt (tên hàm trống được chuyển thành con trỏ tới hàm, analagous đến cách một tên mảng trống được chuyển thành con trỏ thành phần tử đầu tiên của mảng). – caf

+2

1. Vâng, trò chơi ("Dominion") là khá vô lý như vậy 2. Cảm ơn bạn đã làm rõ bit extern, mà làm cho rất nhiều ý nghĩa hơn. Cách tiếp cận của tôi chỉ là ném từ khóa vào nó cho đến khi nó hoạt động ... –

+0

Oh wow, tôi thực sự bắt đầu thực hiện trò chơi đó một thời gian trước, nhưng quyết định nó có thể sẽ không gần như vui vẻ như IRL. Bạn có thể không cần các chức năng riêng biệt cho mỗi thẻ, bạn chỉ có thể xác định thuộc tính cho số tiền mà thẻ mang lại cho bạn, số lượng thẻ bạn kiếm được, số lượng mua và hành động bạn nhận được và số lượng VP có giá trị và sẽ bao gồm hầu hết các trường hợp –

2

cách tiếp cận của bạn là đúng và sẽ làm việc. Cú pháp con trỏ hàm của bạn là đúng, ngoại trừ việc bạn không sử dụng tên tham số - chỉ cần gõ:

int (*do_actions)(struct GAME_STATE *, int, int); 
Các vấn đề liên quan