- 1 名前:デフォルトの名無しさん [2008/06/27(金) 21:31:43 ]
- 言語の入門者向け解説スレです。
教えて欲しいのではなく宿題を丸投げしたいならこちらへ。 C/C++の宿題を片付けます 110代目 pc11.2ch.net/test/read.cgi/tech/1213796455/ ・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 ・開発環境や動作環境も晒すと答えが早いかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 30 pc11.2ch.net/test/read.cgi/tech/1213367888/ 過去スレ makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
- 5 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:12:01 ]
- 型が未定の要素へのポインタの配列へのポインタを作りたいのですがvoid **pでいいですか?
- 6 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:13:13 ]
- >>5
はい
- 7 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:28:51 ]
- 「ポインタの配列へのポインタ」
厳密には 「ポインタの配列の先頭要素へのポインタ」 それはつまり 「ポインタへのポインタ」
- 8 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:29:14 ]
- >>前スレ971
rand()%900+100 ってのは具体的に言うと rand()%(1000-100)+100 rand()%(a-b)+b でb〜a未満の数値が出る
- 9 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:38:51 ]
- ポインタの配列へのポインタ void *(*p)[]
- 10 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:38:51 ]
- >>5
「『型が未定の要素』へのポインタの配列」を「void *の配列」として作るならそれで合ってる 「『型が未定の要素へのポインタ』の配列」を「char *かlong *か決まってないが、何かのポインタの配列」で作るならただのvoid *になる
- 11 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:41:57 ]
- Q 6.13
配列へのポインタをどうやって宣言するのか。 A たいていは、そんなポインタを宣言したいのではない。 なにげなく配列へのポインターというときは、 たいてい配列の最初の要素へのポインターのことをいっているのである。 配列へのポインタではなく、配列の要素へのポインターを使うことを考えること。 型Tの配列は型Tへのポインタに成り下がる。これは都合がよい。 なぜなら結果としてできるポインターを使って添字つきで参照したり、 整数を加えることで配列の各要素にアクセスしたりできる。 これに対して、本当の配列へのポインタは、 添字つきで参照したり整数を加えると、配列全体を飛び越してしまう。 これではせいぜい配列の配列を扱うときにしか役立たない。 本当に配列そのものへのポインターが必要な場合は「int (*ap)[N];」のような表現を使う。 ここでNは配列のサイズを表す。配列の大きさがわからない場合、Nを省略することができる。 しかし 結果として得られる「大きさが未知の配列へのポインタ」は役に立たない。
- 12 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 22:57:02 ]
- char型へのポインタを < で比較するソースがあったのですがどういう意味なのでしょうか?
- 13 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:00:06 ]
- ポインタの大小を比較してるんだろ
- 14 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:00:20 ]
- きっと連続した領域に対してみてるんだと思うけど、
アドレスを比較してる。それ以上はちょっと見てみないと。
- 15 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:07:48 ]
- 配列の要素を指すポインタ同士を引き算するとその要素の距離を求めることができる
たとえば char str[4]; char *p1=&str[0], *p2=&str[3]; としたらp2-p1は3になる だからif(p2-p1>0)なんて文も書くことができる これを書き換えるとif(p2>p1)になる
- 16 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:25:51 ]
- Quiz:
16bitの頃のCコンパイラなら兎も角、32bitコンパイラにおいては、 switch文のコンパイルでジャンプテーブルを作成して、実行時に それをスキャンし、ジャンプするような最適化は為されることは 余りない。何故か?
- 17 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:38:45 ]
- ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7105.c
switch はえーー!
- 18 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:44:08 ]
- >>16
ちょっとした分岐程度なら ジャンプテーブルのメモリアクセスのコストの方が高くなるから?
- 19 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:47:40 ]
- clock_t初めて見ました
面白そう
- 20 名前:デフォルトの名無しさん mailto:sage [2008/06/27(金) 23:58:40 ]
- >>17
どんなコードが出てるか見てごらん
- 21 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:00:05 ]
- 40くらいまで増やしたら差が激しく。
/O2スイッチつけたら両方とも0msでオワタ。HAEEEEE(違
- 22 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:01:07 ]
- ifはわざわざご丁寧に else 以下も条件判定をする
switchはcaseに該当がなければdefaultへ そこが無駄の差
- 23 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:02:13 ]
- >>17
そのコードだとswitch文のほうは実は最適化が施されて何もしてないんじゃねーの? ifのほうはご丁寧に20回まるまるやってるとか
- 24 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:02:35 ]
- っと、ちと補足。
ifはわざわざご丁寧に、21以上でも最初から順に else if 以下も条件判定をする
- 25 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:03:17 ]
- >>23
だからそれが必要の無い条件判定による処理時間の差に出ているんじゃん
- 26 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:03:35 ]
- ちとは意味のある命令をいれとかないと最適化抑制してもだめだめだな。
意味のない足し算でもさせるか。 VC++系なら cl /FAsc hoge.cpp で
- 27 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:14:20 ]
- 任意の論理式を扱う ifと列挙型(int)の値比較に限られるswitch分岐を
比較すること自体が無意味というオチでした。 論理式がint値の値比較であることがif文の最適化の際に判明したら、 比較に関してはswitchと同じようにレジスタに持っておいた値と コード上の固定値の比較に置換するので処理速度差が無くなりました。 というだけね。
- 28 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:24:34 ]
- char *a;
で宣言したaに、関数で文字列を入力したらエラーになるのですがなぜでしょうか?
- 29 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:27:21 ]
- >>28
それはchar型のポインターだから。
- 30 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:32:37 ]
- 始めまして、C言語の勉強を始めて半年ほどの者です。
トランプやUNOの様なカードゲームを作りたいと思うのですが、そういった物の作り方を順番に解説してくれている様なサイト、 もしくは本などを知らないでしょうか?
- 31 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:33:21 ]
- *aだけだと、aがどこを指しているのか不定だから
- 32 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:33:26 ]
- 文字列は先頭文字のアドレスを表すから、char型ポインタに代入できるのかなと思ったんですが・・・ダメなんですかね?
- 33 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:34:55 ]
- 文字列の先頭アドレスを*aに代入するなら問題ない。
そうしてないとは思うけど。
- 34 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:36:00 ]
- >>30
他の言語でもいいならサイト巡れば載ってると思う 大体やってることは一緒だし挑戦してみたら?
- 35 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:37:34 ]
- >>32
char型にしろint型にしろポインタ宣言しただけだとアドレスを格納する入れ物 ができただけで、中身は不定。
- 36 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:42:21 ]
- >>34
ありがとうございます。 少し別の言語の物を探してみます。
- 37 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 00:46:24 ]
- 文字列はリテラルされる(アドレス固定)
そのアドレスが入っている入れ物(変数)の中身を別のアドレスに移動しようとしたから、 おまえ、システム領域弄るんじゃないよ! とACCESSVIOLATIONで怒られる。 >>33の言ってる*aは数値だから構わない。(参照ではなく代入)
- 38 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:11:16 ]
- >>28 で宣言したaに、関数で文字列を入力したらエラーになるのですがなぜでしょうか
入力とは何? a = "hoge"; とかなら大丈夫だろうけど strcpy(a, "hoge"); はだめだよ。 >>32文字列は先頭文字のアドレスを表すから、char型ポインタに代入できるのかなと思ったんですが・・・ダメなんですかね? 文字列の方はconst charの「配列」です。
- 39 名前:38 mailto:sage [2008/06/28(土) 01:12:27 ]
- 誤字だった。
文字列の『型』はconst charの「配列」です。
- 40 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:33:34 ]
- 誰も関数にポインタをそのまま渡してる可能性を指摘しない件
- 41 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:36:03 ]
- >>29がしてるじゃん
アドレス入れる器に文字入れればそりゃエラー起こられる罠
- 42 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:53:53 ]
- >>41
そーじゃなくて main() {
- 43 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 01:54:54 ]
- ミス
main() { char *a; hoge(a); hoge(char *a) { a="HOGE";
- 44 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:02:29 ]
- 28がどうやったのかはっきりしない限りどれも想像でしかないけどな。
- 45 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:05:47 ]
- 亀だが if switch 検証。
if (j <= 20 && 1 <= j) { if (j == 1) ... if (j == 20) } else { } としたところifの方が速くなりました。 んで、if (1 <= j && j <= 20)にしたら比較のコストが大きくなって ifの方がやや遅くなりました。
- 46 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:33:17 ]
- ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7114.c
範囲を指定しないなら、やっぱり switch はえー
- 47 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:38:57 ]
- >>46
なんか初めてハッシュを知った新入りのような喜びようだなw ほほえましくてイイヨーイイヨー
- 48 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:55:37 ]
- >>47 意味不明。自分の理論の穴を突かれて涙目なんだろ?w
>>45
- 49 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 02:59:29 ]
- >>48
ちがうちがう。 状況によってはifを使う方が速いこともあるよっていいたかっただけだ。 ついでに、条件文の書き方でも十分代わりうるということをいいたかった。 適した場面に適したコードを書くのは当たり前で、 switch(str) { case "hoge": } ってかけなくてswitchざまあなんて言い回しと同じように、 switchを使う方が良い場面においてif遅いなどというのはおろかなこと。
- 50 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 03:05:58 ]
- 初心者の頃にnyを使い始めて、ハッシュを知ってはしゃいだことのある
>>47 が可愛いよ皮良いよ
- 51 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 03:09:39 ]
- >>50
なぜny?ハッシュが何を指しているか理解してない、のか? さすがにないと思いたいんだが。 しっかり勉強しろよ?
- 52 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 03:27:59 ]
- >>47
なんか初めてハッシュを知ったny厨のような喜びようだなw ほほえましくてイイヨーイイヨー
- 53 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 04:02:02 ]
- 以上、チンパンジーのアイちゃんの自演でした。
- 54 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 04:11:30 ]
- >>47 論破されて涙目だなwwww
ハッシュなんて持ち出すなら、なおさら指定範囲内の 数値に対する話は論外になるな。無関係な話ではあるが。
- 55 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 04:26:16 ]
- >>47
茶化したつもりがハッシュなんて持ち出すから、さぁ大変。 ny厨乙。お前がそれを知って喜んでいたことの自己紹介ですか? にしても、switch はえーなぁー、をいっw
- 56 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 04:51:02 ]
- ハッシュとny厨に何の関係があるんだろう
- 57 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 07:38:10 ]
- switchが早いのでこれからは
if (a == b) { // 処理 } を switch (a == b) { case 1: // 処理 } と書くようにします!
- 58 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 08:19:48 ]
- ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7115.txt
最適化かけまくりだと0msなんで加算処理を加えてみた。 s w i t c h 蠅ー
- 59 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 10:32:34 ]
- kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7119.txt
このプログラムにおいて、最初のほうで BSTREE_NODE *deleteMinNode(BSTREE_NODE *p, BSTREE_K_TYPE *min); BSTREE_NODE *deleteRootNode(BSTREE_NODE *p, BSTREE_K_TYPE x); と書かなければいけない理由ってなんなんでしょうか? 消すとエラーが出るのに、*pや*minなどの値は変更してもエラーがでないのも意味がわかりません・・
- 60 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 10:35:18 ]
- 色々なC言語のコンパイラがありますがおすすめとかありますか?
- 61 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 10:38:36 ]
- >>59
プロトタイプ宣言かな? コンピューターは先頭から後ろにかけて順次処理してくのは 得意ですが、人間のようにソースを見渡して関数の宣言場所 と利用箇所を眺めてちゃんと定義されてるという確認ができない ある意味融通が利かない人なのです。 なので関数を使ってる箇所よりその関数が後ろに定義されてる場合 はソースの先頭付近に関数の頭の部分を定義してコンパイラに こんな関数があるよと先に結論を教えてあげます。 プロトタイプ宣言がいやなら関数を使ってるところより 先に関数を配置すればOKです
- 62 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 10:42:07 ]
- >>60
windowsPC持ってるならVC++かVC#でいいんじゃないの? Cygwinとかって環境構築ではまりそうだしね >>61の続き プロトタイプ宣言をしたくない?ようなソースはmain関数が ソースの一番最後にあって、main関数より呼ばれるその他 関数が上置くようになってます。
- 63 名前:59 mailto:sage [2008/06/28(土) 10:57:36 ]
- >>61
>>62 なるほど、ありがとうございます。 この宣言において、*minなどを違う文字に変更してもエラーが出ないのはどうしてなんでしょうか? 例えば BSTREE_NODE *deleteMinNode(BSTREE_NODE *p, BSTREE_K_TYPE *min); を BSTREE_NODE *deleteMinNode(BSTREE_NODE *a, BSTREE_K_TYPE *mn); などに変更してもエラーは出ずに実行されるのですが・・
- 64 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 11:04:44 ]
- プロトタイプ宣言は引数の数と型だけ見てるから。
- 65 名前:59 mailto:sage [2008/06/28(土) 11:08:56 ]
- なるほど、わかりました。
ありがとうございました
- 66 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 11:13:57 ]
- >>62
ありがとうございます。vc++ダウンロードしてきます。
|

|