2010-04-12 118 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加上一个偏移量;易于调试(您可以在“打印”中看到所有参数);地点(很好地缓存);很容易变成一个可堆叠的调用集,在那里你不容易知道堆栈中可能需要的任何给定函数的参数。

缺点包括:通过查看函数调用哪些参数对被调用者很重要 - 您必须知道,或者在该函数的源代码中挖掘;引起副作用更容易,特别是允许被调用的函数修改块(坏,坏,坏!);增加耦合(每个函数都可以看到每个参数,这会导致诱惑...)