- 1 名前:デフォルトの名無しさん [2007/10/24(水) 04:07:56 ]
- なんと!意外にもスレが無かったので立ててみました
先日のソフトウェア開発技術者試験午後UのB木のポインタ表現 近年の基本情報技術者試験の午後C言語問題の自己参照構造体 など物凄く出来が悪いです。 ゆとり?文系?自作減少? ブラックボックス化されてメモリ管理やコンピュータの細かい知識が不要となった? 本当にポインターは必要なのか!?議論しましょう
- 580 名前:デフォルトの名無しさん [2007/12/13(木) 16:16:38 ]
- int array[10];
で&arrayってvoid*?
- 581 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 16:52:14 ]
- int**
- 582 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 17:04:52 ]
- 自己レス
int (*)[10]か。 >>581 あれ?それでもいいの? 試してみます
- 583 名前:デフォルトの名無しさん [2007/12/13(木) 17:13:53 ]
- 配列のポインタと、ポインタのポインタを間違えるな
- 584 名前:582 mailto:sage [2007/12/13(木) 17:24:09 ]
- int**はダメだた・・・
- 585 名前:デフォルトの名無しさん [2007/12/13(木) 17:32:46 ]
- >>572
俺にはC++のメモリ管理がだるいと感じるお前が理解できない new したらdeleteすればいいだけじゃん なにがだるいんだか・・・
- 586 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 17:36:05 ]
- それがだるい。
- 587 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 18:31:19 ]
- >>585
C++のメモリ管理ってスマポンタだろ
- 588 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 18:33:31 ]
- >>580
配列名だけで先頭要素のアドレスになる。 ただし、それは変数じゃないので&を付けても無駄。 int array[10]; printf("%p¥n", array); printf("%p¥n", &array); で試してごらん。
- 589 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 18:34:41 ]
- >>586
よきにはからえ、じゃないと駄目だよね。 ゆとりプログラミングの時代さ。
- 590 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 19:24:19 ]
- >>588
arrayは配列の先頭要素へのポインタ &arrayは配列へのポインタ だから値は同じだけど意味が違うんじゃないですか?
- 591 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 19:51:16 ]
- >>589
コンパイラ使うのも似たような言葉で馬鹿にされたものだけどね。
- 592 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 21:53:28 ]
- >>588
違う。 arrayはポインタでは「ない」。 ポインタは変数。配列名は定数。
- 593 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 21:57:39 ]
- 単にarrayと書いたときに「どう解釈されるか?」の話じゃないの?
- 594 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 22:11:13 ]
- アレーイ?
- 595 名前:デフォルトの名無しさん mailto:sage [2007/12/13(木) 23:43:50 ]
- アルェーイ?
- 596 名前:デフォルトの名無しさん [2007/12/14(金) 10:44:32 ]
- 配列とポインタは違うのに同じだ、
と言うニュアンスでK&Rで解説されたために、 その後のC言語の入門書で、 よく分ってないヤツがゴチャゴチャにして説明するようになって、 今に至る
- 597 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 11:49:52 ]
- 基本的に違うけど引数としてはどっちでもとれるって状況
だと思うが引数として使うってのが けっこうメジャーな使いかたなためごっちゃになってるって 状況だとおれは認識してる。
- 598 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 11:55:35 ]
- >>597
>基本的に違うけど引数としてはどっちでもとれるって状況 間違い。 引き数としては、常にポインタ。 # 但し、Cの場合。
- 599 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 12:36:31 ]
- 学校で課題で「配列とポインタの違いを説明せよ」みたいなのあったなぁ・・・
- 600 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 16:41:13 ]
- >>585
自分がnewしてdeleteするなら別に面倒では無いだろうけど リスト構造でなおかつ、その構造が要素追加にnew、削除にdeleteを使うようなプログラムはが何万行と続くとデバック作業がかなり面倒だろ?まあ、それはそれで利点もあるがな それを面倒臭くないというお前はすごいな、それとも極小規模なプログラムしか組んだことないのかな?
- 601 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 17:58:01 ]
- >>599
配列は箱を列に並べたもの ポインタは矢印 でいいかな?
- 602 名前:デフォルトの名無しさん [2007/12/14(金) 18:43:34 ]
- >>601
大学のレポートって、お絵かきでOKなの?
- 603 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 18:59:17 ]
- >>598
そういうことじゃなくてポインタ変数でも配列変数でも 代入できるだろうって意味。
- 604 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 19:25:33 ]
- 住所そのものと住所を書いた紙が別なのは当たり前だろが
住所そのものを変えるには市町村合併でもするほかないが紙に書かれた住所を書き換えるだけなら簡単
- 605 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 19:31:58 ]
- >>604
なんかオブジェクト指向の例え話なみに微妙な話だな
- 606 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 19:50:48 ]
- たとえ話に住所って言葉を使うのが間違ってそう
- 607 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 19:54:39 ]
- ポインタなんて
[C言語 ポインタ完全制覇] 読んで理解したなら 後は、実践を繰り返すだけだろーよ
- 608 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 19:56:31 ]
- どんなに微妙でも人間の脳構造はアナロジーの利くものの方が
覚えやすくできてんだからそれでいいじゃんよ。
- 609 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 20:05:30 ]
- C FAQの6.13
www.kouno.jp/home/c_faq/c6.html#13 c-faq.com/aryptr/ptrtoarray.html に ・・・本当に配列そのものへのポインターが必要な場合は「int (*ap)[N];」 のような表現を使う。 ここでNは配列のサイズを表す(質問1.21も参照)。 配列の大きさがわからない場合、Nを省略することができる。 しかし 結果として得られる「大きさが未知の配列へのポインター」は役に立たない。 ってあるんですが、 int array[10]; int (*ap)[]; ap = &arrrayってエラーにならないんですか?
- 610 名前:デフォルトの名無しさん mailto:sage [2007/12/14(金) 20:17:14 ]
- >>609
配列の不完全型ってヤツか? 良く分からんが、違う構造体同士で相互参照する時なんかに使う 構造体の不完全型の親戚みたいなもんかな
- 611 名前:デフォルトの名無しさん [2007/12/15(土) 02:27:42 ]
- >>609
試せば良いじゃんよ
- 612 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 02:32:55 ]
- VC++ExpressEdition
d:\work\vc\array\arrayptr.cpp(9) : error C2440: '=' : 'int (*__w64 )[10]' から 'int (*)[]' に変換できません。 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
- 613 名前:デフォルトの名無しさん [2007/12/15(土) 04:19:56 ]
- Cより先にアセンブラやれ!!
アドレスの概念を理解しないでいきなりやるから 難しくなるんだよ!!
- 614 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 05:35:26 ]
- それも極端な話だなあ、と思う反面確かにそれが近道だよなあと思っているおれがいる
- 615 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 08:55:36 ]
- ちょっと疑問なんだが、配列自体が先頭のアドレスを示しているのに、
さらにそれのアドレスが欲しい場合ってどういうケース?想像つかないんだけど。
- 616 名前:デフォルトの名無しさん [2007/12/15(土) 10:40:49 ]
- こんな感じなら理解できるか?
#include <stdio.h> #define N 5 void aryfunc(int ary[N][N]) { int *temp; for(temp = &ary[0][0]; temp != &ary[N-1][N]; temp++){ (*temp)++; } } int main() { int ary[N][N] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}, {16,17,18,19,20},{21,22,23,24,25}}; int *temp,i; for(temp = &ary[0][0],i = 1; temp != &ary[N-1][N]; temp++,i++){ printf("%d ",*temp); if(!(i%5)) putchar('\n'); } aryfunc(ary); for(temp = &ary[0][0],i = 1; temp != &ary[N-1][N]; temp++,i++){ printf("%d ",*temp); if(!(i%5)) putchar('\n'); } return 0; }
- 617 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 12:08:10 ]
- >>616
添字でアクセスできるのに、わざわざポインタつかってわかりにくくしてる気がするんだが。 ↓と同じことでしょ? void aryfunc(int ary[N][N]) { int i, j; for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { ary[i][j]++; } } }
- 618 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 12:11:15 ]
- >>615
配列の配列とか、配列の配列の配列とか、つまり多次元配列を 関数の引数として渡すときに必要だな
- 619 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 12:15:46 ]
- >>615
配列名は、配列の「先頭の要素」のアドレス。 配列名に&をつけた場合は配列「そのものの」のアドレス。 ポインタの値としては同じ値だが、意味が違う。 なんか思い違いをしてる気がするぜよ
- 620 名前:615 mailto:sage [2007/12/15(土) 12:48:40 ]
- >>618
多次元配列も、型と先頭アドレスと要素数を何らかの形で渡せばいいわけだから、 アドレスに関しては配列名のみを渡せばいいんじゃないの? >>619 意味の違いは理解してるつもりだが、これじゃなきゃできない、というケースが思いつかなくてさ。 先頭の要素のアドレスと、配列そのもののアドレスが違うことがあれば理解もできるってもんだが…
- 621 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 13:12:30 ]
- &つけようがつけまいが
値同じだから意味は同じ しょうもねー議論してるんじゃねーよw
- 622 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 13:22:07 ]
- そんな乱暴なw
- 623 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 13:54:30 ]
- >>621
型が違うから意味は違うだろ
- 624 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 14:29:01 ]
- >>621
おまい、ポインタはvoid*さえあればいい派だなw
- 625 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 14:51:34 ]
- void *と
void **あれば何もいらねーだろ。 型に束縛される書き方してると 汎用性失う言語だし 携帯のドライバなんかは int Inithoge(void * data1, void *data2, void *data3) こんなの普通だぞ?
- 626 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 15:01:07 ]
- 携帯用のドライバなんかどうでもいい
- 627 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 15:42:40 ]
- www.kouno.jp/home/c_faq/c6.html#18
>>配列の配列は、ポインターへのポインターに成り下がることはない。 これを読んで思ったんだけど、 int main(int argc, char **argv)は間違い(行儀が悪い)で、 int main(int argc, char *argv[])が正しい(行儀が良い)の?
- 628 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 16:43:52 ]
- >>627
関数の引数は常にポインタしかとらない。 字面上配列の形をしていても、そいつはポインタだ。 だから、 void foo(char *pa[]); void bar(char **pp); char aa[10][10]; という関数と配列の配列があったとして、以下の呼び出し foo(aa); bar(aa); のどちらも違法(コンパイラが怒る)だ。 これが「配列の配列は、ポインターへのポインターへ成り下がることはない」の意味だ。 ちなみにmainに渡されるargvはポインタの配列であり、これはポインタのポインタで受けられる。
- 629 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 18:02:39 ]
- argvがポインタの配列だから
void hoge(char str[])を void hoge(char *str)と書けるのと一緒で int main(int argc, char *argv[])を int main(int argc, char **argv)って書くのは全然おかしくないわけか。 むしろ後者の方が実際にやっていることとイメージが近いな。
- 630 名前:デフォルトの名無しさん mailto:sage [2007/12/15(土) 18:45:17 ]
- const char* const argv[] って書きたいところだけど
- 631 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 06:01:17 ]
- ポインタの配列と、配列の配列の違いを、
いくら説明しても全く理解できないヤツ、 会社に一人くらいいるよな・・・ プロのプログラマーのはずなのに
- 632 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 06:05:55 ]
- ・ポインタを「何かを指している矢印」
・配列を「何かが入っている箱」 という図を描いてみて、その上で配列の配列とポインタの配列を描いてみればすぐわかると思うんだけどな。
- 633 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 11:13:25 ]
- >>631
専門書籍で使われてる言葉をそのまま使っても伝わらないよ 一度日本語に直す、相手に伝わる言葉に直す そういうリファクタリングを繰り返してバカ矯正プログラムが完成するんだ
- 634 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 16:47:55 ]
- ダブルポインタと呼ぶのはやめてほしい
- 635 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 17:07:40 ]
- 図ばかり頼りにして、言葉を大事にしないのは、理系プログラマの欠点だ
- 636 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 21:45:05 ]
- 文章から何かをイメージする能力が読む側に備わってない
理系文系だ関係なく読解問題が苦手なの増えてるだろ? だからこっちでイメージを用意してやりようやく相手が理解できる マンガと同じだわ
- 637 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 22:15:45 ]
- そうゆうこと
嫌韓を読めばよくあの国が理解できるのと一緒
- 638 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 22:49:12 ]
- 嫌韓って漫画じゃねえよあれ。カット集じゃん
全編挿絵っつうか
- 639 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 23:05:44 ]
- マジレスすること自体
ゆとりだと自己主張しているものだな。 このスレ削除でよくねーか?
- 640 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 23:08:20 ]
- 時々思いがけない議論があってちょっと楽しいから
削除しないで放置しておいて欲しい
- 641 名前:デフォルトの名無しさん mailto:sage [2007/12/16(日) 23:13:43 ]
- マジレスでもなんでもないだろw
どんどん話題が枝葉にそれてるだけで
- 642 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 00:08:20 ]
- まず、学ぶべきことを定義するのが先じゃないか?
アドレスの代入、アドレスが示す値の参照 関数へのアドレス渡し ポインタを利用するアルゴリズムを理解 こんな感じでさ
- 643 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 00:14:32 ]
- レス600過ぎてから定義されてもwww
- 644 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 01:39:57 ]
- 老いて益々盛んってことわざもあるし
人生に手遅れって言葉はないと思うんだ
- 645 名前:デフォルトの名無しさん [2007/12/17(月) 04:57:57 ]
- w
w
- 646 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 11:54:52 ]
- 図に書いて説明するより、ソースレベルデバッガでポインタ変数にどんな値が入って、
その値が指すアドレス(とその前後アドレス)にどんな値が入ってるのか 見せた方が分かりやすいと思う。
- 647 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 12:32:54 ]
- >>646
ポインタの実際の値がいくつなんて、 どうでもよいことじゃね?
- 648 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 17:17:05 ]
- ポインタをsizeofすると正体がわかるよね
32bitの処理系なら型に限らず全部4だし
- 649 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 18:12:01 ]
- >647
いや、そういう正体のつかめ無さが、初心者には分かりづらいんじゃない? まずは抽象度を下げて、具体例から入った方がいい。
- 650 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 21:20:39 ]
- >>648
ただそんなことに頼っていると書いているコードがしばらくたって 使おうと思うと動かなくなる。
- 651 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 23:40:06 ]
- ポインタは単純だ
for (int i = 0; dst[i] = src[i]; i++); がポインタのおかげで for (; *dst++ = *src++;); できるだけだ
- 652 名前:デフォルトの名無しさん mailto:sage [2007/12/17(月) 23:59:44 ]
- あまり違わない気がする・・・
- 653 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 02:16:14 ]
- つか、C++使い始めてからポインタなぶるなんて中々無くなったわ
- 654 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 02:48:13 ]
- 関数での受け渡し以外にポインタなんて使う?
- 655 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 03:51:26 ]
- mallocなどで確保するときに使うよ
- 656 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 09:50:06 ]
- 文字列だってポインタじゃん
- 657 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 18:39:02 ]
- >>654
自己参照型構造体使ってないのか?素人さん?
- 658 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 20:34:35 ]
- 玄人さんがお見えになったぞ!
- 659 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 20:48:28 ]
- ポインタ使うのに、玄人も素人もない
- 660 名前:デフォルトの名無しさん mailto:sage [2007/12/18(火) 23:03:10 ]
- グローバル変数の初期化順序が保証されてないから、初期化順が重要な
グローバルオブジェクトはポインタだけ定義しといて、初期化関数で順番に newしていくとか。 (順序が重要なオブジェクトをグローバルにすることの是非は置いといて)
- 661 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 01:03:25 ]
- >>654
オブジェクトいろいろ弄る時に使うよ。入れ替えたりとか便利。
- 662 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 01:33:28 ]
- コールバックするのにつかうー
longjumpするのにも使う
- 663 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 01:43:57 ]
- もう「無いと困る」でいいんじゃね?
- 664 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 01:51:40 ]
- >>657
データ格納するならデータベース使わね? 組み込みなら、一時的な(親機に渡す日次処理で消えてしまうよな)データの格納に使ったりするけど 今は組み込みもDBの採用が進んでるし
- 665 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 01:55:29 ]
- それとこれとは話が違う・・・
- 666 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 02:02:54 ]
- 話が違うというか、本物が来ちゃったようだ・・・
- 667 名前:デフォルトの名無しさん [2007/12/19(水) 02:37:02 ]
- ポインタ使って2−3木を作りたいと思っているのですが
ここを見ればおkていうサイトとかありませんか?
- 668 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 08:24:16 ]
- データ構造とアルゴリズムを扱った書籍を買った方がいいと思うね
- 669 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 10:32:47 ]
- てか作ればいいじゃん
- 670 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 10:48:42 ]
- 自己参照構造体というのを試してみたんだが、メモリの開放が面倒そうだ。
自分を指してる一つ前の構造体のアドレスってどうやって取得するの? 元々そういう風に構造体を作らなきゃダメ?↓みたいな感じで。 typedef struct tree { struct tree *prev; struct tree *next; int x; } tree_t;
- 671 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 10:51:29 ]
- 駄目
- 672 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 10:59:19 ]
- 自分は初期の頃はtree->next->nextでNULL見つけてtree->nextを解放したら,
tree->nextをNULLにする.ポインタ最初に戻してまた上から見るみたいなことやってたw 双方向だとその辺ずいぶん速くなるよね.
- 673 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 11:32:57 ]
- >>672
再帰すればいいじゃん。
- 674 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 11:44:48 ]
- >>672
うん,いまは順方向だけの場合そうやってる. 順j方向リストの場合サーチかけてるポインタじゃなくて その次に対して操作すると一つ前のアドレスはサーチかけてる ポインタそのものになるということをいいたかった.
- 675 名前:デフォルトの名無しさん [2007/12/19(水) 12:56:15 ]
- >>668 >>669
わかりました、頑張ります!
- 676 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 13:35:02 ]
- おまいら、1方向の線形リストならもっとうまい手があるだろうが。
あるノードを消す場合は、その後ろのノードを消すノードに上書きして、 後ろのノードをfreeするんだよ。
- 677 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 17:35:31 ]
- 一方向の線形リストなら「上書き」って必要ないでしょ
消すノードの前のノードと後ろのノードを繋げてから 対象ノードをfreeすればいいんじゃないの
- 678 名前:676 mailto:sage [2007/12/19(水) 17:39:23 ]
- 1方向って*prevがないやつか
ごめんなさい
- 679 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 17:39:55 ]
- おれ677だった
ごめんねごめんねごめんね
- 680 名前:デフォルトの名無しさん mailto:sage [2007/12/19(水) 17:56:32 ]
- >>679
許すからキニシナイ。 真面目な話、あるノードを消したければ後ろのノードの内容を上書きして後ろの方の ノードを消すなんてのは一方向線形リストを扱う時の基本的なアルゴリズムだよ。 先頭からまた検索するなんて、無駄無駄無駄〜! じゃ、あるノードの前に新しいノードを追加する時はどうすれば無駄がないか 考えてみそ。
|

|