C言語なら、俺に聞け! <11>

このエントリーをはてなブックマークに追加
>>907は質問者か?
マルチポストした上に“正しい?”ってのは随分な態度ですね?
>905
それのどのあたりが循環リスト?
単に終端子がNULLでなく、thisなだけやないかと。
>>907
正しい。めっちゃめちゃ正しいですが、何か?
911910:02/01/28 18:39
>>909
あ、そういえば、たしかに hoge->next == NULL で お尻なのではない
(自分自身を指すと お尻である、と定義する) リストの実装って
ほとんど見たことがなかったよ…。
912デフォルトの名無しさん:02/01/28 18:40
循環してないぞ! 単方向リストですやん
913905:02/01/28 18:47
>>909
スマン、間違えた
以下の認識で合ってる?

循環リスト
□→□→□→□→□→□→□
↑           │
└───────────┘

終端子がthis(904のリスト構造)
# ところでこれって何かメリットあるの?
□→□→□→□→□→□→□─┐
            ↑ │
            └─┘
914デフォルトの名無しさん:02/01/28 18:47
ん?俺はリスト構造なんか勉強したことないけど
知らない間にほげ->next=NULLが終わりだとして
「これがリスト構造ってやつだな」って思ってつかってたぞ。
オブジェクト指向も言葉の意味がちんぷんかんぷんだったけど、
今では何気にオブジェクト使ってるぞ。クラスの使い方も
わかったぞ!最初はグローバル変数で管理してたけどな!
ごるぁーーー
915デフォルトの名無しさん:02/01/28 18:48
HSIZEが10やのに、hをlongで確保するんかい!
無限ループに陥るといやだから循環リストは使わない。
メリットっていったってどっちもどっちでしょ?
917905:02/01/28 18:51
あぁ、思いっきりズレてる...
ちょっとモナ板に逝って練習してくる。
918905:02/01/28 19:06
完全にズレは消せていないけど...
1)循環リスト
□→□→□→□→□→□→□
↑                │
└───────────┘
2)終端子がthis
□→□→□→□→□→□→□─┐
                 .↑  │
                 .└─┘
3)終端子がNULL
□→□→□→□→□→□→□→NULL

普通は単方向リストの場合、3)が使われると思うけど、
2)を使う理由が知りたいです。
1)と2), 3)の違いは>>916で理解しました。
アクセス違反を起こさないようにするためとかですか?
(見物人)
>>918
違いなんてあるの?
終端を識別するのにNULLポインタ(無効なアドレス値)を使用するか、
自分自身(意味的に無効な値)を使用するか、趣味の問題では?
# 積極的な理由があるのなら、私も知りたいデス…
最後がNULLだと、a->b->…のbを削除するとき、a.next=b.next; free(b);で済むのに、
2)だと判定が1こ必要になるなぁ、なにかメリットあるんだろうか…
0にするかNULLにするか、はたまたNULにするか'\0'にするか、悩まなくて済む(w
>アクセス違反を起こさないようにするためとかですか?
NULLでアクセス違反を起こすようなコードは、
むしろ、さっさと起こして貰った方が健全かと。
924デフォルトの名無しさん:02/01/28 22:10
>>902
&arrと&arr[0]では、型が違うんではないの。
925デフォルトの名無しさん:02/01/28 22:17
arrと&arr[0]はいっしょだけどね
配列についてはarrと&arrは同じ値をかえす。
arrはポインタと書式を一致させるために付け加えられた文法
>>925
ちがう。arrはchar[4]、&arr[0]はchar*。値を評価するときにchar[4]がchar*
にpromoteされるというだけ。
sizeof 使ってみれば違うのが解かるよ。
929デフォルトの名無しさん:02/01/29 01:42
ポインタに代入されるアドレスは一緒じゃないの?
arrと&arr[0]って、、、本には書いてあったのに??
柏原正三に ゆーてんか!
930デフォルトの名無しさん:02/01/29 01:46
sizeofって、、配列の型によってかわるやないけ〜
arrは
 ・sizeof と 単項& のオペランドになるときは、char[4]
 ・それ以外は char* const
として扱われるんだった気がする。
もう一通りくらい配列扱いになる場合があったかも。
VC(C++)だとこうなった
void foo()
{
char arr[4];
struct{int n;}n;

n = arr;
n = &arr;
n = &arr[0];
}
コンパイル中...
test.cpp
c:\test\test.cpp(6) : error C2679: 二項演算子 '=' : 型 'char [4]' の右オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照)
c:\test\test.cpp(7) : error C2679: 二項演算子 '=' : 型 'char (*)[4]' の右オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照)
c:\test\test.cpp(8) : error C2679: 二項演算子 '=' : 型 'char *' の右オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照)
cl.exe の実行エラー
エラーだしてコンパイラに型を教えてもらうのか。
それ、もらった。
>>933
>>932はいつも教えてもらってんだろうなぁ。
935:02/01/29 21:31
char *hogehoge="hogehoge";
char *hugahuga=malloc(sizeof(char)*24);
strcpy(hugahuga,"hugahuga");


hogehoge と hugahugaの違いはなんだ?
なんでhogehogeはfreeしなくていいの?
malloc()したもんじゃないから。
937:02/01/29 21:40
違いはなんだ
malloc()したものかどうか
"hogehoge"は文字列定数、プロセスが起動して終了するまでの間ReadOnlyなメモリ空間に存在する。
malloc()が返すポインタはヒープ領域に確保されたメモリブロックの先頭アドレス。
free()にこのポインタを渡す事でメモリブロックは解放され、以降プロセス内で再利用できる。
少し本やマニュアル読めば分かる事聞いてんなよ、バァーカ。
おめぇはプログラムの前に日本語を学べ、バァーカ。
違いは、指している領域の種類。
free()すべきなのは動的に確保した領域のみ。




ちなみに malloc() して strcpy()、なんてダルイことをせずに、
strdup() または _strdup() を使え。
>>937
細かいことは気にすんな。
いつか分かるよ。
どうしても気になるなら、アセンブラでもやってみ。
>>941
いや、アセンブラやるよりもライブラリのソース読むほうが。
>"hogehoge"は文字列定数、プロセスが起動して終了するまでの間ReadOnlyなメモリ空間に存在する。

そうとは限らん
ReadOnlyである必要はないって? まあそれはそうだが書き込み可能であること
を期待すべきではないっつーのは確かだろ。
それはOS次第だな。言語仕様的にはまずいが
なんてーか、主語をハッキリさせず独断的な言葉を繋ぐ口調から
日下部某を連想するのは私だけでしょうか?
>>940
C99ではstrdupが標準関数に追加されていますか?
>>947
されてない。
inline char* strdup(const char* p){ return strcpy(malloc(strlen(p)+1),p); }
mallocがNULL返すとコア吐くのは仕様ですか?
951940:02/01/29 23:03
C99 に strdup は無い。「または _strdup()」これ重要。
主要な処理系(組み込み除く)のライブラリは strdup/_strdup を
用意しているので、現実には困らん。
なくても実装は簡単だしね。
>>950
んー。でも、そーすると1行で書けなくなるんよね・・・
malloc は NULL を返さないという前提の元でよろしく。富豪的プログラミング万歳。
>>953
それは富豪的プログラミングではなく、単なる手抜きだ。
955:02/01/30 06:04
ありがとう、おかげでレポートの間に合いました。
956ウルトラハッカー 日下部陽一:02/01/30 09:03
上げちゃった。ミスだ。