DiB*_*sco 5 c variables static scope
我将绕圈试图找出如何实现需要由[.c]文件中的多个函数访问的变量.
我一直在使用Stack Exchange和其他谷歌搜索的线程,其中一般[但肯定不是一致的]共识似乎是文件范围的静态变量很好,但是,你应该传递变量(或者至少指针)变量)到功能,不只是有任何旧函数访问静态文件范围变量是在任何函数之外声明(即一个).有些人说文件范围的静态基本上与全局变量一样糟糕,但是如果没有文件范围的静态,则没有说明如何避免全局变量!
但是,在某些时候,即使从函数到函数传递指向文件范围的静态变量的指针,某些函数也必须最初访问该文件范围的静态变量.另外,我看不到一种方法,即.c文件中只有一个函数可以是访问该静态变量的唯一函数,因为并非所有需要静态变量的函数都会通过一个函数.
在我看来,你可以拥有一个除了保存静态变量之外什么都不做的函数,并返回一个指向该静态变量的指针.任何需要访问该变量的函数都会调用该函数,获取指向变量的指针并执行它需要对变量执行的操作.这种事:
struct PacketStruct* GetPacketStructPtr(void)
{
static struct PacketStruct Packet;
return &Packet;
}
Run Code Online (Sandbox Code Playgroud)
我看到有人在这里说,是的,单身工厂是如何建造的(无论是什么),它是完全有效的,但其他人说它很危险(但没有真正解释为什么它是危险的),其他人说这是不好的做法(我认为他们说效率很低,但今天我读得太多了,我可能错了.
那么,我想要确定的是:
文件范围变量可以吗?
如果是这样,假设让所有函数访问该文件范围的静态变量并且不将指针传递给它[静态文件范围的变量]似乎是错误的 - 尽可能使函数重用不同的变量 - 你能决定第一个需要访问文件范围静态的函数吗,然后将指针一直传递给其他函数?我真的很讨厌只访问文件范围的静态变量的代码外观,即使它似乎有点愚蠢地将指针传递给函数可以访问的东西.
如果文件范围的静态变量无效,假设这不是多线程的,只是嵌入式微程序上的run-to-complete程序,可以/我应该使用这种方式将指针传递给函数范围的静态变量到需要访问变量的任何其他函数?
如果不是上述情况,你究竟如何避免可怕的全局变量?这个不使用全局变量的问题在这里似乎已被解决了数十亿次,但没有任何具体的例子说明如何去做.在这里有很多相互矛盾的建议,更不用说在网络的其他部分了!
我强调这是单线程,不是重入,而且都相对简单.
希望这能让我更多地了解我正在尝试做的事情:
#include "work_order.h
// This is work_order.c
// Nothing outside of this file needs to access the WorkOrder struct
static struct WorkOrderStruct WorkOrder;
// Package up a work order - *data is a pointer to a complete serial package
int16_t CableConnectOrder(uint8_t *Data)
{
if (UnpackagePortInformation(&WorkOrder.PortA,&Data) == CARD_UID_NOT_FOUND)
return CARD_UID_NOT_FOUND;
if (UnpackagePortInformation(&WorkOrder.PortB,&Data) == CARD_UID_NOT_FOUND)
return CARD_UID_NOT_FOUND;
AddNewKeysToWorkOrder(&WorkOrder,Data);
WorkOrder.WorkOrderType = CONNECT_CABLE_REQUEST;
WorkOrder.Flags.SingleEndedConnection = FALSE_BIT;
WorkOrder.Flags.PortACableRemoveRequest = FALSE;
WorkOrder.Flags.PortBCableRemoveRequest = FALSE;
return ConstructCableOrderRequest(&WorkOrder);
}
int16_t ConstructCableOrderRequest(struct WorkOrderStruct *WorkOrder)
{
// This function is accessed by other Work Order requests and does the rest of the // packaging of the work order
// It can also pass the work order information further down
DoOtherStuff(WorkOrder); // Kind of further passing that might happen
}
int16_t CheckAdditionalInfoAgainstWorkOrder(struct WorkOrderPortUpdateStruct *Update)
{
// Compare connection information against the previously set-up work order
// Needs to access the static WorkOrder structure as well. Also, can call other
// functions that needs to access the static function
WorkOrder.Foo = Update->bar;
DoYetMoreOtherStuff(&WorkOrder); // This is not real code, but the general kind of idea
}
Run Code Online (Sandbox Code Playgroud)
有关您正在做的事情的更多信息将会有所帮助。我经常进行嵌入式系统编程,其中由于中断,全局/文件范围的静态是绝对必须的。如果这就是你正在做的事情——那就去做吧。
回复:创建变量并将指针传递给所有其他函数的单个函数...您的“单个函数”将是 main 。我经常会像这样创建代码......
struct PacketStruct {
char name[128];
uint8_t age;
float bac;
}
void setup (PacketStruct *packetStruct, ...);
void foo (PacketStruct *parameter);
void bar (PacketStruct *parameter);
int main (void) {
PacketStruct ps;
// Initialize all variables"
setup(&ps);
// Run program
foo(&ps);
bar(&ps);
return 0;
}
void setup (PacketStruct *packetStruct, ...) {
strcpy(packetStruct->name, "Squidward");
packetStruct->age = 16;
packetStruct->bac = 0.11;
}
Run Code Online (Sandbox Code Playgroud)
我喜欢它,因为ps它不是全局变量,您不必动态分配内存(尽管您可以轻松地这样做),并且它可以在所有函数中访问。
同样,如果您发布完整的代码(或显示其使用方式的片段),我们也许可以为您提供一些特定于应用程序的建议。
-编辑- 既然你提到了文件范围,我猜这意味着你没有在与 main 相同的文件中使用这个变量。在这种情况下,我的子文件将具有如下功能filename_init(...):
/* File: FooBar.c
*/
#include "FileWithPacketStructAndOtherCoolThings.h"
// "g_" sits in front of all global variables
// "FooBar_" sits in front of all file-wide statics
static PacketStruct g_FooBar_ps;
FooBar_init(void) {
strcpy(g_ps->name, "Squidward");
g_ps->age = 16;
g_ps->bac = 0.11;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
511 次 |
| 最近记录: |