尝试在 C 中引用值时出现 LValue 错误

发布于 2024-10-26 02:31:02 字数 6223 浏览 7 评论 0原文

这肯定会对某人来说很有趣。所以我有一个对象数组(在我的测试/演示代码中,为了简单起见,我只是将它们加倍),然后创建一个指向这些对象的指针数组。

我这样做的原因是因为我将交换对象,并且交换对象本身的成本很高,而交换它们的指针(在辅助数组中)则很便宜。

我的框数据类型中有许多子索引。基本上,我的目标是能够维护指向盒子“拥有”的对象的连续指针。为此,当我从一个盒子转移到另一个盒子时,我必须在主指针数组中执行多次交换。我通过使用框结构内的子索引来执行此操作,并且正是在那里发生错误...请参阅注释行以了解错误。

#include <iostream>

typedef struct box_s {
  double * TestArrayPointer;
} box_t;

main () {

  double * TestArray;
  double ** TestPointerArray;

  TestArray = new double [100];

  TestPointerArray = new double * [100];

  for (unsigned int Counter = 0; Counter<100; Counter++)
  {
     TestArray[Counter]=Counter;
     TestPointerArray[Counter]=&(TestArray[Counter]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    Boxes[Counter].TestArrayPointer = TestPointerArray[Counter*10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = Boxes[ExitBox+1].TestArrayPointer-1;
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        //Fill in new first with last element of old array.
        (Boxes[BoxNum-1].TestArrayPointer-1)=
      Boxes[BoxNum+1].TestArrayPointer-1; //darn l-value error!
    //Change array head pointer to match.
    Boxes[BoxNum].TestArrayPointer=Boxes[BoxNum-1].TestArrayPointer-1;
     }
     Boxes[EntranceBox].TestArrayPointer = TempPtr;
  }  
  for (unsigned int Counter = 0; Counter<100; Counter++)
     std::cout << "P: " << TestPointerArray[Counter] << " V: " 
           << *(TestPointerArray[Counter]) << std::endl;
}

我认为这是因为“-1”,但当我在上面的循环中用“+1”做类似的事情时,我不确定为什么这是无效的。

PS 这是真正的测试代码。我编译用

g++ main.cpp

。我没有仔细注意评论和大小写,只是尝试坚持 MSDN 建议的大小写方案,所以不要评判......这只是一个快速而肮脏的测试!

编辑1

这是任何关心的人的工作代码...PMG 鉴于new用法,我将其更改为c++。希思,我相信你,尽管你的回答没有解决根本问题。

这是真正的解决方案:

#include <iostream>

typedef struct box_s {
  double ** TestArrayPointer;
  unsigned int NumberPoints;
} box_t;

main () {

  double * TestArray;
  double ** TestPointerArray;

  TestArray = new double [100];

  TestPointerArray = new double * [100];

  for (unsigned int Counter = 0; Counter<100; Counter++)
  {
     TestArray[Counter]=Counter;
     TestPointerArray[Counter]=&(TestArray[Counter]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
  {
     Boxes[Counter].TestArrayPointer = TestPointerArray+Counter*10;
     Boxes[Counter].NumberPoints=10;
  }
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
    Boxes[ExitBox].NumberPoints--;
    Boxes[EntranceBox].NumberPoints++;
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = *(Boxes[ExitBox+1].TestArrayPointer-1);
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        Boxes[BoxNum].TestArrayPointer=
      Boxes[BoxNum].TestArrayPointer-1;
        //Fill in new first with last element of old array.
    *(Boxes[BoxNum].TestArrayPointer)=
      *(Boxes[BoxNum+1].TestArrayPointer)-1;    
    std::cout <<"---------------------" << std::endl;
    for (unsigned int Counter = 0; Counter<100; Counter++)
       std::cout << "P: " << TestPointerArray[Counter] << " V: " 
             << *(TestPointerArray[Counter]) << std::endl;
     }
     Boxes[EntranceBox].TestArrayPointer=
      Boxes[EntranceBox].TestArrayPointer-1;
     *(Boxes[EntranceBox].TestArrayPointer) = TempPtr;
  }  

  for(unsigned int BoxNum = 0; BoxNum<=9;BoxNum++)
  {
    std::cout <<"---------------------" << std::endl;
    for(unsigned int Counter = 0; Counter<Boxes[BoxNum].NumberPoints; 
    Counter++)
      std::cout << "P: " <<Boxes[BoxNum].TestArrayPointer[Counter] 
      << " V: " 
            << *(Boxes[BoxNum].TestArrayPointer[Counter]) 
      << std::endl;

  }
}

注意正确的交换!

Here's one that's sure to be fun for someone. So I have an array of objects (in my test/demo code here, I just make them doubles for simplicity) and then I create an array of pointers to these objects.

The reason I do this is because I'm going to be swapping the objects, and swapping the objects themselves would be expensive, while swapping their pointers (in the secondary array) is cheap.

I have a number of subindexes inside my box data type. Basically, my goal is to be able to maintain contiguous stretches of pointers to objects that the box "owns". To do this, when I transfer from one box to another, I have to perform a number of swaps within the master pointer array. I do this via using the subindex inside my box structure, and it is there that the error occurs... see commented line for error.

#include <iostream>

typedef struct box_s {
  double * TestArrayPointer;
} box_t;

main () {

  double * TestArray;
  double ** TestPointerArray;

  TestArray = new double [100];

  TestPointerArray = new double * [100];

  for (unsigned int Counter = 0; Counter<100; Counter++)
  {
     TestArray[Counter]=Counter;
     TestPointerArray[Counter]=&(TestArray[Counter]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    Boxes[Counter].TestArrayPointer = TestPointerArray[Counter*10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = Boxes[ExitBox+1].TestArrayPointer-1;
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        //Fill in new first with last element of old array.
        (Boxes[BoxNum-1].TestArrayPointer-1)=
      Boxes[BoxNum+1].TestArrayPointer-1; //darn l-value error!
    //Change array head pointer to match.
    Boxes[BoxNum].TestArrayPointer=Boxes[BoxNum-1].TestArrayPointer-1;
     }
     Boxes[EntranceBox].TestArrayPointer = TempPtr;
  }  
  for (unsigned int Counter = 0; Counter<100; Counter++)
     std::cout << "P: " << TestPointerArray[Counter] << " V: " 
           << *(TestPointerArray[Counter]) << std::endl;
}

I think it's because of the "-1", but I'm not sure why that's not valid, when I do similar things with "+1" in the loops above.

P.S. This is the REAL test code. I compile with

g++ main.cpp

. I didn't pay to careful attention to the comments and casing, just tried to stick with MSDN's suggested casing scheme, so don't judge... it's just a quick&dirty test!!

EDIT 1

Here is the working code for whoever cares... PMG I changed this to c++ given the new usage. And Heath I'm giving you credit, though your answer didn't solve the underlying problem.

Here is the real solution:

#include <iostream>

typedef struct box_s {
  double ** TestArrayPointer;
  unsigned int NumberPoints;
} box_t;

main () {

  double * TestArray;
  double ** TestPointerArray;

  TestArray = new double [100];

  TestPointerArray = new double * [100];

  for (unsigned int Counter = 0; Counter<100; Counter++)
  {
     TestArray[Counter]=Counter;
     TestPointerArray[Counter]=&(TestArray[Counter]);
  }
  for (unsigned int Counter = 0; Counter<100; Counter++)
    std::cout << "P: " << TestPointerArray[Counter] << " V: " 
          << *(TestPointerArray[Counter]) << std::endl;

  box_t Boxes[10];
  for (unsigned int Counter = 0; Counter<10; Counter++)
  {
     Boxes[Counter].TestArrayPointer = TestPointerArray+Counter*10;
     Boxes[Counter].NumberPoints=10;
  }
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << Boxes[Counter].TestArrayPointer << " V: " 
          << *(Boxes[Counter].TestArrayPointer)
          << " P+1: " << (Boxes[Counter].TestArrayPointer)+1 << " V+1: " 
          << *((Boxes[Counter].TestArrayPointer)+1) 
          << " P: " << Boxes[Counter].TestArrayPointer <<std::endl;
  for (unsigned int Counter = 0; Counter<10; Counter++)
    std::cout << "P: " << &(Boxes[0].TestArrayPointer[Counter]) << " V: " 
          << Boxes[0].TestArrayPointer[Counter] << std::endl;


  unsigned int ExitBox = 1;
  unsigned int EntranceBox=9;
  unsigned int OldIndex = 12;
  double * TempPtr = TestPointerArray[OldIndex];

  if (ExitBox < EntranceBox)
  {
    Boxes[ExitBox].NumberPoints--;
    Boxes[EntranceBox].NumberPoints++;
     //Swap final element of this box into old position
     TestPointerArray[OldIndex] = *(Boxes[ExitBox+1].TestArrayPointer-1);
     //Keep swapping start for end
     for(unsigned int BoxNum = ExitBox+1; BoxNum<EntranceBox &&
       BoxNum+1<=9;BoxNum++)
     {
        Boxes[BoxNum].TestArrayPointer=
      Boxes[BoxNum].TestArrayPointer-1;
        //Fill in new first with last element of old array.
    *(Boxes[BoxNum].TestArrayPointer)=
      *(Boxes[BoxNum+1].TestArrayPointer)-1;    
    std::cout <<"---------------------" << std::endl;
    for (unsigned int Counter = 0; Counter<100; Counter++)
       std::cout << "P: " << TestPointerArray[Counter] << " V: " 
             << *(TestPointerArray[Counter]) << std::endl;
     }
     Boxes[EntranceBox].TestArrayPointer=
      Boxes[EntranceBox].TestArrayPointer-1;
     *(Boxes[EntranceBox].TestArrayPointer) = TempPtr;
  }  

  for(unsigned int BoxNum = 0; BoxNum<=9;BoxNum++)
  {
    std::cout <<"---------------------" << std::endl;
    for(unsigned int Counter = 0; Counter<Boxes[BoxNum].NumberPoints; 
    Counter++)
      std::cout << "P: " <<Boxes[BoxNum].TestArrayPointer[Counter] 
      << " V: " 
            << *(Boxes[BoxNum].TestArrayPointer[Counter]) 
      << std::endl;

  }
}

Note the proper swapping!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意犹 2024-11-02 02:31:02

我不会质疑你的代码,因为我无法真正阅读它。

关于左值错误,更改为:

(Boxes[BoxNum-1].TestArrayPointer-1) = ...

*(Boxes[BoxNum-1].TestArrayPointer-1) = ...

即使

Boxes[BoxNum-1].TestArrayPointer[-1] = ...

计算出的指针不是左值,也必须取消引用它。换句话说,您无法通过更改地址来存储任何内容,您必须将您的值存储在地址处。

I'm not going to question your code because I can't really read it.

Regarding the l-value error, change:

(Boxes[BoxNum-1].TestArrayPointer-1) = ...

to

*(Boxes[BoxNum-1].TestArrayPointer-1) = ...

or even

Boxes[BoxNum-1].TestArrayPointer[-1] = ...

A calculated pointer is not an l-value, it must be dereferenced. In other words, you can't store anything by changing the address, you must store your value at the address.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文