
次のようなソースで
typedef struct test{
int a;
int b;
int c;
}TEST;
TEST xx;
xx.a=xx.a+3;
xx.b=xx.b+3;
xx.c=xx.c+3;
printf("%d %d %d\n",xx.a,xx.b,xx.c);
のようなことをしたいんですが、
xx.a=xx.a+3;
xx.b=xx.b+3;
xx.c=xx.c+3;
の処理の部分をfor文で回せるようにしたいです。
構造体の宣言のところで配列をつかって
struct test{
int abc[3];
}
とすれば簡単にいくのは分かるんですが、a,b,cそれぞれに分かりやすい名前をつけたいので、配列で確保したくないです。
何かいい方法はないでしょうか?
実際計算に使うんですが、メンバはすべてdouble型で30個程度になると思います。
No.7ベストアンサー
- 回答日時:
軽くなったので続きをば
共用体は、なるべくメンバのアドレスを共有するように動作します。だから、共用体の宣言を変えない限り確保されるパターンが変わることはありません。
だから、安心して使っても大丈夫です。
特に今回のように、配列と名前アクセスを行いたいのであれば、moca12980さんが先の補足にあげられたようにやればまったく問題ありません。
--テストプログラムここから
typedef union test{
struct{double a,b,c,d[17];};
double temp[20];
}uABC;
uABC abc;
int main()
{
int i;
for(i=0; i<20; i++) abc.temp[i]=i;
printf("a=%.2f,\tb=%.2f,\tc=%.2f\n", abc.a, abc.b, abc.c);
for(i=0; i<17; i++) printf("d[%02d]=%.2f,\t", i, abc.d[i]);
printf("\n");
return 0;
}
--テストプログラムここまで
実は、変数の個数が少なければ、defineでもかわせます。個数が増えると見通しがいい分共用体の方が楽なんですけど。
--テストプログラムここから
double temp[20];
#define U_a(A) A[0]
#define U_b(A) A[1]
#define U_c(A) A[2]
#define U_d(A,X) A[(X) + 3]
int main()
{
int i;
for(i=0; i<20; i++) temp[i]=i;
printf("a=%.2f,\tb=%.2f,\tc=%.2f\n", U_a(temp), U_b(temp), U_c(temp));
for(i=0; i<17; i++) printf("d[%02d]=%.2f,\t", i, U_d(temp, i));
printf("\n");
return 0;
}
--テストプログラムここまで
回答ありがとうございます。
あの方法で大丈夫だったんですね。
今回で、構造体や列挙体の使い道も分かってきたので、必要に応じて使い分けて行きたいと思います。
今回質問したことについては、やはり共用体が一番しっくりくる気がするので、まずは共用体で試してみます。
No.6
- 回答日時:
#1です。
> 列挙体を使うというのは、どういう方法になるんでしょうか?#2の方のやり方ということでしょうか?
はい。そうなります。
配列が含まれているとのことですが、列挙定数の値は不連続でも構わないので、
typedef struct test
{
int a;
int b;
int c;
int z[10];
int d;
} TEST;
を
typedef struct test
{
int x[14];
} TEST;
enum
{
a, b, c, z, d = z + 10
};
のようにすれば、
TEST xx;
xx[z + 0] += 1;
xx[z + 3] += 2;
xx[d] += 3;
のように扱うこともできるかと思います。
回答ありがとうございます。
まだまだ曖昧なところはありますが、列挙体の使い方がわかりました。
これから勉強してちゃんと理解したいと思います。
No.5
- 回答日時:
多分あなたの要求しているものは共用体(union)だね。
え~教えて!gooが今のような状態だと私の書き方*1ではストレスがたまって仕方がないので、軽くなるまで私は保留。
どなたも回答がなければサイトが軽くなってから詳しく書きます。
多分1週間以内には軽くなるとは思ってます
共用体を使うのも考えてはいました。
typedef union test{
struct{
int a,b,c,d[17];
}
int temp[20];
}uTEST;
uTEST abc[5];//5が#3の方のお礼のところに書いた変数数
このようにすると
abc[0].aがabc[0].temp[0]
abc[0].bがabc[0].temp[1]
・・・
abc[1].aがabc[1].temp[1]
abc[1].bがabc[1].temp[1]
・・・
と参照できるようになっていいようにも思えるんですが、共用体についてや、アドレスについて知らないことだらけで何かの拍子に上に書いた対応がズレたり、何かバグが潜むんじゃないかと思い使えないでいました。
共用体の使い方等、軽くなってから回答いただけるならお待ちしていますのでよろしくお願いします。
No.4
- 回答日時:
No.3の回答をしたものですが、大丈夫かと思いますが自分の回答でどうしてもいくつか細かい所が気になってしまったので修正します(^^;
1.for文で+99.9としていますが、これはmoca12980さんの希望の値に変えてください。
2.printf文で%fと書いていますが、%lfが正しいですね
No.3
- 回答日時:
あくまでメンバが全てdoubleである事が前提であれば、
typedef struct _TEST {
double a;
double b;
double c;
} TEST;
int main() {
TESTtest;
double*p;
inti;
test.a = 0.0;
test.b = 0.0;
test.c = 0.0;
p = &test.a;
for ( i = 0; i < 3; i++ ) {
*p = *p + 99.9;
p++;
}
printf( "%f %f %f", test.a, test.b, test.c );
}
と構造体の最初のメンバのアドレスから辿ることができます。ただこの方法は限定された条件でのみ使用可能ですので注意してください。
回答ありがとうございます。
この方法でもうまくいきました。
ちょっと質問には直接関係ないことになるんですが、
このプログラムで、各変数(a1,a2,a3,a4・・)にそれぞれ5+変数数の設定値(b,c,d,e,f,g_a1,g_a2,g_a3・・)を持たせるのに、配列を使って
a[変数数][設定値数]という配列を確保していました。
でも実際には、for文でa[0][0],a[0][1],....,a[2][0],a[2][1],...,a[4][0],.....の順番で同じ計算をさせたい部分があるので、
int xxx[変数数*設定値数];と1次元配列で確保して
int (* abc)[設定値数];
abc=(int (*)[設定値数])xxx;
として
xxx[0]~xxx[設定値数]がabc[0][0]~abc[0][設定値数]に
xxx[設定値数]~xxx[2*設定値数]がabc[1][0]~abc[1][設定値数]
・・・
と2次元配列でも参照できるようにしていまた。
この配列の2次元目?(設定値の部分)を今回変数ごとに構造体で持たせて、
struct test{
//設定値
int b,c,d,e[17];
};
struct test abc[変数数];
として確保して
これを、abc[0].b,abc[0].c,abc[0].d,abc[0].e[0],・・・とfor文で回せるようにabc[0].setteiti[0],abc[0].setteiti[1]・・・と対応するようにしたいと思って質問しました。
もちろん回答いただいたポインタの方法でも思っているとおりの動作をするのですが、もっといい方法があったらアドバイスお願いします。
No.2
- 回答日時:
配列で確保して添え字に定数を使えばいいのではないでしょうか。
enum{
a,
b,
c,
};
struct test{
int abc[3];
};
test xx;
xx.abc[a] = xx.abc[a]+3;
xx.abc[b] = xx.abc[b]+3;
xx.abc[c] = xx.abc[c]+3;
for(i = 0;i < 3;++i){
xx.abc[i] = xx.abc[i]+3;
}
回答ありがとうございます。
enumというのを今日はじめて知りました。
>enum{
> a,
> b,
> c,
>};
この宣言というのは、aが0で、bが1で、cが2ということになるということでいいんでしょうか?
質問のときには書かなかったのですが、構造体のメンバで宣言したいものが厳密には
struct test{
int a;
int b;
int c;
int z[17];
}
と中に配列も入っています。
回答の方法で試してみたのですが、
enum{a,b,c,z[17]};
としてしまうとコンパイルエラーになってしまいます。
これを改善する方法はないでしょうか?
実際のところ、
struct test{int a,b,c,z[17];};
というのを
もう一つの配列abc[20]でも参照できるように
abc[0]がa
abc[1]がb
abc[2]がc
abc[3]がz[0]
abc[4]がz[1]
abc[5]がz[2]
・
・
という風にしたいと思っています。
もしくは、enumを使って
abc[0]がabc[a]
abc[1]がabc[b]
abc[2]がabc[c]
abc[3]がabc[z[0]]
abc[4]がabc]z[1]]
abc[5]がabc[z[2]]
・
・
というのも可能なら、こうやりたいです。。
No.1
- 回答日時:
各メンバへのポインタを配列にすればよいのでは?
int *pxx[] = { &xx.a, &xx.b, &xx.c };
for (i = 0; i < 3; i++)
pxx[i] += 3;
といった具合です。
C++であれば、(本当の意味で)メンバへのポインタを使うことも出来ます。
int TEST::*pxx[] = { &TEST::a, &TEST::b, &TEST::c };
for (i = 0; i < 3; i++)
xx.*pxx[i] += 3;
けれども一番簡単なのは、素直に配列にして、インデックスを列挙体にして名前を付ける方がずっとよいかと思います。
回答ありがとうございます。
最初に書いてある方法でもうまくいきました。
C++でのやり方は、C++がわからないのでどういうことなのか理解できませんでした。
列挙体を使うというのは、どういう方法になるんでしょうか?#2の方のやり方ということでしょうか?
よろしければやり方を教えてください。
構造体自体も最近使い始めたばかりで、いい方法がないかいろいろ検討中です。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
構造体の各メンバにfor文からアクセスする
C言語・C++・C#
-
構造体配列の特定のメンバーをFor~Eachで
Visual Basic(VBA)
-
C言語のポインターに関する警告
C言語・C++・C#
-
-
4
配列を使わずに、変数名を動的にループで回したい
C言語・C++・C#
-
5
C言語で構造体のメンバを簡単に出力する方法ありますか?
C言語・C++・C#
-
6
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
7
C言語 配列の長さの上限
C言語・C++・C#
-
8
0xffffとは?
C言語・C++・C#
-
9
戻り値を返す関数の前に(void)を付ける
C言語・C++・C#
-
10
【gcc・cygwin】multiple definitionエラーの解決法
C言語・C++・C#
-
11
fgetsで拾われる改行文字を削除したい
C言語・C++・C#
-
12
構造体配列内の文字列検索のよい方法を教えてください
C言語・C++・C#
-
13
C言語初心者の質問失礼します。
C言語・C++・C#
-
14
構造体の要素すべてに対する四則演算の方法を教えてください.
C言語・C++・C#
-
15
ファイルから読み込んだデータを構造体に格納できますか?
C言語・C++・C#
-
16
do-while文が禁止される理由
C言語・C++・C#
-
17
構造体配列を引数とするDLL作成し、VBで呼ぶには?
Visual Basic(VBA)
-
18
C言語のポインタに直接アドレスを割り振りしたい
C言語・C++・C#
-
19
VBで構造体の配列を関数に渡す方法?
Visual Basic(VBA)
-
20
unsigned long long 型のフォーマット指定子
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【C言語】全角文字の配列を、全...
-
c言語
-
Windows Formアプリからコンソ...
-
gccを行ってもexeファイルが生...
-
C#でTreeViewのCheckBoxのサイ...
-
逆コンパイルと逆アセンブルの...
-
大量のデータを読み込んで表示...
-
visual studio 2022でのC#プロ...
-
C++でデスクトップGUIアプリ開...
-
c言語でイベントフラグを使った...
-
略語の読み方について
-
C#でログファイルにファイルパ...
-
終端記号、非終端記号とは
-
プログラマー達は何故、プログ...
-
C言語について。
-
10進数からN進数に変換するプロ...
-
パソコン
-
コンソールアプリを作成するの...
-
C言語 配列と関数の練習問題
-
[C言語]fputsとfprintfの違い
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体のメンバをfor文で回したい
-
mailto:の本文に文字数制限はあ...
-
batファイルでtelnetを起動⇒文...
-
動的にプロパティ名を変えたい
-
EXCEL VBA でユーザー定義型デ...
-
UWSCで出目画像カウントしたい
-
Bresenhamのアルゴリズムを用い...
-
時間の平均値を計算する方法を...
-
mailto:の中に&を入れる
-
Wi-Fiが繋がらなくなりました N...
-
アクセスで有給休暇管理表を作...
-
USB3.2 GEN2×2のケーブルにThun...
-
ネットワーク上に存在しないIP...
-
デフォルトドメインの意味
-
Oculus Riftが映らない。セット...
-
MACアドレスで逮捕できる?
-
Active Directory運用でのマス...
-
ネットワーク入門者です、おし...
-
RTX810でローカルルータとして...
-
iPhoneのテザリングにてWiFiをp...
おすすめ情報