将指针传递给结构数组

时间:2016-03-26 06:09:34

标签: c arrays pointers struct xc8

这适用于MPLABXC8编译器 我研究过并发现了很多相关的主题。但无法解决我的问题。 我的数组typedef

     typedef volatile struct OneStageOpTag
   {
        unsigned DevID1: 4;
        unsigned SetCmd1 : 4;
        unsigned RdyResponse1 :4;
        unsigned DevID2: 4;
        unsigned SetCmd2 : 4;
        unsigned RdyResponse2 :4;
        unsigned DevID3: 4;
        unsigned SetCmd3 : 4;
        unsigned RdyResponse3 :4;
    }OneStageOpType[3];

现在我的变量

    OneStageOpType CurOperPlan={0};// I checked this one - 
        //-in Simulator 3 element array of structure created

现在我将指针传递给我的函数

GetOperationSeqForTransportReq(1,1,&CurOperPlan);

以下是功能

void GetOperationSeqForTransportReq(StationIDType SourseStnID,StationIDType DestiStnID,
                    OneStageOpType  *CurTransportPlan)
{
    NOP();
    CurTransportPlan[0]->DevID1=5;  // This is Ok
    CurTransportPlan[1]->DevID1=5;  // This is Not working      
}

只有第0个元素是可访问的。另外编译器抱怨结构指针传递给结构数组指针。 我尝试通过在函数中执行指针。它似乎正在推动整个数组指针。 在我看来,&CurOperPlan只是指向第0个索引结构的地址指针。整个数组不包含它。 请帮忙。

3 个答案:

答案 0 :(得分:3)

更改此

GetOperationSeqForTransportReq(1,1,&CurOperPlan);

GetOperationSeqForTransportReq(1, 1, CurOperPlan);

和这个

void GetOperationSeqForTransportReq(StationIDType SourseStnID,StationIDType DestiStnID,
                OneStageOpType  *CurTransportPlan)

是这个

void GetOperationSeqForTransportReq(
  StationIDType SourseStnID,
  StationIDType DestiStnID,
  OneStageOpType CurTransportPlan)

为了完整性,还要更改此

OneStageOpType CurOperPlan={0};

OneStageOpType CurOperPlan = {{0}};

答案 1 :(得分:1)

在函数内部,您需要:

(*CurTransportPlan)[0].DevID1=5;  // This is Ok
(*CurTransportPlan)[1].DevID1=5;

这是因为CurTransportPlan是数组的指针。因此,您必须取消引用它才能获得数组。然后,您可以将数组索引应用于数组。

Link to working example

为了解释第一个似乎有效的原因,我们可以重写应用等价变换的代码X->Y = (*X).YX[N] = *(X+N)

数组表示法中的正确索引应为CurTransportPlan[0][0].DevID1CurTransportPlan[0][1].DevID1;但是你的代码在两种情况下都交换了索引。这意味着第一个仍然有效,但第二个破坏了。

关于您的代码设计:已经注意到有两种方法可以将数组传递给函数:

  1. 你可以将一个指针传递给数组的第一个元素,正如alk建议的那样(分别传递长度或硬编码)

  2. 您可以像现在一样将指针传递给整个数组。

  3. 我将列出这两种设计之间的一些差异。使用您的设计,即指向整个数组的指针:

    • 如果传递的行数不同,则会出现编译错误。
    • 如果传递非易失性数组,则会出现编译错误。
    • 您必须写(*ptr)而不是ptr,这更加详细。

    您决定是否希望编译器在前两点给出错误。铸造可以避免错误,但一般来说,需要施放是另一种方法更好的设计的标志。

    如果此函数只与大小 - 3 volatile数组一起使用,那么IMHO当前的方法是最好的,调用最大的编译器检测错误。

答案 2 :(得分:-1)

因为你有一个三元素数组的typedef:

typedef volatile struct OneStageOpTag {
  // ...
} OneStageOpType[3];

问题似乎是:

void GetOperationSeqForTransportReq(
  StationIDType SourseStnID,
  StationIDType DestiStnID,
  OneStageOpType *CurTransportPlan)       // HERE

在上面的函数中,您将参数声明为指向3元素数组的指针,但您应将其作为指向数组第一个元素的指针传递。这意味着您应该执行以下操作:

typedef volatile struct _OneStageOpTag {
  // ...
} Array[3], Element;

// ...

Array CurOperPlan={0};
GetOperationSeqForTransportReq(1,1,&CurOperPlan);

// ...

void GetOperationSeqForTransportReq(StationIDType SourseStnID,
  StationIDType DestiStnID, Element *CurTransportPlan)
{
  NOP();
  CurTransportPlan[0]->DevID1=5;  // This is Ok
  CurTransportPlan[1]->DevID1=5;  // This is Not working      
}

这应该适合你:)