あなたは何にトキメキますか?

今C言語の研修中で、バブルソートのプログラムをくんでいます。
それで、以下のように配列で入れ替えではなく、ポインタで入れ替えをしたいのですが、
 dt+i = dt+i+1;
 dt+i+1 = dt2;
で、
 invalid lvalue in assignment
というエラーが出てしまいます。
書き方がまちがっているんでしょうか?
参考書やHPも探してみたのですが、探し方が悪いのかどうにもわかりません。
研修中なので、調べるのも勉強だとは思うのですが、お手上げで・・・・・・
情けないですが、教えていただけると嬉しいです。
/** ソート処理 **/
static int SORT_PROC(void)
{
  int i,m;
  syouhin_typ *dt2;

  /** バブルソートでソート処理 **/
  for(m=0; m<i_cnt-1; m++){
    for(i=0; i<i_cnt-1;i++){
      if(strncmp((dt+i)->code,(dt+i+1)->code,sizeof(dt->code)) >= 0){
         dt2 = dt+i;
         dt+i = dt+i+1;
         dt+i+1 = dt2;
      }
    }
  }
}

ちなみにdtはグローバル変数で、
typedef struct{
  char code[5]; /** 商品コード **/
  char uriage[5]; /** 売上数 **/
}syouhin_typ;

/** グローバル変数 **/
syouhin_typ *dt; /** 商品 **/

としてあります。

A 回答 (7件)

a-kuma> ANSI の規格が無かった頃ならいざ知らず、今どきの普通のコンパイラは構造体の


a-kuma> 代入を許してくれますぜ。

どうも古い頭で済みません。
が、

sora8181> *dt2 = *(dt+i);
sora8181> だとコンパイルの時にコアダンプしてしまうので、
sora8181> dt2 = (dt+i);
sora8181> でコンパイルが通りました。

実行時ならいざしらず、コンパイル時にエラーとなるのは、sora8181さんのコンパイラが
この記述を許していない証拠です。*を落としたのでは意味が変わってしまいますから、
これでコンパイルが通っても困ります。
    • good
    • 0
この回答へのお礼

確かにこれでコンパイルが通っても困ったようです。

結局
syouhin_typ dt2;

...

dt2 = *(dt+i);
*(dt+i) = *(dt+i+1);
*(dt+i+1) = dt2;

にしました。

実行してみたところ、データの最期まで比較をしてくれてなくて
まだ悩み中なんですが、この問題に関してはこれでOKだと思います。
ありがとうございます。

お礼日時:2001/12/13 16:29

>実体については、別ファイルでデータの制限をしない、と言われましてsyouhin_typ *dt[100];


>とできないのです。
えっと、よくわからないのですが、ではグローバル変数 dtはどう初期化されているのでしょうか?まずソコが知りたかったのですが...。
一応、*dt[100]というのも考え方の一つとして、です。
予めファイルサイズ等によりデータ数(n)が解るのでしたら、グローバル変数の宣言を
syouhin_typ **dt;
とし、
dt = (syouhin_typ*)malloc(sizeof(syouhin_typ*) * n);
で可変の領域にすれば良いでしょう。
また、データ数が解らないのなら list形式のデータタイプにすることもできます。
typedef struct {
 syouhin_typ *next;
 char      code[5];
 char      uriage[5];
} syouhin_typ;

データの格納方法は割愛。
    • good
    • 0
この回答へのお礼

初期化はこれまた説明不足で・・・・・・mallocとreallocでエリアを確保しています。
ので、そこで初期化しているはずです。

見当違いな補足で申し訳ないです。
また次の機会にも是非教えていただけたら、と思います。
ではでは。

お礼日時:2001/12/13 17:40

ranx> 実行時ならいざしらず、コンパイル時にエラーとなるのは、sora8181さんのコンパイラが


ranx> この記述を許していない証拠です。

