←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.4272

while(変数)の終了条件
投稿者---k(2005/07/13 11:19:04)


windowsNT ボーランドC++32
以下の処理は昇順の並べ替えです。
質問はascend_data関数内で使用しているwhile(i)とwhile(j)のそれぞれのループについてです。
whileは0でないなら真でループを回り、0なら抜けるとテキストにかかれていました。
ここではiとj構造体型のポインタでノードの最後の次はNULLで、0(終了条件は)でないと思うのですがなぜこのようにかけるのか、分かる方ご教授お願いします。

void swapNodeForBubble( list_t *aA, list_t *aB ) {
  int tmpNum;
  int tmpDepartment;
  int tmpSection;
  int tmpSubsec;
  char tmpName[NAME_NUM];

  /* 入れ替えのために、値を保存しておく。 */
  /* a=b; b=a とやると、入れ替えではなく、a=b になってしまう。 */
  tmpNum = aA->num;
  tmpDepartment = aA->department;
  tmpSection = aA->section;
  tmpSubsec = aA->subsec;
  strcpy(tmpName, aA->name);

  aA->num = aB->num;
  aA->department = aB->department;
  aA->section = aB->section;
  aA->subsec = aB->subsec;
  strcpy(aA->name, aB->name);

  aB->num = tmpNum;
  aB->department = tmpDepartment;
  aB->section = tmpSection;
  aB->subsec = tmpSubsec;
  strcpy(aB->name, tmpName);
}

void ascend_data(list_t *main_head) {
  list_t *i;
  list_t *j;
  i = main_head->next;
  while(i) {
    j = i->next;
    while(j) {
      /* 大小関係が逆の時は、入れ替える */
      if( i->num > j->num ) {
        swapNodeForBubble(i, j);
      }

      j = j->next;
    }
    i = i->next;
  }
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:while(変数)の終了条件 4273 まきじ 2005/07/13 11:53:13
<子記事> Re:while(変数)の終了条件 4274 YuO 2005/07/13 12:40:34


No.4273

Re:while(変数)の終了条件
投稿者---まきじ(2005/07/13 11:53:13)


>ここではiとj構造体型のポインタでノードの最後の次はNULLで、0(終了条件は)でないと思うのですがなぜこのようにかけるのか

X3010 の 6.3.2.3 に
「値0をもつ整数定数式又はその定数式を型 void* にキャストした式を空ポインタ定数」
と記載されています。


この投稿にコメントする

削除パスワード

No.4274

Re:while(変数)の終了条件
投稿者---YuO(2005/07/13 12:40:34)


>whileは0でないなら真でループを回り、0なら抜けるとテキストにかかれていました。

while (expr)
とは,
(expr) != 0である間ループを続ける,ということです。

ここで,exprがポインタ型であれば,0は空ポインタ定数として扱われます。


>ここではiとj構造体型のポインタでノードの最後の次はNULLで、0(終了条件は)でないと思うのですがなぜこのようにかけるのか、分かる方ご教授お願いします。

NULLとは空ポインタ定数につけた#defineでしかないので,
iやjが空ポインタになったときに,ループから抜けます。



この投稿にコメントする

削除パスワード

No.4275

Re:while(変数)の終了条件
投稿者---k(2005/07/13 13:15:07)


お二方ありがとうございました。謎がわかりました。
NULLポインタ定数。空ポインタ。などから自分でも以下のサイトで確認しました。結構理解できました。

http://okuyama.mt.tama.hosei.ac.jp/unix/C/slide50-1.html


この投稿にコメントする

削除パスワード

No.4276

Re:while(変数)の終了条件
投稿者---円零(2005/07/13 13:30:07)


便乗質問で恐縮ですが、要するに、

・ソースコードのテキストそのものには0が書かれていなくても、while文は実際には定数0を含んでいる
・今回のケースにおいて、この定数0はポインタ型の変数と比較されているためコンパイル時にNULLポインタに変換される
・二つのNULLポインタを比較した場合、常に等しいことが保証されている

よってiやjがNULLポインタのときループは終了する
ということでよろしいでしょうか?


この投稿にコメントする

削除パスワード

No.4277

Re:while(変数)の終了条件
投稿者---円零(2005/07/13 13:31:43)


すみませんコンパイル時じゃなくてプリプロセスでしょうか。


この投稿にコメントする

削除パスワード

No.4278

Re:while(変数)の終了条件
投稿者---円零(2005/07/13 13:40:57)


ああ削除したいときに限って削除パスワードが入ってない。

プリプロセスはNULLを0にするときでした。


この投稿にコメントする

削除パスワード

No.4284

Re:while(変数)の終了条件
投稿者---RAPT(2005/07/13 23:38:54)


MSDN> while( expression ) 
MSDN>     statement
MSDN> while キーワードは、expression が 0 になるまで繰り返し statement を実行します。

while() の()内の値は、定数かどうかは関係ありません。
あくまでその「式・値」を評価した結果が、0 か 非0 かで判断されます。

C言語では、多くの処理系では、
#define NULL (void *)0
と定義されているかもしれません。

C++言語では、
#define NULL 0
と定義されています。

上記MSDNの引用で、expression が非ポインタ型であるとき、
expression != 0 が成立する間、statement を実行します。

expression がポインタ型であるとき、
expression != NULL が成立する間、statement を実行します。

expression が式・真偽値であるとき、
expression != false が成立する間、statement を実行します。

※C言語では、式の評価結果が偽(false)は 0、真(true)は 1 です。



この投稿にコメントする

削除パスワード

No.4291

Re:while(変数)の終了条件
投稿者---YuO(2005/07/14 11:53:59)


>・ソースコードのテキストそのものには0が書かれていなくても、while文は実際には定数0を含んでいる

whileが含む,というより反復文が反復するための定義です。
それを「含む」というのであれば,含みます。
ref) ISO/IEC 9899:1999 6.8.5 Iteration statements / Paragraph 4


