【问题标题】:initialize a struct of structs through function calls通过函数调用初始化一个结构体
【发布时间】:2020-08-31 16:28:58
【问题描述】:

无法确定用于在结构中初始化结构的嵌套取消引用。我终于想通了通过对 Inode 结构的函数调用来初始化一个结构,但我似乎无法将其转换为通过对 Inodetable 结构(它是一个 Inode 结构的结构)的函数调用来初始化一个结构结构。

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

int POINTERS_PER_INODE = 5;
int Total_Inodes = 64;

struct Inode {
   int  valid;/* 0 == invalid, 1 == valid*/
   int size;
   int Blocks [5];
};

struct InodeTable InodeTable;

int InodeToString(char * InodeString, struct Inode iNode){
  char * blockBuffer;
  sprintf(InodeString, "%d", iNode.valid);
  int i;
  for (i = 0; i < POINTERS_PER_INODE; i++){
    blockBuffer = malloc(8);
    sprintf(blockBuffer, "%d", iNode.Blocks[i]); //no valid pointers yet
    strcat(InodeString,blockBuffer);
    free(blockBuffer);
  }
  return 0;
}


int initializeInode(struct Inode * iNode){
  int i;
  for (i = 0; i < POINTERS_PER_INODE; i++){
    iNode->Blocks[i] = -1; //no valid pointers yet
  }
  iNode->valid = 0; //initialized as invalid inode
  return 0;
}

int initializeInodeTable(struct InodeTable * ITable){
    char * InodeTableString;
    char * inodeString;

    InodeTableString = malloc(sizeof(struct Inode) * 64);
    memset(InodeTableString, 0 , sizeof(struct Inode) * 64);


    for (int i = 0; i < Total_Inodes; i++){
      inodeString = malloc(sizeof(struct Inode));
      memset(inodeString, 0 , sizeof(struct Inode));

      initializeInode(&ITable.InodeTable[i]);
      InodeToString(inodeString, &ITable.InodeTable[i]);
      strcat(InodeTableString,inodeString);
      free(inodeString);
    }


    printf("write: %s"InodeTableString);
    free(InodeTableString);
    return 0;
}

int main() {
  struct InodeTable iNodeTable[64];
  initializeInodeTable(&iNodeTable);


  return 0;
}

【问题讨论】:

  • “我遇到了麻烦”并没有具体告诉我们您的问题是什么。 “我不得不将它分解并尝试一点一点地重建它”仅供参考,最佳做法是始终这样做。编写大量代码然后在最后进行一次大爆炸测试并不是一个好主意。编写一小段代码,测试它们是否工作(最好使用自动单元测试),然后继续编写下一小段代码。
  • 特别是我对嵌套取消引用感到困惑。它似乎不适用于结构中的结构,就像它适用于结构中的数组一样,我尝试了一些变体,在所有地方都取消引用箭头但不起作用,但也许我被 sprintf 绊倒了,只是没有使用正确的组合?
  • 我最初确实以尽可能小的块编写尽可能多的代码,但是当将它们从 IDE 移动到引用文件而不只是字符串的实际项目时,我不得不调整许多部分,然后更改了有关实现更大功能(例如导入文件)的设计决策,这改变了我计划使用/引用/读取/写入用户定义结构的方式。
  • 我能够通过将 inode 结构传递给初始化函数来初始化它,但是当我尝试将它嵌套在 InodeTable 的初始化函数中时,它是 Inode 结构的结构并尝试传递在我以类似方式进行的任何最佳尝试中指向 InodeTable 的指针,我似乎无法初始化任何东西。
  • 原来的项目要大得多,因为我在这个初始化策略上没有取得任何进展,所以我构建了所有东西以避免使用结构体,这帮助我充实了许多其他设计决策,并且是唯一的选择,因为我无法弄清楚这一点,但它是一个我不满意的笨拙的解决方法,特别是对于添加未来的代码并且没有解决我未能实现预期的数据结构的问题。

标签: c function pointers struct initialization


【解决方案1】:

使用 gcc 编译代码(在 mac 上技术上是 clang)会出现以下错误

Inode.c:52:30: error: member reference type 'struct InodeTable *' is a pointer; did you mean to
      use '->'?
      initializeInode(&ITable.InodeTable[i]);
                       ~~~~~~^
                             ->
