【问题标题】:Renaming (aliasing) array elements C重命名(别名)数组元素 C
【发布时间】:2012-12-14 20:40:19
【问题描述】:

不确定什么是“良好做法”或被认为更“正确”。我有一个数组,我想通过数组名 [] 以外的名称访问单个元素。我可以使用#defines 或指针,也可能是其他方式。

例子:

#define value1 myarray[1]

int myarray[SIZE];
value1 = 5;

int myarray[SIZE];
int *ptr;
ptr = &myarray[1];
*ptr = 5;

在我看来,#define 路线更简单,使用的内存更少,但可能会带来一堆我不知道的问题。任何见解都会很棒,我希望尽可能让我的代码遵循普遍接受的标准。

*编辑:也许有更好的方法。我的最终目标是获得一个将发送到外围端口的阵列。然而,数据由非常不同的数据集组成,单个数组名称不能代表所分配的数据。我的内存非常有限,所以我想避免重复存储每个值。

【问题讨论】:

  • 神圣维护的噩梦,蝙蝠侠!
  • 你为什么要这样做?什么是合理的?
  • 我觉得,如果一个值需要一个不同于数组中所有其他值的标识,那么该值首先不应该在数组中。你能提供一个更具体的例子来证明你的想法的实用性吗?
  • 这肯定会成为维护的噩梦。为什么要这样做?

标签: c++ c


【解决方案1】:

我提出第三种选择,例如:

#define VALUE1_IDX  1

int myarray[SIZE];
myarray[VALUE1_IDX] = 5;

与 #1 相比,它的优势在于,您使用 myarray 仍然很明显,而与 #2 相比,优势在于,正如您所说,避免使用指针。我会怀疑,但尚未验证,通过优化,选项 #2 不会有额外的内存使用,尽管它看起来很直观。

我认为最佳解决方案会因情况而异,并且我认为您的两种选择中的任何一种在正确的情况下都是可以辩护的。

编辑:为了回应 Kevin 的评论,首先值得检查的是,当您不集体处理值时,是否可以避免使用数组。我知道在某些情况下这肯定不适用,例如,如果您阅读了长消息并想简单地提取几个关键值。

【讨论】:

  • 这似乎很有希望,而且很明显不知道为什么我没有想到它。保持数组名称通用但使用描述性索引值可以获得我想要的结果。感谢您的意见。
【解决方案2】:

为什么不参考?

int A[3];  
int& a1=A[1];

【讨论】:

    【解决方案3】:

    unions 是另一种给变量取别名的方法。但不要将此作为建议。如果您依赖别名,它们是危险的(不可移植的)。你应该只使用它们来优化内存使用,对于你不需要的变量。

    【讨论】:

    • 联合不会让您为预先存在的变量设置别名。同样使用联合来使对象相互别名可能(取决于类型)违反严格的别名规则,并且由于一次只有一个联合成员“活跃”的规则,这也是值得怀疑的。
    【解决方案4】:
    enum {SIZE = 100};
    
    struct Mapping {
      int unused1;
      int value1;
      int unused2;
    };
    
    Mapping& AsMapping( int(&array)[SIZE] ) {
      return *reinterpret_cast<Mapping*>(&array);
    }
    
    int arr[SIZE];
    AsMapping(arr).value1 = 5;
    Mapping& values = AsMapping(arr);
    values.value1 = 5;
    

    这几乎不需要内存,优化器应该能够擦除所有内容。同时,它是合理可维护的。

    在您的structs 上设置对齐可能是您必须小心的要求。

    【讨论】:

      【解决方案5】:

      你可以这样做

      typedef enum
      {
          foo = 0;
          // ... more named values
          bar = SIZE;
      } Thing;
      
      int value[SIZE];
      value[foo] = 5;
      

      Using an enum as an array index

      【讨论】:

        【解决方案6】:

        非定义方法允许您进行一定程度的类型更正,这是第二种方法所不具备的。

        此外,任何健全的编译器生成的实际代码对于两者都是相同的。

        总而言之,我更喜欢第二个,因为很明显发生了什么。另一个问题是#define 可能会导致超出您实际处理的区域范围的问题。

        使用后者更明智,因为这意味着其他人不太可能在以后出现并将其搞砸......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-31
          • 2014-01-28
          • 2013-11-15
          相关资源
          最近更新 更多