【问题标题】:static member(2d array) of structure (2d array) in CC中结构(二维数组)的静态成员(二维数组)
【发布时间】:2016-07-27 02:13:40
【问题描述】:

我有一个关于结构的静态成员的问题 这是场景:

  • 即使从另一个 C 文件中的函数退出后,也需要二维数组变量来保留其值。从 main() 到另一个 C 文件的后续调用,对该函数的调用将使用最后一个值并继续进行计算以生成和更新新值(也保留)。所以,我认为我需要为该数组使用静态。

  • 二维数组是二维结构的成员。我需要二维结构来识别二维数组。假设我用成员 [5] [5] 获得了身份 [行] [列],我需要在 main() 的整个调用过程中静态定义成员。但我注意到,C 中不允许结构成员的静态。

我正在尝试的代码:

//in function.h

 #define row 2
 #define column 5
 int function(int rowNUM);

  //in function.c
int function(int rowNUM)
{
typedef struct {
    static int member[5][5];
    int y[5][5];
    int forg;
} mystruct;

mystruct identity[row][column];// declare the identity as structure array

int columnNUM;
int c;
int d;

//----try to initialize member to 1
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
   {
for(d=0;d<5;d++){
   identity[rowNUM][columnNUM].member[c][d]=1;
       }
    }
}


//----try to update member--- The values should retain for subsequent call from main
for (columnNUM=0;columnNUM<column;columnNUM++)
{
for (c=0;c<5;c++)
   {
for(d=0;d<5;d++){
   identity[rowNUM][columnNUM].member[c][d]=1+identity[rowNUM][columnNUM].member[c][d]; // to update member new value
       }
    }
}
}


// in main.c

main()
{
function(1);
function(2);// member here is in different identity from function (1)
function(1);//member should retain its value from function(1)
function(2);//member should retain its value from function(2)
}

如果这不是实现目标的方式,欢迎提出任何其他建议。 我是编程新手,请帮帮我。

