はじめまして。

この度、ちょっとした計算プログラムを作ることになったのですが、
タイトルにもありますように、
『動的に作成した構造体配列の中に、さらに動的に構造体配列を作る』
方法がわからずに困っています。
実際には下記のようにプログラムしたいのですが...

-------------------------------------------------
'a'の構造体の中に作られる'b'の配列数は、下記のように
'a'の配列の番号により違い、また'a'の配列数も最初の段階では未定です。

構造体'a'←配列数未定 構造体'b'←配列数未定
a[0]-----b[0]
 |    b[1]
 |    b[2]
 |
a[1]-----b[0]
 |    b[1]
 |
a[2]-----b[0]
 |    b[1]
 .    b[2]
 .    b[3]
 .

-------------------------------------------------
new演算子で'a'の配列は作れたのですが、その中の'b'の数の分だけ
配列を動的に作成する方法がわかりませんでした。

最初は'b'の配列を多めに取って計算すればよいと思っていましたが、
計算過程で'b'の配列数が10000を越えてしまう場合があり、
また'b'の構造体のサイズも大きめなので、断念せざるをえませんでした。

どなたか、このように配列を作成する方法を知っている方がいましたら、
是非教えていただきたいです。

下手な説明ですいません。

A 回答 (2件)

struct typDataB{


 long lData1;
 long lData2;
};

struct typDataA{
 typDataB* uDataB;
};

void main()
{
 typDataA* uDataA;
 uDataA = new typDataA [10];
 uDataA[0].uDataB = new typDataB [20];
 uDataA[0].uDataB[2].lData1=0;
 uDataA[0].uDataB[2].lData2=2;
}
では、外しているかも

この回答への補足

回答ありがとうございました。

ですが、またしても問題が発生してしまいました。
上でいうところの'uDataA'の配列を途中で増やす必要が出てきてしまいました。
もし、動的に配列を増やすことができるようであれば、そのやり方も教えていただきたいです。

よろしくお願いいたします。

補足日時:2001/07/12 23:28
    • good
    • 0

構造体'a'の中で配列bを直接指定せずにポインタ型で指定し、


構造体'b'の宣言は構造体'a'の外に出し、別立てにしたらいかがですか。

つまり、a[0]の次にb[0],b[1],...,b[a[0]],を配置し、
その次にa[1]をメモリ配置しようとしても位置が決まらないわけですから。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q構造体のマスクというメンバ

一般的な構造体についての質問です。
例えば CHOOSECOLOR 構造体のようにメンバにマスクを持つ構造体があって、
その構造体に値を代入する関数を使うには、CHOOSECOLOR 構造体のマスクを
設定し、そのマスクで有効にしたメンバだけが値を入れられるんですよね?
マスクを持つ構造体というのは、それに値を入れる関数を使う前に
マスクを指定してから、その構造体のアドレスを関数の引数にセット
するんですよね?
マスクは無視されて、それ以外の全てのメンバに値が入るというわけでは
ないですよね?

Aベストアンサー

CHOOSECOLORにマスクは無いと思いますよ。
CHARFORMATですか?CHARFORMATならEM_GETCHARFORMATでbCharSetメンバだけに値を得ることになっているからEM_GETCHARFORMATするときのマスクは参照されません。
その他、SCROLLINFOとか普通のやつはマスクで有効にしたメンバだけがGet*()で得られるメンバです。

Q動的配列の構造体の受け渡しについて

動的配列の構造体の受け渡しについて教えていただきたいです。
typedef struct{
int class;
int **matrix;
}pattern_struct;
という構造体を用意しました。
メイン側で
int main(){
pattern_struct *sample,*prototype;
省略
for(k=0;k<9;i++){
for(i=0;i<height;i++){
for(j=0;j<width;j++){
prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j];
}
}
for(i=0;i<height;i++){
for(j=0;j<width;j++){
prototype[1].matrix[i][j]=sample[k].matrix[i][j]+prototype[1].matrix[i][j];
}
}
    ~9まで続きます~
}
省略
}