ああ、本当だ。「コンパイルの時にコアダンプしてしまうので」とありますね。
質問が終息しそうですが、最後に使っている環境を教えてもらえるとうれしいなあ > sora8181さん
    • good
    • 0
この回答へのお礼

まだまだソートファイルの完成は遠そうですが、がんばってみます。
環境なんですが、UNIX OS:MS-Windows 95 MS-Windows NT 3.51, 4.0
です。
ちなみに今更すっとぼけたことをお伺いしますが、
環境は?って聞かれたらこんな感じの答えであってますか?
コンパイラがどういうものなのか調べようとしたんですがどうすればいいのやら。

とにかくありがとうございました。
またお伺いすることがあるかと思いますので、そのときはよろしくお願いします。

お礼日時:2001/12/13 17:16

ranx> 結局入れ替えるのは「中身」というのはa-kumaさんのおっしゃる通りなのですが、


ranx> 構造体なので、単純な代入はできません。

何をおっしゃる。

ANSI の規格が無かった頃ならいざ知らず、今どきの普通のコンパイラは構造体の
代入を許してくれますぜ。

で、私の回答に対するお礼については ranx さんの

ranx> それと、dt2の実体領域も忘れないように。

が回答になります。


syouhin_typ dt2;

...

dt2 = *(dt+i);
*(dt+i) = *(dt+i+1);
*(dt+i+1) = dt2;
    • good
    • 0

結局入れ替えるのは「中身」というのはa-kumaさんのおっしゃる通りなのですが、


構造体なので、単純な代入はできません。

> dt2 = dt+i;
> dt+i = dt+i+1;
> dt+i+1 = dt2;

の部分を

memcpy(dt2, dt+i, sizeof(syouhin_typ));
memcpy(dt+i, dt+i+1, sizeof(syouhin_typ));
memcpy(dt+i+1, dt2, sizeof(syouhin_typ));

としましょう。

yatokesaさんのおっしゃる実体領域の確保ですが、
私は
syouhin_typ dt[100];
のような感じでいいと思います。

それと、dt2の実体領域も忘れないように。

あと、内側のループですが、これでも間違いとは言えませんが、
for(i=0;i<i_cnt-1-m;i++)
で良いはずです。
不必要な比較をしています。
    • good
    • 0

>/** グローバル変数 **/


>syouhin_typ *dt; /** 商品 **/
この実体はどのように確保しているのですか?
私がコーディングするならば、
syouhin_typ *dt[100];
:
for(int i = 0; i<100; i++) {
 dt[i] = malloc(sizeof(syouhin_typ));
 sprintf(dt[i]->code, "%d", i); //データ格納
}
というような感じにします。これならばご質問のコーディングが生かされると思います。
まずはどのようなデータ構造になっているのか教えてください。

この回答への補足

説明不足で申し訳ありません。

実体については、別ファイルでデータの制限をしない、と言われましてsyouhin_typ *dt[100];
とできないのです。

補足日時:2001/12/13 16:30
    • good
    • 0

ポインタを使っていますが、結局入れ替えるのは「中身」ですよね。



> dt2 = dt+i;
> dt+i = dt+i+1;
> dt+i+1 = dt2;

*dt2 = *(dt+i);
*(dt+i) = *(dt+i+1);
*(dt+i+1) = *dt2;

です。
    • good
    • 0
この回答へのお礼

早速のお返事ありがとうございます!
*dt2 = *(dt+i);
だとコンパイルの時にコアダンプしてしまうので、
dt2 = (dt+i);
でコンパイルが通りました。

これはポインタだから*をつけろよってことでいいんですかね?
あと、ついでに時間があったらでいいんですが、更に問題だでてきまして・・・・・・
時間があったら教えてください。

先ほどのプログラムだと、
*(dt+i) = *(dt+i+1);
の時点でdt2の値も*(dt+i+1)の値に変わってしまうんです。
これはポインタだからだと思うんですが、
どうしたものかとおもいまして・・・・・・厚かましくてすみません。

お礼日時:2001/12/13 15:47

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


おすすめ情報