【问题讨论】:

    标签: c


    【解决方案1】:

    您已经定义了一个二维结构数组,它很难静态初始化,因为每个结构都包含整数矩阵。此外,您不能只拥有一个静态结构的成员,必须将整个结构定义为静态。

    我能想到的最简单的方法是定义一个 mystructs 的静态矩阵和一个辅助变量,以便在第一次调用时对其进行初始化,即,

    //in function.c
    #include <stdbool.h>
    
    int function(int rowNUM)
    {
        typedef struct {
            int member[5][5];
            int y[5][5];
            int forg;
        } mystruct;
    
        // helper flag    
        static bool first_call = true;
    
        // this is a matrix of (row x cols) mystructs
        static mystruct identity[row][col];
    
        if (first_call) {
            /* initialize the matrix however you want
               BUT remember to set first_call to false!
            */
            first_call = false;
        }
    
        // rest of function ...
    }
    

    如果您不想保留 y 和 forg 成员的值(forg 代表什么?是错字吗?),您应该将结构一分为二,但我不能看看为什么要保留结构的某些值并丢弃其他值,除非它们是时间变量。

    如果y 和forg 是时间变量,您绝对应该将您的结构定义一分为二。

    另一种方法是将指向矩阵的指针作为参数传递给您的函数,这样您就可以在不使用静态变量的情况下保持状态

    int function(int rowNUM, mystruct **identity)
    

    但请注意,尽管大多数时候数组衰减为指针(您可以在与this one 类似的问题中找到更多信息),但它们与thing 不同。

    【讨论】:

    • 实际上我想对一系列拥有自己属性(结构成员)的对象(结构的二维数组)进行分组,其中一些是矩阵(这就是二维数组成员的原因)需要为后续调用保留它们的值,有些是常量,有些是时间变量。如果将静态成员与其他成员分开会更好。我只是想将数据组组织为具有标识的对象,以便以后可以轻松访问或管理它们。我试过你的方法,它适用于一些奇怪的行为。我会在这里的答案中发布。
    【解决方案2】:

    如果你只希望结构的成员是静态的,你最好的选择是在函数中创建一个静态类型,在你的情况下是一个静态二维数组,然后分配给 [stack]调用函数时的结构。

    例如:

    .. function(...)
    {
      static int b[2][2]
      typedef struct { int a[2][2] } struct1;
      struct1 x[2][2];
      x->a = b;
    }
    

    【讨论】:

    • 我在编译过程中收到“错误:在非结构或联合 x->a=b; 中请求成员‘a’”。这里的“x[][]”代表我在 OP 中提到的“identity[][]”吗?
    • 哎呀,对不起,我忘了添加数组索引。应该是 x[i][j] = b,其中 i 和 j 是一些迭代变量
    【解决方案3】:
    void function(int rowNUM){
    
    int c;
    int d;
    int columnNUM;
    
    
    
    typedef struct {
    int member[3][3];
    }mystruct;
    
    mystruct identity[ROW][COLUMN];
    static bool first_call = true;
    if (first_call) {
    // INTIALIZE each element of member array to 1 
    for (columnNUM=0;columnNUM<COLUMN;columnNUM++)//total cell
    {
    for (c=0;c<3;c++)
       {
    for(d=0;d<3;d++){
       identity[rowNUM][columnNUM].member[c][d]=1;
    //printf("identity[%d][%d].member[%d][%d]=%d\n",rowNUM,columnNUM,c,d,identity[rowNUM][columnNUM].member[c][d]);
           }
        }
    }
    first_call = false;
        }
    
    
    
    identity[0][0].member[0][0]=identity[0][0].member[0][0]+3;
    printf("%d\n", identity[0][0].member[0][0]);
    identity[0][0].member[0][1]=identity[0][0].member[0][1]+1;
    printf("%d\n", identity[0][0].member[0][1]);
    
    
    
    }
    

    以上代码产生: 第一次通话= 4 2 第二次通话= 7 3 第三次通话= 10 4 工作得很好,很好。但无论我声明它都可以正常工作

    mystruct identity[ROW][COLUMN];
    

    或

    static mystruct identity[ROW][COLUMN];
    

    这是否意味着我根本不需要声明静态?

    【讨论】:

    • 是的,您必须声明它static:它告诉编译器将变量放入全局内存而不是堆栈中(这些全局变量只能从该函数访问)。 printf 可能没有使用足够的堆栈变量来让您在调用函数时它们所在的内存区域中有不同的值。这也取决于您声明堆栈变量的顺序。请注意,您首先声明了c、d 和columnNUM。如果您在初始化之前打印c、d 或columnNUM,您可能每次都会看到随机值。
    • without static : intitizlize , c , d 之前的 printf 显示第一次调用函数时的巨大随机数,第二次和第三次调用返回正常数。使用 static ,每次调用都会显示巨大的随机数。结构数组值对于这两种情况都很好。这是否会对数组的值造成麻烦,比如说如果程序变长并且在静态声明之前或之后声明的变量更多?声明变量时,我不太了解内存分配。希望能更详细地了解这个..@miravalls
    • 好的,所以在 C 程序中有几个内存区域:全局只读(常量)、全局共享变量、堆栈和堆。当你声明一个static 变量时,它被放置在全局内存中,但它只定义在你放置它的范围内(一个变量只能在它的范围内使用)。堆栈是一个共享的字节数组,编译器使用它来存储函数的返回地址、函数参数和函数的局部变量。启动函数时,栈变量在栈中分配但未初始化
    • ...所以它们的初始值有些随机:它可能是先前的值,也可能是先前函数调用的参数,也可能是随机的,因为这些字节从未被初始化,或者可能某些字节已用于较短的堆栈变量......有很多组合。有很多来源,您可以查看更深入的解释。我建议您查看c.learncodethehardway.org(练习 17 和 22)或 Kernighan 和 Ritchie 的“C 编程语言”的第 4 章。
    • 谢谢@miravalls。您的解释和建议很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    • 2012-02-28
    • 2021-04-21
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多