ページ 11

ポインタ

Posted: 2008年5月04日(日) 16:16
by kazuoni
お邪魔します。
ずっとポインタについて勉強してたんですが・・・いくつか疑問が出てきましたので質問させていただきます。

typedef struct{
	const char *abc[3];
}states_t;

states_t states[10]
このように定義したのちにmain文で、↑の構造体でstates[0]でのabc[/url]に、
abc[0]→"要素1"
abc[1]→"要素2"
abc[2]→"要素3"
としたいのですが、
states[0].*occupation[3]={"要素1" , "要素2" , "要素3"};
と記述ができないとすると、どう記述をしたら良いのでしょうか?もしかしたら構造体の中が違うのでしょうか?


メモリの動的確保のところを勉強したんですが、イマイチ使う理由が分からないです。例えばゲームプログラミングでいうと、ゲームの前半では使用していたものが、後半に入ると全く使わなくなるので、メモリを解放すれば、少しでも処理が軽くなる!みたいなことなんでしょうか?あとリスト処理・・・ぐらいですか?

よろしくお願いします。

Re:ポインタ

Posted: 2008年5月04日(日) 17:24
by
#include <stdio.h>

typedef struct{
    const char *abc[3];
}states_t;

int main(void)
{
    states_t states[10];
    
    states[0].abc[0]= "要素1";
    states[0].abc[1]= "要素2";
    states[0].abc[2]= "要素3";
    printf("%s\n", states[0].abc[0]);
    printf("%s\n", states[0].abc[1]);
    printf("%s\n", states[0].abc[2]);
    return 0;
}


なお、main「文」ではなく、main「関数」です。

Re:ポインタ

Posted: 2008年5月04日(日) 19:51
by 管理人
動的確保は要素をいくつ用意すればいいか解らない時などによく使います。
例えばリプレイ記録を作る為に、ユーザーが入力した情報を記録しないといけないとします。
わかりやすく単なる配列で説明します。

今キーの入力情報が10種類必要だとします。
(左、右、上、下、ジャンプ、加速、ポーズ・・・等)
60FPSで動いているのならこの10*60個の要素が1秒間に必要です。
30分記録したいのなら10*60*60*30個の要素が必要です。
これは約100万個であり、1メガに相当します。
BYTE型で用意したとしても、1メガバイトも配列だけで占有してしまう事になります。

しかしプレイヤーが30分でクリアするだろうと思っても、途中で点数稼ぎをする為に、わざとゆっくり
行くかもしれないし、どれ位の時間でクリアするかわかりませんよね。
せっかく入念に点数稼ぎしてても、クリア直前になって「リプレイ情報が記録できなくなりました」なんてログが出たらガッカリすると思います。

そこでどうすればいいのでしょう?
使うかどうかもわからないのに、多めに・・1000万個位確保しておくのが適切でしょうか?
いや、使う時に使う分だけ増やす方がいいですよね。

他にもいい例はあるかもしれませんし、リプレイデータはキー入力データを圧縮したりしますし、ビットのオンオフで入力状態を管理する事が多と思うのでいい例だったかどうかわかりませんが、ご紹介しました。

Re:ポインタ

Posted: 2008年5月05日(月) 14:55
by kazuoni
返事が送れて申し訳ありませんでした。。・さん、管理人さんご回答ありがとうございました!
states[0].abc[0]= "要素1";
states[0].abc[1]= "要素2";
states[0].abc[2]= "要素3";
は一つにまとめて定義はできないんでしょうが・・・?

なんだかまだ自分は動的確保をうまく使いこなせそうにないですね^^;w
それよりもポインタをもっと煮詰めないといけないです・・・(泣)

Re:ポインタ

Posted: 2008年5月05日(月) 15:11
by Justy
>は一つにまとめて定義はできないんでしょうが・・・?
 望む形かどうかはわかりませんが、
こうすれば一応纏められます。
[color=#d0d0ff" face="monospace]#include <stdio.h>

typedef struct{
    const char *abc[3];
}states_t;

static const states_t default_state_value = { "要素1", "要素2", "要素3" };

int main(void){
    states_t states[10];
    states[0] = default_state_value
    printf("%s\n%s\n%s\n", states[0].abc[0], states[0].abc[1], states[0].abc[2]);
    return 0;
}
[/color]

Re:ポインタ

Posted: 2008年5月05日(月) 15:23
by tk-xleader
mallocで確保するメモリは、スタックではなくヒープ領域から確保される事が多いです。スタックはプログラムコードの展開場所である事も多いので、スタックを消費すると実行できなくなる事もあります。

そんなに大きい配列を必要とするならば、vectorを使うというのはどうでしょうか?

Re:ポインタ

Posted: 2008年5月05日(月) 15:50
by ibis
ところで、char *abc[3] というのは2文字の文字列へのポインタではないのですか?

Re:ポインタ

Posted: 2008年5月05日(月) 16:15
by kazuoni
justyさん、tkmakwins15さんご回答ありがとうございます!

>states[0] = default_state_value
申し訳ないのですが、構造体の中にはconst char型のみではなく、int型もある場合、これは使えないのですが、ほかにはあるでしょうか?
自分のやりたいこととして、構造体はRPGのキャラクターのステータスをまとめるために使っています。

vectorですか。。使ったことないですね。。またちょっと調べてきます・・・

>char *abc[3] というのは2文字の文字列へのポインタではないのですか?
abcは<charへのポインタ型>の大きさ3の配列だと思いますよ。

Re:ポインタ

Posted: 2008年5月05日(月) 16:17
by バグ
いえ、char型の配列ではなく、char型へのポインタの配列です。

Re:ポインタ

Posted: 2008年5月05日(月) 16:18
by tk-xleader
よく考えたらC++ではなくC言語での開発ですね。失礼しました。C言語ではvectorは使えません。

Re:ポインタ

Posted: 2008年5月05日(月) 16:40
by Justy
構造体の中にはconst char型のみではなく、int型もある場合、
これは使えないのですが、ほかにはあるでしょうか

 なるほど、構造体の中の文字列へのポインタの配列の部分だけを初期化したい、と。
 なら、その部分だけを別の構造体にすれば一応出来ます。

[color=#d0d0ff" face="monospace]#include <stdio.h>

typedef struct hoge_strings_t {
    const char *p[3];
} hoge_strings_t;

typedef struct states_t {
    hoge_strings_t abc;
    int d;
    int e;
    int f;
    int g;
}states_t;

static const hoge_strings_t default_hoge_strings = { "要素1", "要素2", "要素3" };

int main(void) {
    states_t states[10];
    states[0].abc = default_hoge_strings;
    printf("%s\n%s\n%s\n", states[0].abc.p[0], states[0].abc.p[1], states[0].abc.p[2]);
    return 0;
}[/color]

Re:ポインタ

Posted: 2008年5月05日(月) 17:03
by kazuoni
Justyさんご回答ありがとうございます!

完璧です!!ww新しい構造体を入れるのは全く考え付かなかったです。。

あと・・・staticは静的な場所(?)が割り当てられて、プログラムの実行が開始されてから終了するまで、ずっと同じ場所って覚えているんですけど・・・プログラミングの中で変更することのないものはすべてstaticをつければよいのでしょうか?

Re:ポインタ

Posted: 2008年5月05日(月) 17:24
by tk-xleader
プログラム中で変更しない変数には、staticではなくconstをつけるといいです。

Re:ポインタ

Posted: 2008年5月05日(月) 18:10
by kazuoni
たびたびすみません。。
>extern static const hoge_strings_t default_hoge_strings
をヘッダーに書くと「2 つ以上のストレージ クラスが指定されています」と出てしまうのですが・・・staticを書かなければうまく通ります。staticは書かなくても大丈夫ですかね?

Re:ポインタ

Posted: 2008年5月05日(月) 18:39
by Justy
>staticは書かなくても大丈夫ですかね?

 特に問題はないと思います。
 staticにしたのはそのファイルの中だけで有効にしたかっただけですから。
 externで外に出してしまうなら、staticは外さなければなりません。

Re:ポインタ

Posted: 2008年5月05日(月) 18:55
by kazuoni
Justyさん、ご回答ありがとうございます^^

今思えばヘッダーに入れる必要は特になかったので、結局最初の記述で落ち着きました(汗)
単純な質問の連続、申し訳ありませんでした。そして親切なご回答ありがとうございました!

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