>・今回のケースにおいて、この定数0はポインタ型の変数と比較されているためコンパイル時にNULLポインタに変換される

整定数式0(またはそれをvoid *にキャストしたもの)は,
常に空ポインタ定数として機能します。

つまり,ポインタと0の比較では,常に0は空ポインタとして扱われます。
ref) ISO/IEC 9899:1999 6.3.2.3 Pointers / Paragraph 3


>・二つのNULLポインタを比較した場合、常に等しいことが保証されている

これは,ISO/IEC 9899:1999 6.3.2.3 PointersのParagraph 4に書かれていますので,保証されています。


>よってiやjがNULLポインタのときループは終了する
>ということでよろしいでしょうか?

よいと思います。



この投稿にコメントする

削除パスワード

No.4300

Re:while(変数)の終了条件
投稿者---円零(2005/07/14 20:42:38)


ありがとうございます。

>つまり,ポインタと0の比較では,常に0は空ポインタとして扱われます。
>ref) ISO/IEC 9899:1999 6.3.2.3 Pointers / Paragraph 3

ええ、実行時、比較が行われる時点では必ず、既に空ポインタに変換されていると思うのですが、
ポインタ型とconst int型の比較として警告を受けない以上は、要するにコンパイルされた時点で既に「変換」(例えば、ビットパターンとして展開)されているということか、と考えてしまったわけです。
しかし「ポインタ定数」なんてものはないのですから土台無茶な発想ですし、
と言うか単に整数定数式であると同時に「空ポインタ定数」でもあるから型チェックで弾かれない、と考えればいいだけですよね。
さらに考えてみれば、たとえ仮にコンパイルの時点で空ポインタのビットパターンを作る実装だったとしても、それは実装の話であってC言語の仕様とは関係ない話だし…


JIS X 3010、6.5.9等価演算子、の「制約」
次のいずれかの条件を満たさなければならない。
― 両オペランドは算術型をもつ。
― 両オペランドとも適合する型の修飾版又は非修飾版へのポインタである。
― 一方のオペランドがオブジェクト型又は不完全型へのポインタで他方がvoidの修飾版又は非修飾版へのポインタである。
― 一方のオペランドがポインタで他方が空ポインタ定数である。

で、思いっきり4番目に書いてありました(whileの説明で等価演算子を使っているわけではありませんが、多分これに準じるのでしょう)。
最初は関係ある話のつもりだったんですが、結局本題と関係の薄い方向に流れてしまってすみません。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity