3

印刷を容易にするために、構造体の要素へのポインターの配列を 1 つ作成します。どうやってやるの?私の試みは、構造体の最後の行にあります。注意として、この構造体には int 以外の値があり、ここに示されています。この種のインデックス作成は、int に対してのみ必要です。

struct status {
    int lastinputVac;
    int inputVac;

    int outputVac;

    /* The unit is % */
    int outputpower;

    int outputHz;

    /* The unit is % */
    int batterylevel;

    int temperatureC;

    int *ordered_values[] = { &lastinputVac, &inputVac, &outputVac, &outputpower, &outputHz, &batterylevel, &temperatureC };
}
4

7 に答える 7

1

弾丸を噛んで、追加のコードを記述して、構造体メンバー アクセスで出力します。数行のコードを節約するために設計を妥協する価値はありません。

いつかこの構造体をライブラリに公開する必要があると想像してください。本当の目的を果たさないこの奇妙なポインター配列でユーザーを本当にロードしたいですか?

于 2012-04-06T14:30:39.337 に答える
1

したがって、質問は「構造体の要素へのポインターの配列を 1 つ作成したい」というものでした。要素がint以外のものである可能性があると述べています。

私は、安全性または言語の適合性と設計の点で多くの改善が必要な一般的な解決策を作成しましたが、以下の質問に対する 1 つの解決策を示しています。以下のコードは、構造体の要素がすべて同じサイズであると仮定して構造体のサイズを計算し、要素へのポインターの配列を構築し、print_array 関数がそれらの要素を出力することによってそれらの要素を反復処理します。ostream<< 演算子をオーバーロードすることもできましたが、できるだけ単純にしたかったのです。

  #include "stdafx.h"

  struct status {
      int lastinputVac;
      int inputVac;
      int outputVac;

      /* The unit is % */
      int outputpower;

      int outputHz;

      /* The unit is % */
      int batterylevel;

      int temperatureC;
};

//template<typename T>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>

// hide this into a library 
template<typename T>
size_t build_array(const status& val, T*** vecptr)
{
const size_t _size = sizeof(status) / sizeof(int);
*vecptr = (T**)malloc( sizeof(T*) *_size );

for (size_t i = 0; i < _size; ++i) {
    (*vecptr)[i] = ((T *)((&val)+i));
}
return _size;
}

template<typename T>
void free_array(T** vecptr)
{
free(vecptr);
}

template<typename T>
void print_array(T **vecptr, size_t size) 
{
for (size_t i = 0; i < size; i++)
    std::cout << *(*vecptr + i) << std::endl;
}

//T1 is the type of the struct and T2 is the type of the elements
template<typename T1, typename T2>
class PrintStruct
{
private:
    T2 **m_vecptr;
    size_t m_size;

public:
    PrintStruct(T1 t) {
        m_size = build_array<T2>(t, &m_vecptr);
        print_array(m_vecptr, m_size);
    }

    ~PrintStruct() {
        free_array(m_vecptr);
    }
 };

 int _tmain(int argc, _TCHAR* argv[])
 {
 status _status;
 _status.batterylevel = 1;
 _status.inputVac = 2;
 _status.lastinputVac = 3;
 _status.outputHz = 4;
 _status.outputpower = 5;
 _status.outputVac = 6;
 _status.temperatureC = 7;

 PrintStruct<status, int> _ps(_status);
 return 0;
 }
于 2012-04-06T17:18:41.077 に答える
0

構造体変数インスタンスとは別に、構造体メンバーのアドレスを取得することはできません。IOW、あなたは次のようなことをしなければならないでしょう

struct status foo;
int *ordered_values[] = {&foo.lastInputVac, &foo.inputVac, ...};

ただし、すべての構造体メンバーがsであるとすると、型のパンニングintを行うことができます。

int *ordered_values = (int *) &foo;
for (i = 0; i < 7; i++)
  printf("%d\n", ordered_values[i]);

これは機能するはずです。構造体インスタンスのアドレスは最初のメンバーのアドレスと同じであり、すべてのメンバーがintsであるため、配置やパディングの問題は発生しないはずです。練習はお勧めしませんが、あなたの目的には十分に機能するはずです。

于 2012-04-06T14:26:59.633 に答える
0

このままでは無理です。

C++ には、メンバー ポインター (「相対」ポインター) の概念があり、それが本当に必要です。

あなたの場合、CIは常にintの配列を使用し、単にインデックスに名前を付けることを提案します

struct status {
   int values[7];
}
..
const int lastinputVac = 0;  // or upper case when you like, or use #define
..
status a;
a.values[lastinputVac] = 27;
int z = a.values[lastinputVac];

わかりますか??

ちなみに、ユニオンを使用して両方のアプローチを行うことができ、名前を使用したコンパイル済みアクセスと、配列のインデックスを介した方法を提供できます

于 2012-04-06T14:22:37.190 に答える
0

コメントを読むと、構造体に多くの要素があるように見えますが、それらの一部のみを印刷したいと考えています。ここに私の考えがあります:

1) この配列を構造体に入れないでください! これは静的です。変更されることはないstruct statusため、構造体に含めるのは無駄であり、直感的ではありません。

2) これらの値を独自の構造体に分離することを考えましたか? その後、次のパラダイムを使用できます。

enum status {
    LASTINPUT_VAC,
    INPUT_VAC,
    OUTPUT_VAC,
    OUTPUT_PWR,
    OUTPUT_HZ,
    BATT_LVL,
    TEMPERATURE,
    STATUS_MAX
};

struct system {
    char name[MAXNAME];
    long other_data;
    float coords[2];
    char *whatever_you_have_here;
    int status[STATUS_MAX];
};

次に、参照するものを印刷/使用するには、次のようにします。

struct system sys;
int temp = sys.status[TEMPERATURE];
for (int i = 0; i < STATUS_MAX; i++)
    printf("%d\n", sys.status[i]);

それはあなたの正確なニーズに合わないかもしれませんが、Cでこの種のことを行うことができる別の方法としてそれを公開したかっただけです.乾杯!

于 2012-04-06T15:03:17.293 に答える
0

私の頭に浮かぶ別のアプローチがあります。私の観察では、メンバーは正しい順序になっていますが、インデックスによって簡単にアクセスしたいでしょう。

ただし、警告: パディングに注意する必要があります。パディングはintをずらす可能性があります。ただし、int32 の場合は問題ないと思います。

これはハックすぎると考える人もいますが、可能性はあります

struct status {
  int lastinputVac;
  int inputVac;

  int outputVac;

/* The unit is % */
  int outputpower;

  int outputHz;

  /* The unit is % */
  int batterylevel;

  int temperatureC;
} stat;

int* a = &stat;

int maxIndex = (&stat.temperatureC - &stat.lastinputVac) / sizeof (stat); // should be 6
 // you could build named constants for that
a[0]; // lastinputVac
a[1]; // inputVac
a[2]; // outputVac
a[3]; // outputpower
a[4]; // outputHz
a[5]; // batterylevel
a[6]; // temperatureC
于 2012-04-06T18:04:14.573 に答える
0

構造体を配列と結合します。アラインメントについては、コンパイラのドキュメントを参照してください。

union {

    struct {
       int someInt0;
       int someInt1;    
    }; //anonymous

    int arry[2];

} thing;

val0 = thing.someInt0; //structure access
val1 = thing.arry[0]; //gcc, C18, XC8, and XC32 handle this with the top value indexed to 0

if (val0 == val1) { 
    puts("this works");
}
于 2016-05-11T23:07:44.973 に答える