Inode.c:52:30: error: incomplete definition of type 'struct InodeTable'
      initializeInode(&ITable.InodeTable[i]);
                       ~~~~~~^
Inode.c:15:8: note: forward declaration of 'struct InodeTable'
struct InodeTable InodeTable;
       ^
Inode.c:53:41: error: member reference type 'struct InodeTable *' is a pointer; did you mean to
      use '->'?
      InodeToString(inodeString, &ITable.InodeTable[i]);
                                  ~~~~~~^
                                        ->
Inode.c:53:41: error: incomplete definition of type 'struct InodeTable'
      InodeToString(inodeString, &ITable.InodeTable[i]);
                                  ~~~~~~^
Inode.c:15:8: note: forward declaration of 'struct InodeTable'
struct InodeTable InodeTable;
       ^
Inode.c:59:23: error: expected ')'
    printf("write: %s"InodeTableString);
                      ^
Inode.c:59:11: note: to match this '('
    printf("write: %s"InodeTableString);
          ^
Inode.c:65:31: error: array has incomplete element type 'struct InodeTable'
  struct InodeTable iNodeTable[64];
                              ^
Inode.c:15:8: note: forward declaration of 'struct InodeTable'
struct InodeTable InodeTable;
       ^
Inode.c:15:19: error: tentative definition has type 'struct InodeTable' that is never completed
struct InodeTable InodeTable;
                  ^
Inode.c:15:8: note: forward declaration of 'struct InodeTable'
struct InodeTable InodeTable;
       ^
7 errors generated.

因此,您应该马上注意到您没有定义 InodeTable。也许这就是为什么你不能初始化第二个结构。

另外,我认为您的意思是使用 * 而不是 &amp;

*foo = "地址foo处的数据"

&amp;foo = "数据地址foo"

另一个需要修复的地方是你放了

printf("write: %s" InodeTableString);

相对于

printf("write: %s", InodeTableString);

如果您使用您尝试使用的语法,则存在多个参数

在访问foo 指向的结构的成员bar 时,最好使用

foo->bar

换句话说

foo-&gt;bar = "foo 指向的结构中的元素 bar"

并且您可以避免整个“我完全使用 * 还是 & 问题”,因为以下是正确的

foo-&gt;bar = (*foo).bar

但是,以下是可能的错误

(*foo).bar != (&amp;foo).bar

【讨论】:

  • 谢谢。我正在使用 IDE 来可视化有助于跟踪空终止符的代码,但它没有提供太多错误信息,所以也许我也会使用 gcc。 printf 是最后一分钟的错字,由于该错误,我没有注意到,我之前一直在打印单个 inode。我不太确定定义 InodeTable 是什么意思,因为我认为这就是“struct InodeTable InodeTable;”。在顶部和“struct InodeTable iNodeTable [64];”正在做,其余的应该发生在初始化函数中。我缺少正确定义的哪一部分?
  • 天哪!哎呀!第一个应该是:struct InodeTable{ struct Inode InodeTable[64]; };第二个:struct InodeTable iNodeTable;
  • 仍然无法初始化。
  • this: struct InodeTable iNodeTable; 曾经是 struct Inode inode1;,我可以正确地将其传递给 inode 初始化。我想我想弄清楚如何在 inodetable 初始化中声明每个 inode,而不初始化它,然后将其传递给 inode 初始化。所以在 initializeInode 之前会是这样的:struct Inode *ITable-&gt;InodeTable[i]; 除了以一种有意义/编译的方式
  • 我认为最能帮助你的是en.wikipedia.org/wiki/The_C_Programming_Language。本书由 C 编程语言的创造者 (Ritchies) 和计算机科学的最佳阐释者之一 (Kernighan) 撰写。它被亲切地称为 K&R,被认为是计算机科学文化中的必读。在第 6.5 节中,他们给出了一个示例,说明如何初始化一个与您尝试编写的结构非常相似的结构。请参阅该部分中的 talloc() 函数,该函数初始化 tnode 结构,该结构是较大树数据结构结构的一部分。
猜你喜欢
  • 1970-01-01
  • 2020-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多