2010-04-12 115 views
5

我正在研究具有不同輸出能力(數字輸出,串行,模擬等)的嵌入式系統。我試圖找出一個乾淨的方式來傳遞許多控制這些函數的變量。我不需要太頻繁地傳遞它們,但我希望有一個函數可以讀取輸入數據(在這種情況下是從TCP網絡),然後解析數據(IE,第3個字節包含8個數字輸出的狀態(根據該字節中的哪個位爲高或低)),並將其放入一個變量中,然後我可以在程序中的其他位置使用該變量。我想要這個函數與main()函數分開,但要這樣做需要將指針傳遞給它將要寫入的大約20個左右的變量。我知道我可以使變量成爲全局變量,但是我試圖通過將變量傳遞給函數來允許函數被允許編輯該變量,從而使它更易於調試。如何將多個變量傳遞給C中的函數?

我最好的想法是一個結構,只是傳遞一個指針,但不知道是否有更有效的方法,特別是因爲只有一個函數需要一次訪問所有它們,而大多數其他人只需要將存儲在這堆狀態變量中的部分信息。

因此無論如何,有沒有一種乾淨的方式來發送一次需要編輯的函數之間的許多變量?

+0

你知道'struct',對嗎? – Javier 2010-04-12 21:37:24

回答

5

使用帶有指針的結構是一個很好的選擇。代碼可能會稍微長一些,但它看起來不錯。你可以通過值傳遞一個結構體,但通過引用將避免複製數據。

另一種選擇是創建一個由結構體組成的結構體。然後,您可以通過傳遞整個東西(其中只有一個或兩個)或結構的單個元素來更加有選擇性地傳遞給每個函數的數據。

typedef struct a { 
    struct b { 
    int b1; 
    int b2; 
    } b_s; 
    struct c { 
    int c1; 
    int c2; 
    } c_s; 
} a_s; 
0

我會說結構是你最好的選擇。如果您不需要特定函數中的所有變量,則可以選擇僅將其中一個成員傳遞給函數。如果您需要設置各個位,您可能也會從第3個字節的位域中受益。當然,這個位域也可以是你的struct的成員。

0

我會做的是寫他們都接受結構。程序運行後如果效率問題應該很容易返回並更改那些只使用一個或兩個變量的函數,只接受變量作爲參數。

0

將指針傳遞給結構通常是「乾淨」的方式。智能地定義數據結構可以爲這種方法提供強大的功能和靈活性。例如採取數據結構:

struct func_params { 
    int type; 
    union { 
     struct { 
      int port; 
      int direction; 
      long target_addr; 
     } digital_io; 
     struct { 
      int channel; 
      long sample_rate; 
     } analog_in; 
     struct { 
      int channel; 
      int async; 
      int hold_output; 
     } analog_out; 
     struct { 
      int port; 
      int direction; 
      int encoding; 
     } serial_io; 
    }; 
}; 

的東西定義你的函數一樣

my_function (struct func_params* pStruct, size_t length) 

當使用功能,首先要創建一個緩衝區足夠大,以包含數據結構以及任何潛在變量的大小將要發送給函數的長度數據(例如,發送端口的數據)。數據緩衝區的第一部分將由您定義的結構組成。緩衝區的其餘部分(length-sizeof(struct func_params)字節)將是您存儲數據的位置。您的函數讀取type結構成員,並確定如何解釋結構的其餘部分,並在處理結構後確定如何解釋可變長度數據部分。

這可能比您想象的要多一點。在嵌入式世界中,許多通信協議(例如SCSI)通過發送一個頭部,然後是像這樣的可變長度數據部分進行通信。它給函數提供了一個乾淨的界面,很好地將相關信息捆綁在一起,並且使得將來更改函數更容易,而無需更改調用參數。

2

這是一個「參數塊」的經典用法 - 只是一個指向着名結構的指針。

好處包括:高效,因爲對給定參數的任何訪問都是一個adderess加上一個偏移量;易於調試(您可以在「打印」中看到所有參數);地點(很好地緩存);很容易變成一個可堆疊的調用集,在那裏你不容易知道堆棧中可能需要的任何給定函數的參數。

缺點包括:通過查看函數調用哪些參數對被調用者很重要 - 您必須知道,或者在該函數的源代碼中挖掘;引起副作用更容易,特別是允許被調用的函數修改塊(壞,壞,壞!);增加耦合(每個函數都可以看到每個參數,這會導致誘惑...)