【问题标题】:accessing array through multiple functions通过多个函数访问数组
【发布时间】:2018-12-07 20:19:40
【问题描述】:

所以我正在用 C 语言创建一个小程序,但我遇到了一个我找不到任何相关解决方案的问题。 这是我的程序:我有一个数据数组。我有一个每秒填充这个数组的函数。所以我在main 中声明了这个数组,并将它传递给我的函数:

readDataLoop((uint16_t tableau []);

到目前为止一切顺利。一旦这个数组被填满,我就有一个函数:stateManager(state) 被调用。我没有将我的数组传递给这个函数。在这个函数中,我的状态管理器决定验证数据,所以我调用一个函数validateData() 来确定数组中的数据是否正确。

这是我的问题:我的函数 validateData 如何访问初始数组,因为我没有将它作为参数传递?

我可以做的是将数组作为参数传递给状态管理器,然后再次将数组传递给函数validateData(),但这会破坏我的逻辑。我希望我的状态管理器拥有的唯一参数就是状态。

我也可以将我的数组声明为全局变量,但我也在努力避免这种情况...

【问题讨论】:

  • 您需要将其作为参数传入,否则您将无法访问它。需要注意的另一件事是数组的大小未知,因此您可能需要第二个 size_t size 参数。
  • 不就是包含状态的数组吗?

标签: c arrays function pointers


【解决方案1】:

下面是一个快速示例,说明如何使用参数在函数之间传递数组、读取数据并对其进行验证。

请注意,读取数据和验证数据不需要对数据有任何概念,除了类型和大小。我已经传递了大小,但是 C 不能很好地处理不同的类型。您需要创建不同的函数来处理这个问题,使用常见的#define 类型,或者做一些奇怪的void * 和类型枚举类型的东西。 (C++ 有模板来处理这个问题...)

还请注意,这里确实没有状态管理器或其他任何东西,只有几个功能。如果你想建立一个真正的状态管理器,那么数据真的很想成为那个管理器的一部分。这又可以进入 C++ 领域,尽管 C 可以体面地做这种事情。

#include <stdio.h>

typedef int BOOL;
#define TRUE 1
#define FALSE 0

// Pass the data by reference and include the number of entries.
// This way we can modify the data.  In C, you almost always pass
// arrays this way as passing arrays by value isn't well supported.
void readData(int *myData, int numEntries)
{
    for(int i=0; i<numEntries; i++)
    {
        myData[i] = i;
    }
}

// validate the data - *myData here could/should be constant.
BOOL validateData(int *myData, int numEntries)
{
    for(int i=0; i<numEntries; i++)
    {
        if(myData[i] != i) 
        {
            return FALSE;
        }
    }
    return TRUE;
}

// Using C style defines for constants.  Newer compilers can do it safer.
#define NUM_ENTRIES 10
int main()
{
    int myData[NUM_ENTRIES];

    readData(myData, NUM_ENTRIES);
    if(!validateData(myData, NUM_ENTRIES))
    {
        printf("Bad Data\n");
    }
    else
    {
        printf("Good Data\n");
    }

    return 0;
}

我考虑过展示一个全局数组版本,但我反对它,因为它会促进非常糟糕的编码习惯,并且在这种情况下不需要。

【讨论】:

    【解决方案2】:

    我可以做的是将数组作为参数传递给状态管理器,然后再次将数组传递给函数 validateData() 但这会破坏我的逻辑。我希望我的状态管理器拥有的唯一参数就是状态。

    嗯,你有四个选择:

    1. 将数组设为全局变量,这样任何人都可以随时访问它。这是一个糟糕的主意。

    2. 将数组作为参数传递给状态管理器。你说这会破坏你的逻辑,但这没有意义——如果你的状态管理器当前没有使用数组,那么代码中的任何内容都不会因为你添加了一个参数而中断。

    3. 使数组成为传递给状态管理器的state 的一部分。这样可以避免添加您似乎不喜欢的参数,同时仍然允许状态管理器访问数组,并且不使用全局变量。

    4. 不要从stateManager() 调用validateData(),而是从你可以访问数组的地方调用。 (向 Tim Randall 致敬,他在下面的评论中提出了这个建议。)

    【讨论】:

    • 或者将数组设为 static 并将函数 readDataLoop()validateData() 限制为永远位于同一个源文件中。或者重构代码以便在不同的时间验证数组? (如果验证取决于当前状态,那么只需将数组与状态一起传递!)
    • 我将使用选项 1 包装静态变量,因为静态变量实际上只是一个访问受限的全局变量。重构是一个不错的选择——我会补充的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2019-07-08
    • 2011-09-06
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多