【问题标题】:Unable to access field members of struct in another .c file无法访问另一个 .c 文件中结构的字段成员
【发布时间】:2015-12-02 00:19:59
【问题描述】:

我创建了一个复数结构并编写函数来创建它,如下所示:在 Complex.c:

typedef struct Complex
{
    double m_re;
    double m_im;
}Complex;

ComplexP fromCharFunc(char *s)
{

    double *values = extractValuesFromString(s);

    if(values == NULL)
    {
        return NULL;
    }

    double re = values[0], im = values[1];
    free(values);

    return createComplexNumber(re, im);
}


static ComplexP createComplexNumber(double re, double im)
{
     ComplexP complexNumber = (ComplexP)malloc(sizeof(Complex));

     complexNumber->m_re = re;
     complexNumber->m_im = im;

     return complexNumber;
}

这在 Complex.h 中:

typedef struct Complex* ComplexP;

为了检查我所做的是否正常,我在 Complex.c 文件中创建了一个主函数并调用了

ComplexP a = fromCharFunc("0,1i");
a->m_im = 3;

一切正常。

但是当我在另一个 .c 文件中这样做时:

#include "Complex.h"
#include <stdio.h>
#include <stdlib.h>

并且使用相同的主函数,它在主函数的第二行给了我这个错误:“取消引用指向不完整类型的指针”。我在另一篇文章中读到了它,那里的人说没有分配内存......但我确实分配了内存并且它没有发生在 Complex.c 文件中。

请帮忙。谢谢

编辑:我不允许更改头文件。学校作业

【问题讨论】:

  • 既然头文件是固定的,那就贴吧。里面的某些else是有用的。
  • 那里没有其他相关的东西。只是一些我还没有机会在我的新 .c 文件中调用的方法。分配内存和创建此结构的变量并不重要。
  • 如果您无法更改标题,则必须创建访问功能才能获取成员。除非您可以看到结构定义,否则您无法访问成员 - 并且标头中的 opaque 类型不允许这样做。标头中的一些未实现的函数可能提供了您需要的访问权限。
  • 正是那些“我还没有机会调用的方法”才是问题的解决方案。
  • 我理解@JonathanLeffler 回答的问题。谢谢大家!

标签: c pointers struct forward-declaration


【解决方案1】:

你应该搬家

typedef struct Complex
{
    double m_re;
    double m_im;
}Complex;

Complex.h.

那是因为新创建的类型ComplexP 指的是Complex

更新问题的变化:如果头文件Complex.h不能改变,你要么必须复制Complex类型的定义到其他.c文件中,或创建另一个包含类型定义的头文件,并将其包含在.c 文件中。但这显然不是它的预期用途。

【讨论】:

    【解决方案2】:

    “取消引用指向不完整类型的指针”很好。它表明main.c 代码正在尝试访问它不知道或不应该知道的结构的详细信息。

    a->m_im = 3;
    

    这称为信息隐藏。 complex.h 具有以下不透明指针。

    typedef struct Complex* ComplexP;
    

    当然还有其他方法(函数原型)允许访问complex.h 中的ComplexP应该使用main() 而不是a-&gt;m_im = 3;

    【讨论】:

      【解决方案3】:

      您需要练习良好的封装。您的头文件通过向前声明类型来隐藏Complex 的类型。

      头文件中必须有一些其他方法可以帮助您。您可以比较两个复数以查看它们是否相同,例如

      ComplexP a = fromCharFunc("0,1i");
      ComplexP b = createCompleNumber(0,1);
      if (compareComplex(a, b)) {
          printf("Success\n");
      } else {
          printf("Try again\n");
      }
      

      或者有打印功能,例如

      ComplexP a = fromCharFunc("0,1i");
      printComplexNumber(a);
      

      或者也许有函数可以返回实部和虚部:

        ComplexP a = fromCharFunc("0,1i");
        printf("Real: %f, Imaginary: %f\n", complexRealComponent(a), complexImaginaryComponent(a));
      

      由于我看不到标题的其余部分并且您拒绝发布它,所以我不得不猜测调用了哪些函数。我猜其中至少存在一个。

      【讨论】:

        【解决方案4】:

        您必须在Complex.h 中定义结构Complex(或从主函数可见的某个位置)。否则,编译器将不知道Complex 拥有哪些成员,也无法访问它们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-06
          • 1970-01-01
          • 1970-01-01
          • 2021-04-07
          • 2017-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多