2012-04-06 48 views
3

印刷を容易にするため、構造体の要素へのポインタの配列を1つ作成します。どうやってやるの?私の試みは、構造体の最後の行にあります。メモと同様に、この構造体にはint以外の値があります。これはここで示しています。私はこの種のインデックスをintのためだけに使いたいと思います。C:構造体内の構造体要素へのポインタ

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 }; 
} 
+1

ネヴァーマインド - 編集したコードは、より理にかなって;) – sonicwave

+0

ので、構造体の内部のインデックスのこの種を作成するための正しい方法は何ですか? –

+0

C++を使用していますが、一般的な考え方は、前の質問に投稿した[回答](http://stackoverflow.com/a/5088496/179910)に示されています。明らかに 'std :: string'を' char * 'に、' cout'を 'printf'に変更する必要がありますが、' offsetof'で得られたオフセットの配列は重要であり、そのまま残されます。 –

答えて

1

箇条書きを一文字にして、struct memberアクセス​​でそれを印刷するための余分なコードを書いてください。数行のコードを保存するためにデザインを妥協する価値はありません。

この構造体をある日ライブラリーに公開する必要があるとします。あなたは実際には役に立たないこの奇妙なポインタ配列を使ってユーザをロードしたいのですか?

+0

私はあなたの意見を理解することができ、それに部分的に同意します。しかし、私はまだそれがどうやっているのか不思議です。 –

0

このようにすることは不可能です。

C++には、メンバーポインタ( "相対"ポインタ)の概念があります。これは本当に必要なものです。あなたのケース及びCに

私は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]; 

に名前を付けます?ところで

、あなたは あなたは独立して、Aの構造体メンバのアドレスを取得することはできません配列

0

のインデックスを経由して名前とやり方でコンパイルしたアクセスを提供し、労働組合との両方のアプローチを行うことができます構造体変数のインスタンス。 IOWは、あなたが

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

このべきをpunningいくつかの種類を行うことができ、すべての構造体のメンバは、int sがあることを考えるしかし

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

、ような何かをする必要があると思います作業;構造体インスタンスのアドレスは最初のメンバのアドレスと同じであり、すべてのメンバはintであるため、整列またはパディングの問題はありません。私は練習を勧めませんが、あなたの目的のためには十分にうまくいくはずです。

+0

構造体の一部のみが表示されます。私はそれの中に他のバールを持っています。しかし、intの場合にのみ、この種のインデックスが必要です。ありがとう! –

+0

@PeterSenna:その場合、私が書いたものは無視してください。すべてが同じタイプでない場合、この例は機能しません。 –

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]; 
}; 

その後、あなたはそれを参照1がして、使用/印刷するには:

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

あなたの正確なニーズに合わせていないことが、私はちょうどそこにそれを出したかったですもう一つの方法として、Cでこのようなことをすることができます乾杯!

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; 
} 
+0

これはC++ではありません。 –

+0

私は同意します。 :)別の解決策を投稿します。 – ervinbosenbacher

+0

テンプレートをマクロに置き換えるのは簡単です。コアはCで書かれています(C++としてコンパイルされています)。それはあなたが構造を印刷することができ、制約を簡単に提供できる1つのライナーになります。 – ervinbosenbacher

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 
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"); 
} 
関連する問題