少し変えていますが、このようなプログラムを記述しました。
記述を省略するためにmallocで作成した構造体配列の足し算をする関数を作りたいのですが、どのように記述するべきなのでしょうか。

動的配列の構造体の受け渡しについて教えていただきたいです。
typedef struct{
int class;
int **matrix;
}pattern_struct;
という構造体を用意しました。
メイン側で
int main(){
pattern_struct *sample,*prototype;
省略
for(k=0;k<9;i++){
for(i=0;i<height;i++){
for(j=0;j<width;j++){
prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j];
}
}
for(i=0;i<height;i++){
for(...続きを読む

Aベストアンサー

>switch の立場はいったいどこへとは?

#2でちゃんと説明してありますけど。

>prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j];

switch (sample[k].class)
{
case 0:
prototype[0]~ // prototype[0] の 0 はsample[k].classの値と一緒
break;
case 1:
prototype[1]~// prototype[1] の 1 はsample[k].classの値と一緒
break;
~ これを9まで繰り返し
}

これは次に書き換えられるわけで

switch (sample[k].class)
{
case 0:
prototype[sample[k].class]~
break;
case 1:
prototype[sample[k].class]~
break;
~ これを9まで繰り返し
}

さらにswitchも意味がないので

prototype[sample[k].class].matrix[i][j]=sample[k].matrix[i][j]+prototype[sample[k].class].matrix[i][j];

になるわけですが。
なのでswitchの立場がない。

変えたのは少しのつもりなんでしょうけど質問に書かれてるのと処理的には別物になってますが、これであってるんですか?

>switch の立場はいったいどこへとは?

#2でちゃんと説明してありますけど。

>prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j];

switch (sample[k].class)
{
case 0:
prototype[0]~ // prototype[0] の 0 はsample[k].classの値と一緒
break;
case 1:
prototype[1]~// prototype[1] の 1 はsample[k].classの値と一緒
break;
~ これを9まで繰り返し
}

これは次に書き換えられるわけで

switch (sample[k].class)
{
case 0:
prototype[sample[k].class]~
break;
...続きを読む

Q条件によって構造体のリスト構造を変えたい

こんにちは。

C(C++)で構造体を使っているのですが、まだまだ未熟で使い方が良く分かりません。以下のことを実施したいのですが、やり方をどなたかご教授頂けませんでしょうか。よろしくお願いします。

条件によって構造体のリスト構造を変えたいのです。
例えば、
条件1の場合は
構造体a→構造体b

条件2の場合は、
構造体a→構造体c

上記のようにです。そして構造体のルートから参照先をたどっていくことで、配下の構造体の値を取得したいのです。

文法上許されないようですが、イメージとしては、
struct a aa;
aa.c->b.aa

ということをしたいのです。よろしくお願いします。

struct a{
char a;
char b;
struct c;
:
};

struct b{
char aa;
:
};

struct c{
:
:
};

Aベストアンサー

一番手っ取り早いのは、構造体aの中に、構造体bと構造体cの両方のポインタを持たせておいて、使わない側にはNULLを入れるといった方法でしょうか。

struct a
{
 /* .bまたは.cのNULLではない方が有効 */
 struct b *b;
 struct c *c;
};

他には、構造体aと構造体bの最初のフィールドの型を同じにしておいて、そこにaかbかを判別できる値を格納するようにし、構造体aと構造体bの共用体へのポインタを構造体aに持たせるといった方法です。

struct b
{
 char tag; /* 'b'を格納 */
 ...
};

struct c
{
 char tag; /* 'c'を格納 */
 ...
};

struct a
{
 union
 {
  struct b;
  struct c;
 } *p; /* .p->b.tagが'b'なら構造体b, 'c'なら構造体c */
};

好みかもしれませんが、私なら多分前者を使います。

一番手っ取り早いのは、構造体aの中に、構造体bと構造体cの両方のポインタを持たせておいて、使わない側にはNULLを入れるといった方法でしょうか。

struct a
{
 /* .bまたは.cのNULLではない方が有効 */
 struct b *b;
 struct c *c;
};

他には、構造体aと構造体bの最初のフィールドの型を同じにしておいて、そこにaかbかを判別できる値を格納するようにし、構造体aと構造体bの共用体へのポインタを構造体aに持たせるといった方法です。

struct b
{
 char tag; /* 'b'を格納 */
 ...
};
...続きを読む

Qchar *name1[4] とchar name2[][4] の違いについて

C言語のことで質問があります。

char *name1[4]は
char *name1[4] = {"abcdefghi","jkl","l","mn"};
と宣言でき,ポインタを4つ確保した形となりました。

char name2[][4]は
char name2[][4] = {"abc","def","ghi","jkl","mno","pqr","stu","vwx"};
と4文字以内の文字列を初期化した数だけ確保した形となりました。

この結果からchar *name1[4]の意味は,char name2[][4]ではなくchar name2[4][]に近いと思いました。
しかし,char name2[4][]ではポインタを4つ確保した事にはならないみたいでコンパイルが通りません。
*name1[4]では4つのポインタを確保できるのに~と思ってしまいます。

ポインタと配列は別物と考えるべきなのでしょうか?
訳の分からない質問かもしれませんが,
何卒ご指導いただくようよろしくお願いします。

Aベストアンサー

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり、この場合のa1は、
変数ではなく、定数のようなものなのです。

複合的なケースについて見てみましょう。
char **q1; ポインタへのポインタ
 q1,*q1,**q1,q1[0],*q1[0],q1[0][0] のいずれも変数として
 扱うことができます。(値を代入することが文法的に許されます。
 ただし、実行時にはアクセス違反になる場合もあります。)
char q2[4][4]; 二次元配列
 q2,q2[0]は変数として扱うことができません。q2[0][0]のように
 して、初めて変数として扱えるようになります。
char *q3[4]; ポインタの配列
 q3は変数として扱うことができませんが、q3[0],*q3[0],q3[0][0]
 はいずれも変数として扱うことができます。
 なお、この定義は char *(q3[4]); とした場合と全く同じ意味です。
char (*q4)[4]; 配列へのポインタ
 q4,(*q4)[0],q4[0][0]はいずれも変数として扱うことができます。
 しかし、*q4,q4[0]は変数として扱うことができません。

char *name1[4]; と char name2[4][]; は確かに似ています。しかし
違うところもあります。それは、name1[0] が変数として扱えるのに
対し、name2[0] には値を代入できないという点です。(データの
具体的な構造については、inthefloiさんが書いておられる通りです。
> char name2[4][]ではポインタを4つ確保した事にはならないみたい
というのも、全くその通りで、配列の定義では、ポインタ変数の領域
を確保する余地はないのです。

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり...続きを読む

Q構造体の宣言

下記のように構造体の宣言をした所、

struct B_PARAM test;

「`test' の領域サイズがわかりません」というエラーになってしまいました。この構造体を宣言し、値を入れていこうとしています。

ヘッダファイルに構造体の形は定義してあるのですが、
構造体の中に構造体があるからでしょうか?

またこの構造体を正しく宣言するにはどうすればいいのでしょうか?

Aベストアンサー

typedef struct _B_PARAM {
char p1;
char p2[2];
} B_PARAM;

の、_B_PARAM は、構造体の「タグ名」です。
これは、sutruct とともに使う名前です(C++ struct 無しでもOK)
ですから、この例では、struct _B_PARAM で正解です。

後ろの、B_PARAM は、typedef した名前です。

おおざっぱに言えば、
struct _B_PARAM {
char p1;
char p2[2];
}
という構造体を、B_PARAM という名前で読み替えることを宣言しています。
ですから、こちらを使うのであれば、struct 無しの
B_PARAM test; で正解です。

構造体は必ず typedef しなければならないというものではありません。

Q[VC++][MFC][SDI]ダイアログコントロールもしくわツールバー!!詰まってます!!

現在VC++6.0でMFCを使いSDIのプログラムを作っているのですが、フォームにダイアログバーを張っています。

これをツールバーのように自由に動かしたり、左右上下にドッキングさせたり。
これって実現可能でしょうか?

色々ためしてみたんですが無理でした。
やっぱ不可能ですかね?

これが無理なんであればデフォルトで作成されるツールバー([新規作成][開く][保存]等が入ってる)にコントロール(ボタンやリストボックス)を追加して使用、と考えているのですがこれも難しい!!!


まだまだ未熟者なのですがどうかご存知の方おられましたらご教授ください!!
よろしくお願いします!!

Aベストアンサー

Dannerです。
参考URL(英語)を載せておきます。

参考URL:http://www.codeguru.com/Cpp/controls/toolbar/placingcontrolsintoolbars/article.php/c2505/

Q構造体→文字列→構造体 をする方法

VB6.0の話です。

 不特定の構造体を文字列(String)に格納し、これを最初の構造体に戻す事はできませんか?

 具体的には「共有メモリを使い構造体を文字列にして格納>別ウインドウで文字列を取得して構造体に戻す」と言う事をやりたいんです。
 共有メモリに不特定の構造体をいれる方法でもいいんですが…VALIANTだとサイズが大きすぎて実用性がありませんし、違う主旨の質問をするのも良くないので回答はあくまで「構造体→文字列→構造体 をする方法」と言う事でお願いします。

Aベストアンサー

APIを使えば出来ます。

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (cStr1 As Any, cStr2 As Any, ByVal iLen As Long)


構造体→文字列
Call CopyMemory(strB, ByVal typeA, Len(typeA))

文字列→構造体
Call CopyMemory(typeA, ByVal strB, Len(typeA))

ただし構造体のメンバに配列があると使えません(VBの配列はメモリを連続してとらない為、メモリーリークします)。

また構造体の中身は string *5 などの固定長である必要があります。

以上です。

Q共用体の配列 [C言語]

今C言語のプログラムを組んでいたのですが、共用体の配列あるわけないと思いつつ共用体の配列を宣言したソースをコンパイルして見ました。そしたら普通にコンパイルできてしまったんです。びっくりしてその配列に値を代入したのですが、それはコンパイルエラーが出ました。共用体の配列なんてあるのでしょうか?回答よろしくお願いします。

Aベストアンサー

あります。

QPGにおいて構造体や列挙型はいつ使いますか?

PGにおいて構造体や列挙型はいつ使いますか?

構造体でテーブルみたいなものに一旦入れて、個別に取り出すときに使うと思うのですが、
DBを使ってたら、構造体を使う場所がよくわかりません。

どういうプログラミング時に構造体・列挙型を使うのか教えてください。

Aベストアンサー

複数の項目を一元管理したいとか、あとで(他人が)見た時に判り易いためとか、使う理由は様々あると思います。

例えば、RPG(ゲーム)のプログラミングで、
キャラクターのパラメーターとしてはHP、MP、ちから、すばやさ、EXP等々ありますね。

これを1つの構造体として定義しておく。

主人公 AS 構造体
仲間1 AS 構造体

のようにすれば、1人1人の各パラメータを宣言する手間が省けますし、
何より見やすいですね。
呼び出すときも、主人公.HP、仲間1.HP となってれば、判り易いです。

Q[動的配列]C言語の勉強で簡単な単語帳プログラム

C言語の勉強として以下のような簡単なプログラムを作りました。
テキストファイルからユーザが入力した単語を検索し、ヒットしたものだけ
その単語とその説明を表示するというプログラムです。

正常に動いているようなので、
つぎはループごとに、読み込んだ文字数に合わせて
配列(mean)の要素数を動的に確保するということを
しようと思うのですがどのタイミングでmallocやreallocを入れればよいのか
いまいちよくわかりません。

また、このプログラムの欠点などありましたら教えていただけると助かります。
よろしくお願いします。

---------------------------------------------------------------------
//マイ単語帳プログラム
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

main(){

char input[100];//ユーザが入力した文字列を格納
char tango[200];//ファイルの単語
char mean[1000];//ファイルの説明
char conti;//検索を続けるかどうかの入力
int flag;//検索単語がヒットした場合に立てるフラグ
FILE *fp;

//単語ファイルのopen
if((fp=fopen("tango.txt","r"))==NULL){
printf("ファイルが開けません。");
exit(1);
}

/*******************ファイルからの文字列読み込み****************************/
//Yが入力されるまで検索を続ける
do{
printf("検索する単語を入力してください。\n");
scanf("%s",input);
printf("検索対象:%s\n\n",input);

flag=0;//ヒットしたかどうかのフラグの初期化
while((fscanf(fp," %s %s",tango,mean))!=EOF){//fscan 書式を指定して読み込める。
if(strcmp(tango,input)==0){//strcmpは2つの引数が同じ時0を返す
printf("%s\n%s\n\n\n",tango,mean);
flag=1;//ファイル内に単語があった場合にフラグを立てる。
}
}

rewind(fp);

if(flag==0){
printf("その単語は登録されていません。\n");
}

printf("検索を終了しますか? ==> Y\n");
printf("検索を続けるにはY以外の文字を入力してください。\n");
scanf(" %c",&conti);//scanfの問題点を回避するために読み込み前に半角スペース
}
while(conti!='Y');

/**************************************************************************/
fclose(fp);
return;
}
----------------------------------------------------------------
tango.txt

apple リンゴ
SMTP 電子メールの送信や転送を行うためのプロトコル。
rewind 形式:rewind(ファイルポインタ); C言語のファイルシステム関数。ファイルの現在位置をファイルの先頭に置くことができる。

C言語の勉強として以下のような簡単なプログラムを作りました。
テキストファイルからユーザが入力した単語を検索し、ヒットしたものだけ
その単語とその説明を表示するというプログラムです。

正常に動いているようなので、
つぎはループごとに、読み込んだ文字数に合わせて
配列(mean)の要素数を動的に確保するということを
しようと思うのですがどのタイミングでmallocやreallocを入れればよいのか
いまいちよくわかりません。

また、このプログラムの欠点などありましたら教えていただけると助かります。
...続きを読む

Aベストアンサー

>やはりできないのですかね?(^_^;)

meanを読み込む前にmeanのサイズを取得する方法がないと…無理でしょうね。

あるいは…1文字(1バイト)ずつ読み込んで、改行位置に到達しなかったらrealloc()で拡張して、さらに1文字(1バイト)読み込む…とか。
realloc()自体は1バイト単位でやる必要は無いかも知れませんけどね。
# そこらヘンは http://oshiete.goo.ne.jp/qa/6961996.html 辺りでも話題になってますが。

>要するにヒットしたらすぐに抜け出す方が効率がいいということですかね?
>テキストファイルのインデックスは重複しないように作成するつもりです。

仕様次第…です。
 man (成人の)男,男子
 man [無冠詞で総称的に] (女と対比して)男
 man オンラインリファレンスマニュアルのインターフェース
とか、複数の意味があるものを無視するかどうか…でしょう。
最初にヒットしものだけ。重複はない。というのであれば、ヒットした時に読み込みループを抜けた方が動作としては軽い…かと。

>strcmpする前にワンクッションおいて大文字小文字を区別しないような動作を入れるといいということでしょうか?

stricmp()を使う。なんて方法もあります。
input[]に入るのが、ASCIIの場合に限るかも知れませんけど。
# shift-jisが入った場合にstricmp()が正しく動作するかは…ライブラリ次第でしょうな。

>やはりできないのですかね?(^_^;)

meanを読み込む前にmeanのサイズを取得する方法がないと…無理でしょうね。

あるいは…1文字(1バイト)ずつ読み込んで、改行位置に到達しなかったらrealloc()で拡張して、さらに1文字(1バイト)読み込む…とか。
realloc()自体は1バイト単位でやる必要は無いかも知れませんけどね。
# そこらヘンは http://oshiete.goo.ne.jp/qa/6961996.html 辺りでも話題になってますが。

>要するにヒットしたらすぐに抜け出す方が効率がいいということですかね?
>テキストファイルのインデッ...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング