10/06/30 10:22:47
なぜポインタで引っかかる人が多いのか
引っかかる人は何に困惑しているのか
2:デフォルトの名無しさん
10/06/30 10:41:34
ポインタは概念のようなものなので、知ってすぐ使える標準関数やSTL等と違い「何に使えるか」が不明瞭だから
3:デフォルトの名無しさん
10/06/30 11:12:35
*だから
4:デフォルトの名無しさん
10/06/30 11:30:00
なぜ雑談スレや質問スレに書き込まずにスレを立ててしまうのか。
クソスレ立てる人はバカなのか死ぬのかチンパンジーなのか。
5:デフォルトの名無しさん
10/06/30 11:45:08
物理メモリにデータをおいてるってイメージがないとね
6:デフォルトの名無しさん
10/06/30 14:28:09
ポインタって訳すと「指し示す」だろ。
それを*をつかって値を書き換えたらポインタじゃないじゃん。
参照するまでは許す!でもいじったらポインタじゃない!
7:デフォルトの名無しさん
10/06/30 15:26:56
数値扱いにもなるのが理由じゃないかな。
それ故に今扱ってるのがデータなのか、アドレスなのかワケが分からなくなる。
アドレス書くべきところにデータを書いてしまったり、逆をしたりしたときに
予測不能な挙動を引き出してしまい、何が起きたのか分からなくなる。
ポインタ型と数値型が明確に区別されて、キャストしないと数値にできず
型エラー出すなら引っかかりにくいと思う。
8:デフォルトの名無しさん
10/06/30 15:44:40
ポインタはね、メモリのアドレスでしょ。
そんなことは言われればだれだって理解できるんです。
要するに計算用紙の座標がポインタですから。
でも複合型の文法を出した途端、頭の中で処理できなくなるんです。
加えて、配列がポインタとかウソの説明をうけてごらんなさい。
ほら、分からなくなった!
そうこうしているうちに関数ポインタの説明まで行くでしょ、
そこまで行ったらなーんとなく概念では分かるけど、
文法は全くわからんちーん。
アドレスだから数値と一緒で計算できるとか勘違いするようになる。
配列のポインタが配列の先頭要素指してるから
キャストエラーを無視してもいいとか頭の中が沸いてるんじゃないかと
思う発送をしだすようになる。
9:デフォルトの名無しさん
10/06/30 15:47:43
配列がポインタ、は嘘なんだが
言語仕様からして割と混同されてるだろ
あれでは分からなくなるのも無理はないかと
10:デフォルトの名無しさん
10/06/30 15:52:06
でも別にそんなのどうだってよくね?
物理メモリのどっかにあるその領域の先頭を指してるもん的な
意味でしか使ってないぞ>配列
あくまで俺はって話しだけど
いちいち配列の先頭とポインタとでごっちゃになっちゃうような使い方してるのって
組んでるプログラムも怪しくねーか?
俺みたいに物理メモリのどっかを指してるモノってとらえてると
配列もポインタって言っちゃう人がいるのかもね
ただ、その場合連続してるもんとしてないもんと脳みそに入ってないとダメだけど
11:デフォルトの名無しさん
10/06/30 15:57:19
配列式aをa[0]に自動変換できる一部の場合(要するにsizeofとか以外)、
a[2]=2[a]が*(a+2)と等しいことを取って配列と等しいことを指して、
配列とポインタが等しいなんて言う人がいるんだよなあ。
まあもっともポインタが引っかかる人はそれ以前だと思うが。
12:デフォルトの名無しさん
10/06/30 16:03:58
では配列とポインタはどこが違うのだろうか。
正確な答えを自分は知らない。
13:デフォルトの名無しさん
10/06/30 16:55:16
>>12
int a[10];
int *b;
この時、aは定数、bは変数
a[0]はアドレスa+0を参照する
*bは変数bが保持する値をアドレスとしてメモリを参照する
printf等でaとbを参照すると、どちらからもアドレスを得られるので混乱の元となる
14:デフォルトの名無しさん
10/06/30 17:15:09
等しいものとして扱うとどんなバグが発生するのか例を出して
15:デフォルトの名無しさん
10/06/30 17:19:00
領域が連続しているかどうかぐらいの違いしか見えないな
でもポインタのアドレスずらして計算なんてぶっちゃけいまやらないからまったく害がないなw
16:デフォルトの名無しさん
10/06/30 17:38:00
ここはポインタを理解できない人の原因を探るスレッドだろ
17:デフォルトの名無しさん
10/06/30 17:41:49
使う→間違える→考えるの繰り返し
わからない人はどれもやっていない
18:デフォルトの名無しさん
10/06/30 17:46:38
アセンブラもやってようやく理解といった感じ
19:デフォルトの名無しさん
10/06/30 17:49:47
プログラムのお勉強のいいところは
やる環境さえあれば、身についてしまうことだ。
20:デフォルトの名無しさん
10/06/30 20:15:10
int a[10];
int *b=a;
で、sizeof(a)=40, sizeof(b)=8;
21:デフォルトの名無しさん
10/06/30 20:33:36
>>18
俺もそうだったな。学生時代にBASIC→C言語やった時には
全く理由の解らない現象に悩んだもんだ。
メモリの状態によっては期待通りの結果が出たり出なかったりするからまたタチが悪い…
22:デフォルトの名無しさん
10/06/30 20:37:57
勉強に使った本が悪いんじゃないかな
[C言語ポインタ完全制覇」とか使ってみて理解できないなら別の要因だろうけど
それと自分で理解を深めたい時、どういった確認(プログラム)すればいいのかわからない
23:デフォルトの名無しさん
10/06/30 20:44:16
>>20みて思った
俺いまだ32bitのアプリ作ってるわ
24:デフォルトの名無しさん
10/06/30 20:57:09
64bitは甘え
25:デフォルトの名無しさん
10/06/30 21:12:21
・アドレス値の変更可否
・sizeofの値
違いはこれくらいかな。
26:デフォルトの名無しさん
10/06/30 21:39:19
アセンブラやってからだと全く困らないんだけどねー。
27:デフォルトの名無しさん
10/06/30 22:22:41
char *name[]とか見たらウンザリする。
これってname[0]、name[1]などはアドレスを意味するんですよね?
28:デフォルトの名無しさん
10/06/30 23:00:36
>>27
そうだっけ?
29:デフォルトの名無しさん
10/06/30 23:31:09
>>2
メモリアドレスという、非常に具体的なものなのだが。
30:デフォルトの名無しさん
10/06/30 23:34:19
java出身者はこの辺まるでダメだね
なんでこんな糞を量産してるの?ってぐらいダメだね
31:デフォルトの名無しさん
10/06/30 23:58:38
珍班AIは糞スレ
32:デフォルトの名無しさん
10/07/01 00:03:05
javaにポインタはないと言ってる香具師は
ぬるぽしたことがないんだろうか
33:デフォルトの名無しさん
10/07/01 00:05:23
>>32
本当はjavaでも理解してなきゃならないよな
でもさっぱりわかってねーのがほとんどなの
34:デフォルトの名無しさん
10/07/01 00:41:31
見て見ぬふり出来るということ
35:デフォルトの名無しさん
10/07/01 01:02:48
Z80とC言語を同時期に教えれば、ポインタではまず引っ掛からない
高専電気科は同時期に教えてた
36:デフォルトの名無しさん
10/07/01 04:49:23
>>32
Java, Cどちらもできるけど、「Javaにはポインタは無い」でいいよ。
ポインタが存在する、っていう説明でも別にいいけど。
あるのはあくまで参照。ポインタ演算は不可能。配列も大概アクセス遅いし。
Java出身者が引っかかるのはC++のオブジェクトが
Cで言うオブジェクトと近くて、要するに構造体で値型なところだろう。
>>25
あと&演算子も配列とポインタじゃ変わってくる。
37:デフォルトの名無しさん
10/07/01 07:57:22
うんと昔、はじめてCを勉強した頃を思い出してみると、
int i;
char buffer[100];
char *ptr = buffer;
scanf("%d", &i);
scanf("%s", ptr);
printf("%d", i);
printf("%s", ptr);
なにこれ?なんでscanfではポインタだけ&がなくて、printfでは両方&がないの?
って不思議に思ったな。
この辺でつまづくんじゃね。って一番最初だが。
38:デフォルトの名無しさん
10/07/01 08:37:40
>>35
おれ6809だったけど、ポインタでは引っかからなかった
39:デフォルトの名無しさん
10/07/01 08:49:26
まあ、でも別に半年もすれば大抵の人間が理解しちゃうし
2~3年たっても理解できない奴なんていないし
大した問題じゃないんだけどなw
40:デフォルトの名無しさん
10/07/01 10:13:55
理解できない奴は2年も経たずに離脱するからな。
41:デフォルトの名無しさん
10/07/01 10:33:45
理解出来ないものに2年も係わるなよ
42:デフォルトの名無しさん
10/07/01 10:45:20
だから、「2年も経たずに」って書いてあるじゃん。
43:デフォルトの名無しさん
10/07/01 10:59:40
開発1年半ぐらいの奴が、関数の引数で**pとせずに*pとしてハマってて、
試しに簡略なメモリマップ書かせてみたら、書けなかった
という話を開発のリーダに聞いたんだが、ある意味すごいな
44:デフォルトの名無しさん
10/07/01 11:00:16
ポインタはわかるけど、引数がポインタのポインタとかになってるとわけわかめ
45:デフォルトの名無しさん
10/07/01 11:01:17
>>43
意味不明なことやらせんなよ
Windowsのはきついだろw
46:デフォルトの名無しさん
10/07/01 11:09:08
プログラマの人材募集に応募してきたプログラマの面接時の珍回答の例:
・「ダブルポインタは大丈夫ですけどトリプルポインタは自信がありません」
・「Cの入門書を3冊読んだから書いたことがなくても大丈夫」
・ランバラルの台詞を引用する
47:デフォルトの名無しさん
10/07/01 11:18:39
たまたま知る限り全ての処理系でポインタの実装がメモリアドレスを格納する変数なだけで
規格上はポインタがメモリアドレスである保証は無い
48:デフォルトの名無しさん
10/07/01 11:22:03
>>47
実際、Cインタプリタで、ポインタの実装が(実装言語の)配列インデックスである例はあるよ。
49:デフォルトの名無しさん
10/07/01 14:49:20
それって翻訳の処理が規格通りじゃないから
そもそも規格準拠の処理系じゃないんじゃね?
どういう解釈になるんだろ
50:デフォルトの名無しさん
10/07/01 15:23:18
>1
俺みたいなやつがいるから
51:デフォルトの名無しさん
10/07/01 18:15:36
PICなんかはコード領域とデータ領域が物理的に分離されてるからな
52:デフォルトの名無しさん
10/07/02 08:45:10
たしかに何に使えるのかのイメージが湧かない
極力使わないように回避出来ちゃいそうな気もした
53:デフォルトの名無しさん
10/07/02 08:51:15
>>52
アセンブラのインデックスアドレッシングを拡張したもんだから、
ハード寄りのプログラミングでは必須。
目次なしでも辞書を引けないことはないが時間かかり過ぎ、というのと似ている。
54:デフォルトの名無しさん
10/07/02 10:19:27
>>52
配列とインデックスを別々にすると変数や引数が多くなって気持ち悪い
55:デフォルトの名無しさん
10/07/02 14:00:22
int *ip; int n=1;
ip += 1;
ip += n;
ip++;
上3つは全て等価だろうか?
int ia[10];int *ip = ia;
for(int n=0; n != 10; n++){
*ip + n = n;
ip[n] = n;
*(ip + n) = n;}
上3つは全て等価だろうか?
56:デフォルトの名無しさん
10/07/02 15:31:36
>>55
そんなゴミみたいな例を出すからわからなくなる
大事なのはイメージ
物理メモリにおいてある領域にアクセスしようとしてる仕組みのイメージを
脳みそに描くことであって
そんな読みにくいコードが読めるかどうかはプログラムの能力とちっとも関係ない
57:デフォルトの名無しさん
10/07/02 15:36:43
>*ip + n = n;
なんだこりゃ
58:デフォルトの名無しさん
10/07/02 15:45:08
よくわかってない人間が、うっかりすると書いてしまうことがある。
だから、なぜ望んだ動作をしないのかわからず、引っかかるんだ。
読みやすい書き方を提示してやれば、ポインタで引っかかる人間は激減する。
59:デフォルトの名無しさん
10/07/02 15:57:07
>>55
後半はバグっていて話にならない(>>57のとおり)
前半は何が聞きたいのかわからない。ポインタに1を足してるという点では等価だが、
評価順序とかアセンブラコードとか言い出したら等価ではないが、質問のポイントが書いていないので
答えようがない。
結論:>>55はど素人。引っ込んでろ。
60:デフォルトの名無しさん
10/07/02 16:05:36
初期化してないものを演算するな
61:デフォルトの名無しさん
10/07/02 16:42:01
>>60
上のはメモリに対する演算ではなく、ポインタの値を変化させてるだけだから、
参照してない以上、何も問題はない。
62:デフォルトの名無しさん
10/07/02 16:42:52
>>59
いちいち罵倒せずにはいられんのか。情けない奴。
63:デフォルトの名無しさん
10/07/02 16:43:16
ポインタ自体は説明すれば分かってくれる。
問題は表記だな。 Cのポインタ関連の表記が悪い。
64:デフォルトの名無しさん
10/07/02 16:47:22
>>62
罵倒?
ど素人に引っ込んでろと書いたら罵倒なのか?
あんまり詳しくない方は書かないでもらえますか、とでも書けばいいのか?(ワラ
65:デフォルトの名無しさん
10/07/02 17:18:53
>>63
でも代替案も却って煩雑だったりするし、
今更ポインタの文法が変わるわけがないので、
慣れてちょうだいとしか言いようがない。
一番いいのはC言語使わないことだけどね。
66:デフォルトの名無しさん
10/07/02 17:29:30
>>64
バカを晒さないようお願い申し上げます。
67:デフォルトの名無しさん
10/07/02 17:31:08
>>66
*ip + n = n;
とか書いちゃうバカに言われてもwwww
68:デフォルトの名無しさん
10/07/02 17:34:55
>>67
それは私ではありません。横で見てて見苦しいので
重ねてバカを晒さないようお願い申し上げます。
69:デフォルトの名無しさん
10/07/02 18:09:39
>>64
罵倒だとも。それがわからない程度の人間というわけでもあるまい?
70:デフォルトの名無しさん
10/07/02 22:53:16
>>63
BASICにもVARPTRとかVARSEGとかあるけどCのポインタで躓く人には
分からないよ
アセンブラ学んだりしてメモリの存在意識してからじゃないと
スっと理解するのは難しいんだろうな
いきなりC言語から始めると値しか視界に入らないと思う
71:デフォルトの名無しさん
10/07/03 02:29:03
ジョエル・オン・ソフトウェア
URLリンク(bit.ly)
">私のささやかな経験から言わせてもらうと、伝統的に大学のコンピュータ
サイエンスのカリキュラムで教えられているもので、多くの人がうまく理解
できないものが2つあった: ポインタと再帰だ。
"
72:デフォルトの名無しさん
10/07/03 03:28:48
短縮URLなんて全くクールじゃねえから。ソースはきちんと示せ
73:デフォルトの名無しさん
10/07/03 09:06:42
>>71
サンクス。クール内容だった。ポインタの理解が能力の見極めになるのはアセンブリ
言語を知らない人だけだろうな。知ってればレジスタ間接のようなものかですむ。逆に
アセンブリ言語知らなくてポインタを理解できる人は尊敬してしまう。どうやって理解に
至ったのかぜひ聞いてみたい。
74:デフォルトの名無しさん
10/07/03 09:16:19
俺ほとんどアセンブリ言語知らないけどポインタは理解できたぞ。
はっきりいってポインタはアセンブリ言語知ってるどうのじゃなくて、
どういう型システムがあってああいう文法になるのかっていうことが
ポイントなんだと思うよ。
75:デフォルトの名無しさん
10/07/03 09:22:08
再帰が理解できないって
高校数学で数列が理解できないレベルだろ
池沼認定
76:デフォルトの名無しさん
10/07/03 09:32:17
アセンブラなんて知らなくてもポインタは理解できるだろ
大事なのは、いまいじってるデータが物理メモリのどっかにおかれていて
そこにアクセスする仕組みがポインタだと理解することだ
一番面倒なところはプログラムの記述といくらにらめっこしてても理解できないっていうところかなぁ?
概念を理解しないといけないってのは義務教育ではあまりないからな
再帰はツリー構造のデータをいじらせれば一発で理解できるから
そんなに重要じゃないと思うけどね
はじめに教える人間がタコだと苦労しちゃうのかも・・・
77:デフォルトの名無しさん
10/07/03 10:10:21
>>74.,>>76
アセンブリ言語知らないと理解できないとは言っていない。知っていれば少しも
難しいものではないと言っている。ほとんど知らないとかではなくまったく知らない
人がどう理解していったのかを知りたい。そういう人を知らないので聞いてみたい。
78:デフォルトの名無しさん
10/07/03 10:18:39
>>77
データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
って必要にせまられたら一発で理解できたけど
画像とかさ
Aパートでロードした画像をBパートでもう一回使いたいんだけど?的な場面で
79:デフォルトの名無しさん
10/07/03 10:54:13
>>77
俺も同意。
BASICから初めて、その後C言語をやった時はさっぱりだったが
情報処理試験のためにCASLをやったらあっさり理解できるようになった。
80:デフォルトの名無しさん
10/07/03 10:59:11
配列とポインタの違いとかもアセンブラ知ってると理解が速いわな。
char *ptr;
char buffer[10];
_ptr: dc.l 0
_buffer: ds.b 10
puts(ptr);
puts(buffer);
move.l _ptr, -(sp) #ポインタを引数に渡す場合
jsr _puts
lea _buffer, -(sp) #配列を引数に渡す場合
jsr _puts
addq.w #8, sp
81:デフォルトの名無しさん
10/07/03 11:00:19
むむっ久しぶりなんで間違えた予感。
>lea _buffer, -(sp) #配列を引数に渡す場合
こんなアドレス形式はないな。
pea _buffer
だった。失礼。
82:デフォルトの名無しさん
10/07/03 11:32:05
テレビの中身を知らなくても、テレビを操作することはできる感じでポインタは使うことはできたけど
レジスタとメモリがどのように使われるのかを体感したら、理解が深まったのは覚えてる
83:デフォルトの名無しさん
10/07/03 11:39:38
おまえらレベルの低いところで理解できたつもりになっててワロスw
84:デフォルトの名無しさん
10/07/03 11:43:11
週末だというのに煽るしかやることがないなんて可哀想
85:デフォルトの名無しさん
10/07/03 11:45:29
賞賛からはほとんど得るものはない
人間は失敗から学んで成長する生き物
86:デフォルトの名無しさん
10/07/03 12:09:03
>>78
サンクス。
> データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
それだとポインタを使わなくても普通にできることでは?
> 画像とかさ
> Aパートでロードした画像をBパートでもう一回使いたいんだけど?的な場面で
言語を限らないとメモリーコピー、参照渡しなどポインタを使わない方法もある。
意地悪く書いたけどポインタを使えていると思う。上から目線ですまぬ。
87:デフォルトの名無しさん
10/07/03 12:10:49
> データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
そこにアクセスする方法にアクセスする方法だろポインタっつーのは
88:デフォルトの名無しさん
10/07/03 12:28:38
どうやって理解するも何もそのままだろうが
89:デフォルトの名無しさん
10/07/03 12:55:08
理解出来ない奴が理解出来ない
90:デフォルトの名無しさん
10/07/03 13:09:57
番号付き箱にモデル化されたメモリでの説明で理解した。
アセンブリは知らん。
91:デフォルトの名無しさん
10/07/03 13:17:40
>>87
ポインタってそんなに複雑なものか?
>>80のコンパイル結果を見ればただの long 定数があるだけだ。
これがポインタの正体。つまりポインタは int や long と同じようにメモリ上にとられる
エリア。それをデータのアドレスを入れるために使う。
このプログラムはぬるぽになる。本来の意味でぬるぽが使えるのに感動!
92:デフォルトの名無しさん
10/07/03 13:39:23
>>86
>それだとポインタを使わなくても普通にできることでは?
できねーだろ
ハンドル使ってもポインタは回避できないと思う
93:デフォルトの名無しさん
10/07/03 15:30:20
知らないことは誰だってあるけど、いいやんとか言って違いも調べず思考停止するやつは向上心もう少し持とうぜ
94:デフォルトの名無しさん
10/07/03 15:32:03
と、アンカーの使い方もわからない雑魚がいっております
95:デフォルトの名無しさん
10/07/03 16:12:00
>>92
aというメモリー上のデータにアクセスしてbという変数に入れる。
b = a;
どこにポインタを使う必要がある?
96:デフォルトの名無しさん
10/07/03 17:23:29
>>95
元の話題とまったくつながりが見えないんだけど
なんの話してるの?w
97:デフォルトの名無しさん
10/07/03 17:48:57
>>95 は固定長データしか扱ったことないんだよ
そっとしておいてやれよ…
98:デフォルトの名無しさん
10/07/03 18:34:20
アセンブリ言語を覚えたら
複雑な関数ポインタをスラスラ書けるようになっちゃうの?
99:デフォルトの名無しさん
10/07/03 18:35:38
アドレスにまつわる文法はアセンブリの方がわかりやすいかもな
100:デフォルトの名無しさん
10/07/03 19:16:58
>>96
>>87でポインタを使わなければデータにアクセスできないと書いているからそりゃ無い
だろと書いている。揚げ足取りに近いのだけど。
Cを使って大量のデータを使いまわしするということならポインタについてはそうだろう。
だから後に言語を限らなければとわざわざ書いている。
>>98
スラスラ書けるようになるかどうかはわからないがCでなぜポインタを取り入れたか、
何を実現したかったは理解できるようになる。
101:デフォルトの名無しさん
10/07/03 19:20:03
>Cでなぜポインタを取り入れたか、
>何を実現したかったは理解できるようになる
それはポインタの理解とは無関係
102:デフォルトの名無しさん
10/07/03 19:43:06
>>101
俺も同意見。
アセンブリ言語を理解したとして、
結局あの文法が正確に分かるようになるのかというと別だと思う。
たとえば、 const int (* const (*)(void))(void) なんてのがあったとしよう。
これはアセンブリ言語を知っていたとしても
ポインタ自体に精通していなければ文法上の
意味を正確に掴みかねると思われる。
裏でどういう値が動いているかは分かると思うが。
俺自身アセンブリ言語に詳しくないから
そう思うだけなんだけど識者の人はどう考えているの?
103:デフォルトの名無しさん
10/07/03 20:05:05
ポインタで引っかかる人はアセンブリ言語を知っていれば簡単にわかる程度の
ところで引っかかっていると思うが。
104:デフォルトの名無しさん
10/07/03 20:28:40
アセンブリの感覚だと、とりあえずvoid*にして後でキャストすればいいと思えるし
constはただの自己満足だとわかる。
必要最小限のサブセットと、自己満足のための高度な内容を分けて考えるべき。
105:デフォルトの名無しさん
10/07/03 20:33:39
int x=100;
int y=50;
int *p=&y;
int z=x/*p;
どうしてCはポインタの記号に*を採用したのか*/
106:デフォルトの名無しさん
10/07/03 20:41:22
>>104
あくまで>>102は例だ。
本当に箱を並べたポンチ絵程度のものが分からないことを
アセンブリ言語を知っていれば分かるようになるのか、
それともC言語的な文法も踏まえたことをアセンブリ言語を
知っていれば分かるようになるのか、そういうことを言いたいだけ。
ポインタで引っかかるって言っても、
↑の2種類はいると思うけどね。
107:デフォルトの名無しさん
10/07/03 21:24:21
ポインタと文法は別
ポインタはわかるが文法がわからないという話は聞いたことがない
だから文法自体は悪くない
悪いのは、文法以前で引っかかってる人に文法を踏まえさせること
108:デフォルトの名無しさん
10/07/03 21:35:36
ポインタの配列とか
ポインタのポインタとか
配列のポインタとか
言ってる人は判ってるなと思うけど
ダブルポインタって言ってる香具師は
馬鹿じゃねーのと思う
109:デフォルトの名無しさん
10/07/03 21:45:18
int **x; ←*が2つついてダブルポインタ
ではないの?
110:108
10/07/03 21:51:01
そうだよ
111:デフォルトの名無しさん
10/07/03 22:03:07
ポインタ自体は難しいと感じないんだけど
ポインタの配列、ポインタのポインタ
使うプログラムって難しく感じる
配列が多次元になったり
連結させたりするとな
112:デフォルトの名無しさん
10/07/03 22:09:25
おまいら
int main(int argc, char *argv[]) を使う派?
それとも
int main(int argc, char **argv) を使う派?
113:デフォルトの名無しさん
10/07/03 22:12:32
後者。引数のブラケットほど虚しいものはない。
114:デフォルトの名無しさん
10/07/03 22:13:55
Javaですねわかります
115:デフォルトの名無しさん
10/07/03 23:05:50
なぜJavaで引っかかる人が少ないのか
typedef void *Object;
typedef Object *Vector;
int main(int argc, Vector argv)
116:デフォルトの名無しさん
10/07/04 02:26:43
*p=10000;
117:デフォルトの名無しさん
10/07/04 06:17:05
めんどくさいときは構造体に入れて関数に渡すわ
118:デフォルトの名無しさん
10/07/04 06:20:21
yes we can
119:デフォルトの名無しさん
10/07/04 09:11:19
int* p;
int *p;
int * p;
アスタリスクの使い方がポインタの理解を阻害する
120:デフォルトの名無しさん
10/07/04 09:23:31
>>100
>>>87でポインタを使わなければデータにアクセスできないと書いているからそりゃ無い
>だろと書いている。揚げ足取りに近いのだけど。
は?>>87俺じゃねぇし
まったく話が見えない
121:デフォルトの名無しさん
10/07/04 09:50:02
都合悪いから「俺じゃねぇ」ですね
122:デフォルトの名無しさん
10/07/04 10:05:01
>>120
すまない。アンカー間違えてた。 >>78だった。
>>100のレスが無くても>>78にたどり着くので流れは分かると思うが分からないのなら
おれには説明できない。
123:デフォルトの名無しさん
10/07/04 11:29:50
>>119
俺のポインタ周りの混乱はそうだったなぁ。
俺の混乱履歴。
char *p;
char型の*pを宣言してるように見えてた。
char i;
i=1;
が正しいのだから、
char *p;
*p=1;
が正しくない理由が分からなかった。
加えて
char *p="abcd";
こんな表現もあって混乱した。*pにいきなり値を代入してるように見えるから。
実際にはpに代入していて、char*型のpを宣言してるんだと感じてから、
char* p;
と書くようにした。
そして
char* p,r;
でまた混乱。
124:デフォルトの名無しさん
10/07/04 11:47:41
意味を考えなくても文法知識をいじり倒すだけで正解を導けるという
思い込みのはげしい人が多いのはなぜか。
125:デフォルトの名無しさん
10/07/04 12:01:59
規格書が全てですが何か
コンパイルできるかできないかはシンタックスが正しいか正しくないかであって実行して悪魔が出るかどうかはセマンティクスに違反しているかしていないか
ポインタなんて単なる数値だよ
*をいくつ使うかで表現できる階層が変わるだけ、C言語でオブジェクト指向っぽく連想配列でも実装すれば理解できるよ
ポインタは複合型であり、構造体や共用体、ポインタ、配列などの複合型の不完全型をシンプルに表現できる抽象データ型なだけであって難しいことなど無い
126:デフォルトの名無しさん
10/07/04 12:15:44
Cを始めるにあたって、規格から調べる人は控えめに言ってマレでしょう。
普通は入門書や、入門webサイトを見る。
初めて見るソース、ソースから受ける第一印象はとても大事。
127:デフォルトの名無しさん
10/07/04 12:22:36
難しいことを難しく表現することは誰にでも出来る。
難しいことをやさしく表現することは、能力が無いと出来ない。
能力が著しく足りないと、簡単なことを難しく表現してしまう。
という言葉を思い出した。
128:デフォルトの名無しさん
10/07/04 12:36:07
>>119
C++ が普及する前の C のときは事実上
FILE *f;
だけだったはずで
FILE * f; とか
FILE* f; とか
書きかたしていると笑われたもんだ
なぜか C++ で本来の
HOGE *h;
は影を潜め
HOGE* h;
という書き方が横行するようになった
129:デフォルトの名無しさん
10/07/04 12:38:33
char* p,r;
でまた混乱。
なんで*が実質右ってことを忘れてんの?
130:デフォルトの名無しさん
10/07/04 12:39:47
>>128
>>123 みたいなアホのせいだな pgrw
131:デフォルトの名無しさん
10/07/04 12:41:22
>>123
> char *p;
>char型の*pを宣言してるように見えてた。
それで合ってる
何か変な本読んで混乱させられたんだな
かわいそうに
132:デフォルトの名無しさん
10/07/04 12:47:44
ここは"なぜポインタで引っかかる人が多いのか"を考えるスレ。
初心者が起こす勘違いを考えるスレ。
133:デフォルトの名無しさん
10/07/04 12:57:03
対象者が何につまずいているのかを想像する能力がなければ、
真の意味で教えることは難しい。
教える側に対象者のつまずきを理解する能力が無い場合、
対象者が理解できるかどうかは対象者の能力に依存する。
134:デフォルトの名無しさん
10/07/04 13:09:12
>>133
そうだな
簡単な話が理解出来ないのは
耳が悪いのかも知れないし
そもそも話を聞いてないのかも知れないし
頭が悪いのかも知れない
135:デフォルトの名無しさん
10/07/04 13:17:00
ポインタは正常に動くのにたまに変になることがある
int a[10];
a[10]=100;
みたいにやると、稀におかしくなる
コンストラクタとかifとかで複雑になってくると
よく見ると
int * p;
*p=100;
みたいなことを平然とやってたりする。
短いプログラムだとこんなことはしないだろうけど
複雑なプログラムだと初心者はわけがわからなくなる。
これが初心者にとって難しいんだろうな。
136:デフォルトの名無しさん
10/07/04 13:23:07
>>135
> a[10]=100;
正常に動くことがあるから、誤解の種になるよね。
必ず異常動作すれば気づくんだが。
char *p="abc";
*p='A';
これが正常に動く環境があって、
しばらく平気でそういう記述してた時期があった。
137:デフォルトの名無しさん
10/07/04 13:30:53
char* pの書き方だけは許さない。
こういう書き方をしている人物こそポインタで引っかかったままだと言える。
138:デフォルトの名無しさん
10/07/04 13:31:57
>>137
Microsoftのソフト開発者は全員そうだな。
139:デフォルトの名無しさん
10/07/04 13:41:21
結構、ポインタって文法の丸暗記で何とかなったりするからなぁ
int (*ptr)[10];
int a[100]; //mallocの代わり
ptr = (int (*)[10])a;
↑これを理解するのに結構時間かかった、特に関数の引数にしたときとか
アドバイスもらって、アセンブラ入門を勉強したら理解できるようになったんだよな
多分、実際のメモリ範囲確保とインデックスによるアドレス指定が理解の助けになったと思う
140:デフォルトの名無しさん
10/07/04 13:44:58
>>137
char *p[10];
char (*p)[10];
*がpに付くのなら上記は同じ意味になるだろう。
*が宣言に付くからこそ(*p)とすることで違う意味になる。
そういう意味からは
char* p;
のほうがしっくり来る。
俺は char *p; と書くけどね、char* p0,p1; のことがあるからね。
141:デフォルトの名無しさん
10/07/04 13:46:46
やたら記述にこだわってて内容理解してそうにない書き込みが多いところが恐怖
142:デフォルトの名無しさん
10/07/04 13:48:30
C#では
int* p,q,r;
ってやったらpもqもrも
CやC++でいう
int *p,*q,*r;
みたいに、全部が*つけたようになるな
アンセーフモードでしか実行できないけどね
Microsoftのポインタに対する意識が明確に現れてるな
143:デフォルトの名無しさん
10/07/04 13:58:02
>>126
第一印象に敏感な人は重症化しやすい、という意味では大事かもしれないが
本来は、印象なんてあやふやなものには鈍感なほうが良い
>>141
上のほうで、文法より意味を考えようぜっていう正論が出たから
逆の書き込みをすれば色々釣れるだろうと思ってるのかもしれん
144:デフォルトの名無しさん
10/07/04 13:58:46
char *p;
char (*p);
上記は同じものを指すが、結果として同じものをさすだけであって、
その意味合いは異なる。
前者は"char*型のpの宣言"であり、
後者は"pはポインタであって、そのポインタはcharを格納するアドレスのポインタ"。
それが理解できなければ、
char *p[10];
char (*p)[10];
は理解できない。
145:デフォルトの名無しさん
10/07/04 14:03:27
ホント記述弄り好きだな
こんなの覚えてもしょーがねーだろ
146:デフォルトの名無しさん
10/07/04 14:09:25
>>145
しょうがなく無いぞ
char *p[10];
char (*p)[10];
どっちの意味でも使うことあるから。
宣言の*が型に付くことを知っていれば、
前者のpが配列、後者のpがポインタだと理解しやすい。
147:デフォルトの名無しさん
10/07/04 14:14:23
int a[10][10];
148:デフォルトの名無しさん
10/07/04 14:19:29
それは別にポインタが難しいからじゃなくて、C言語が難しいから。
文法云々というか、プログラマの責任がデカい部分。
149:デフォルトの名無しさん
10/07/04 14:23:31
>>146
*(p[10]) か (*p)[10] かの違いだよ。前者の括弧は冗長だから書かないだけ。
*は前置単項演算子だから、被演算子は常に後ろに付く。型に付くことはない。
150:デフォルトの名無しさん
10/07/04 14:42:16
なにいってるんだ
int * p
の*は演算子ですらないぞ
*p=&x
みたいのでpの←の*は演算子だけど。
151:デフォルトの名無しさん
10/07/04 14:47:48
>149
知ったかは口はさむな
152:デフォルトの名無しさん
10/07/04 14:55:06
説明する能力がなければ、真実を伝えることが難しい例。
説明する能力があれば、真実でなくても実質問題の無い考え方を伝えることが出来る例。
153:デフォルトの名無しさん
10/07/04 15:26:43
mallocだのなんだの使うより
new int
のほうがわかりやすいよね
154:デフォルトの名無しさん
10/07/04 16:57:46
>>144
意味合いも型も全く同じ。
どちらも*演算子を適用するとcharになる。
>>146の意味合いは演算子の
結合が異なるから意味が異なって当然:
・char *p[10] =>char *(p[10]) => pに[]したあと*すればcharになる
・char (*p)[10] => pに*したあと[]すればcharになる
変数の記述と同じように演算子を適用したら、
最終的に一番左に書いたcharやらが取得できるのがポインタの文法。
155:デフォルトの名無しさん
10/07/04 23:34:12
ポインタで引っかかる人が多い、というより
Cのポインタで引っかかる人が多い、の方が正確だろうな。
C以外でポインタで引っかかる人の話はほとんど聞かない。
Cのポインタも、言語規格を読めば別に難しくないが、直感では理解しにくい。
156:デフォルトの名無しさん
10/07/05 00:47:28
とりあえず複数変数宣言を一行でやるのやめろや・・・
見づらくて仕方ない。
157:デフォルトの名無しさん
10/07/05 00:52:23
>>131
あってないだろ
*pが変数名ならポインタ使用するときpって書くなよ
*とpを分解するなよ
*とpがくっついて初めてIDなんだろ?って思った
あくまでpはchar*型の変数だろ
だから*演算子でポインタpの値参照できるんだし
158:デフォルトの名無しさん
10/07/05 01:15:16
↑
char *p
*pはchar型であってるよ
*pは変数名じゃないよ
pが変数名だよ。
159:デフォルトの名無しさん
10/07/05 01:30:09
char * p
「char型」の「ポインタ(*)」の「変数p」と言った方がいいかな。
160:デフォルトの名無しさん
10/07/05 01:41:40
*pの型がcharとかは関係なくて
char *p;で宣言される変数はp
てだけだろ。
*pは宣言されてない。
配列とかでも同じだからなぁ。
特に分かりづらいと思ったことなかった。
161:デフォルトの名無しさん
10/07/05 03:57:28
幅WID, 高さHEIのint型の二次元配列arrayを動的に確保したい。
1)arrayの宣言文を書け。
2)arrayのメモリ確保文を警告レベル最大でも警告が出ないように書け。
3)arrayの要素アクセス方法、具体的にはarray中の横からw番目、縦にh番目の要素に0を代入する文を書け。
162:デフォルトの名無しさん
10/07/05 06:43:49
>>159
char*型の変数pでいいよ。
変数名取り除いたのが型の名前だし。
>>161
とりあえずC99禁止しようか。
163:デフォルトの名無しさん
10/07/05 07:37:57
>161
二次元配列ってなんだ
配列の配列か
一次元的に取られたメモリを工夫して二次元的に扱える形にしろというのか
一次元的に取られたメモリを工夫して三次元的に扱える形にしろ
ただし、外側から縦、横、奥を表すとし、メモリの確保は1回で実行せよ
また、型は適当なものをtypedefし、type_t型として作成せよ
ただし、縦、横、奥は実行時に与えられ、特定のtype_t型に依存するコードは書いてはならない
縦、横、奥はsize_t型を仮定してよいものとする
全ての縦、全ての横、全ての奥のアドレスに対してそのアドレスがそのアドレス以外のものと異なるようにせよ
全ての縦、全ての横、全ての奥の要素に対して任意の値を代入し不正なメモリ書き換えが行われないようにせよ
メモリの確保には標準関数のvoid *malloc(size_t)を使用せよ
ここで、言語仕様はC89またはC90を仮定してよいものとする
ただし、コンパイラの拡張を使用することを禁止する
例 : type_t ***array3; array3 = alloc3(h, w, d); array3[h][w][d] = val;
164:デフォルトの名無しさん
10/07/05 08:05:39
前の問題の答も出さずに勝手な問題積み上げてバカじゃないの
165:デフォルトの名無しさん
10/07/05 11:18:28
スレタイとは何の関係もない話題になった。
166:デフォルトの名無しさん
10/07/05 15:19:30
*********************************************p
167:デフォルトの名無しさん
10/07/05 16:37:36
*は2つあれば十分
3つ以上使うコードがあっても、void**とキャストを使うコードに変換できる
168:デフォルトの名無しさん
10/07/05 16:46:54
変換できることに意味はないな。適当にtypedefし直せば充分。
169:デフォルトの名無しさん
10/07/05 16:57:39
バイナリエディタで機械語書かせれば一発で理解できると思うんだ
170:デフォルトの名無しさん
10/07/05 17:15:05
誰も>>161には答えられない、と。
171:デフォルトの名無しさん
10/07/05 17:21:17
興味が無ければ答えない。当たり前だと思うが。
172:デフォルトの名無しさん
10/07/05 17:24:00
今まさに仕事でその手のコードを書いているからめんどくさいw
CPUとGPUの違いやsimdの演算効率の違いを考慮して、
AofSとSofAを切り替えたりxyzの順序を変えたりの詰め替えばっかりw
173:デフォルトの名無しさん
10/07/05 18:09:33
>>170
配列へのポインタでいいのか?
174:デフォルトの名無しさん
10/07/05 18:32:08
>>161
1) int *array;
2) array = (int*) malloc(sizeof(int) * WID * HEI);
3) array[h * WID + w] = 0;
Java使いでちゃんとしたCのコードなんか書いたことないんだけど、
これでいいのかな?このスレにいる詳しい人添削頼む。
あと>>163も同じように処理しちゃまずいのかな。
175:デフォルトの名無しさん
10/07/05 18:52:55
>>174
2次元配列と書いてるから、array[WID][HEI}の形にしないと駄目だろうね
>>161の条件だと↓でもよさそうだけど、>>163はひと手間かけないといけない
int (*array)[HEI] = (int (*)[HEI])malloc(sizeof(int) * WID * HEI);
176:デフォルトの名無しさん
10/07/05 18:56:41
一回でメモリ確保せよとはあるけど必要充分にとは書いてないから、
3次元分のメモリとポインタ分のメモリを確保してポインタの配列をこさえればいいんだけどね。
177:デフォルトの名無しさん
10/07/05 22:16:21
>>163
>ただし、縦、横、奥は実行時に与えられ、特定のtype_t型に依存するコードは書いてはならない
これは↓がだめだという意味?
typedef char (*type_t)[w][d];
type_t array = (type_t)malloc(sizeof(int) * h * w * d);
178:177
10/07/05 22:17:04
1行目
typedef int (*type_t)[w][d];
ね。
179:デフォルトの名無しさん
10/07/05 22:27:24
typedefしなくていいのなら、
for文で回しながらmallocして、
for文で回しながらfreeすれば出来そうだけど。
(そこまでするんならいっそ1次元でとって、添え字演算したほうがすっきりしそうだが・・・)
>>163 は出来るのかね。
180:デフォルトの名無しさん
10/07/06 02:01:16
URLリンク(kansai2channeler.hp.infoseek.co.jp)
自分で書いていて途中で嫌になってきた
typedefを使わないとほとんど読めないプログラムになってしまうのが
ポインタの問題だな
関数へのポインタの配列へのポインタを返す関数
(関数は配列を返す事ができないので配列へのポインタで返す)
でも無駄な事を一段やってるような気がするな
配列だと分かっているんだから配列を変えそうとせず、ポインタで配列の
先頭アドレスを返せば簡単になるような気もする
181:デフォルトの名無しさん
10/07/06 02:16:07
いや違うかこれ以上簡単にならんな
関数は配列を返す事が出来ないんだから、配列へのポインタを
返すと書かなければならない
本当はそうではないのだが、Cの文法がそう書く事を許さない仕様に
なっている
こういう場合は関数宣言の方を変えて、配列を返すのではなく関数への
ポインタのポインタを返すと書けば簡単になるだろう
但しそう書くとプログラムが何をやっているのかますます不明瞭になり、
ほとんど読み解く事が困難になってしまう
182:デフォルトの名無しさん
10/07/06 02:20:23
URLリンク(kansai2channeler.hp.infoseek.co.jp)
こんな感じ
これなら一段間接参照が減る
さて寝よう
183:デフォルトの名無しさん
10/07/06 08:36:52
array[h * WID + w]でいいよ
ひとつ言えることは
ポインタで引っかかる人は、文法や型にこだわる
問題を出されると出題者に盲従する傾向がある
だったら、文法や型や規格書などに従うのを一度やめてしまえばいい
たとえばアセンブラを使ってみるとか
184:デフォルトの名無しさん
10/07/06 10:38:36
それでいいなら、int array[W][H];も必要ないね
185:デフォルトの名無しさん
10/07/06 10:46:20
[W][H] じゃなくて [H][W] だというところには誰も突っ込まないんだなw
186:デフォルトの名無しさん
10/07/06 10:57:25
言いたいことそんな所じゃないだろうからな。
187:デフォルトの名無しさん
10/07/06 10:58:23
メモリのスキャン方向が変わるから実行速度等に影響が出るんだが
188:184
10/07/06 11:56:51
>>175から持ってきて、あんまり考えずに成形しただけだから気にするな
>array[h * WID + w]でいいよ だけだったら異論はないよ
あとあと、楽とわかってるから静的に2次元配列として宣言するんだよね
動的確保でも、その楽にする方法があるから、(言い方を借りれば)文法にこだわるんじゃないか
まぁ、これも>問題を~の1文がなければ、そうですねって話だけど
189:デフォルトの名無しさん
10/07/06 11:57:59
>>79
俺と全く同じ奴がいる・・・
190:デフォルトの名無しさん
10/07/06 12:33:04
>>184
array[WID][HEI] と array[h * WID + w] は等価ではない
191:184
10/07/06 12:51:07
>>190
なぜ、俺にこのタイミングでレスするんだ
安価は>>175にしてくれよな
192:デフォルトの名無しさん
10/07/06 12:56:11
アホ曝しage
184 デフォルトの名無しさん [sage] 2010/07/06(火) 10:38:36 ID: Be:
それでいいなら、int array[W][H];も必要ないね
193:デフォルトの名無しさん
10/07/06 14:40:57
>>183
良くない。
array[h][w]という表記ができない言語(例えばアセンブラ)ならそれでもいいが、
言語仕様で出来るのにやらないと、後から読んだ者を混乱させる。
理由があってわざとやらないのか、書いた奴が知らなかっただけなのか判断つかないからな。
それに、hとかwとかなら array[h*WID+w]でもarray[h][w]でも大差ないが、もっと複雑な式に
なった時に、[h][w]形式の方が断然読み易くなる。
ぶっちゃけ、二次元ポインタを使いこなせない奴の言い訳にしか見えない。
194:デフォルトの名無しさん
10/07/06 15:49:07
どうでもいい。
個人的にはベタバッファにポインタアクセスのが分かりやすいし、使いやすい。
C++は知らんがCなら慣れの問題。
195:デフォルトの名無しさん
10/07/06 15:58:19
array[i][j] と記述したくなるのは、ベクトルやマトリックス周辺だけかな。
数式をそのままに近い形式で記述したい という意図だけどね
196:デフォルトの名無しさん
10/07/06 16:09:18
結果あわせるだけならどっちでもいいんだけれども
配列のアライメントや入れ替えがあるから、用途によるよね
197:デフォルトの名無しさん
10/07/06 16:42:13
>>190
どう等価じゃないんですか?
198:デフォルトの名無しさん
10/07/06 16:56:35
array[4][5]とarray[5][4]は違うと言っている。
199:デフォルトの名無しさん
10/07/06 18:54:32
こういう書き方はどうか?(長文失礼)
・char , int は型である。
・Tが型ならば、T[N]は型である。(Tの配列と解釈する)
・Tが型ならば、$Tは型である。(Tへのポインタと解釈する)
・T,U1,U2,…,Umが型ならば、T(U1,U2,…,Um)という記号列は型である。(関数と解釈する)
・宣言方法は「T a;」とする。
具体例(カッコは適宜省略) C言語での表記法
↓ ↓
int a; ( int a;という意味)
int[N] a; ( int a[N];という意味)
(int[w])[h] a; ( int a[h][w];という意味。wとhは逆になる)
$int a; ( int* a; )
int(char) func; ( int func(char); )
$($int) a; ( int** a; )
($int)[N] a; ( int* a[N]; )
$(int[N]) a; ( int (*a)[N]; )
$(int(char)) f; ( int (*f )(char); )
($int)(char) f; ( int* f (char); )
int($char) f; ( int f (char*); )
($(int(char)))[N] f; ( int (*f [N])(char); )
($$(int(char)))[N] f; ( int (**f [N])(char); )
$(($(int(char)))[N]) f; ( int (*(*f )[N])(char); )
200:デフォルトの名無しさん
10/07/06 19:03:33
ご苦労さん
201:デフォルトの名無しさん
10/07/06 19:14:30
>>193
記述の問題ならマクロ導入すりゃいいでしょう
202:デフォルトの名無しさん
10/07/06 19:17:35
まあな。w
203:デフォルトの名無しさん
10/07/06 19:33:38
ポインタに1足したら、2byteとか4byteとか進む?
ポインタってアドレスなんだろ?
そんなもん1進むに決まってるんじゃないのか?
204:デフォルトの名無しさん
10/07/06 19:41:18
オブジェクト(要するに型)のサイズ分進む。
sizeof演算子で進む量を得ることが出来る。
205:デフォルトの名無しさん
10/07/06 19:58:50
>>197
判ってて聞いてるんだろうけど
array[h * WID + w] と array[w][h] はポイントしているアドレスが違う
array[h * WID + w] と array[h][w] が同じ場所を指さないと
共同開発してる仲間に迷惑だろ?
そんなことも知らないからポインタスレに来てるんですねわかります
206:デフォルトの名無しさん
10/07/06 20:21:03
前者は連続した領域にmallocすることが求められるが、
後者は離れた領域にmallocしても一向にかまわない。
207:デフォルトの名無しさん
10/07/06 20:22:13
そろそろ>>163の見本お願いします
208:163
10/07/06 20:58:16
>>207
まあ、あせるな
みんな、なかなかいい線いってるよ
もう少し検討が深まるのを待とう
209:デフォルトの名無しさん
10/07/06 21:32:28
>>208
これはだめなの → >>177
C89ならw,dが変数でも通ったけど。
210:デフォルトの名無しさん
10/07/06 21:41:09
>209
>208ではありませんが、コンパイラとコンパイルオプションを示してみてください
また、可能であればコンパイラのバージョンも示してみてください
211:デフォルトの名無しさん
10/07/06 22:00:20
>>210
PC@Test> gcc --version
gcc.exe (GCC) 3.4.5 (mingw special)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
PC@Test> gcc -Wall -pedantic -std=c89 Test6.c
Test6.c:14: warning: ISO C90 forbids variable-size array `type_t'
Test6.c:14: error: variable-size type declared outside of any function
Test6.c:14: warning: ISO C90 forbids variable-size array `type_t'
Test6.c:14: error: variable-size type declared outside of any function
ごめん、今やったら通らんわ。
212:221
10/07/06 22:01:09
昨日、下記のソースをいじってら通ったんでC89ならOKなんだと思ってた。
昨日の試行錯誤の過程で勘違いした模様。
#include <stdio.h>
#include <stdlib.h>
#define MODE (0)
#if MODE == 0
int w = 10;
int d = 20;
#elif MODE == 1
const int w = 10;
const int d = 20;
#elif MODE == 2
#define w (10)
#define d (20)
#endif
typedef char (*type_t)[w][d];
int main(void) {
int h = 30;
type_t array = (type_t)malloc(sizeof(char) * h * w * d);
printf("%d\n",((int)&array[0][0][1])-((int)array));
printf("%d\n",((int)&array[0][1][0])-((int)array));
printf("%d\n",((int)&array[1][0][0])-((int)array));
free(array);
return 0;
}
213:デフォルトの名無しさん
10/07/06 22:08:40
てか何が出来たら「三次元的に扱え」たコトになるのよ?
条件が色々付いてるけど、根本的な要求が分からん
214:デフォルトの名無しさん
10/07/06 22:11:01
下記のポンタ何を指すが書きなさい
15秒以内の回答できて小学1年レベルらしい
int (*a)[N];
int (*f )(char);
int (*f [N])(char);
int (**f [N])(char);
int (*(*f )[N])(char);
215:デフォルトの名無しさん
10/07/06 22:15:02
>>214
日本人ではないな?
だからどう、ということもないが
216:デフォルトの名無しさん
10/07/06 22:51:32
m行n列の二次元配列をメモリ上に表現する場合
1 サイズm*nの一次元配列として確保
2 サイズmのポインタの配列とサイズnの一次元配列m個
1の利点 ポインタの配列分メモリが必要無い
2の利点 列を削除追加できる
2は多段のポインタなので
普通の二次元配列として扱うと遅い
中継用のポインタ使う必要があるので可読性は低い
217:デフォルトの名無しさん
10/07/06 22:53:54
2 はargvですね
218:デフォルトの名無しさん
10/07/06 22:57:59
小学生すごいな、即答出来ても15秒で書けないな
219:デフォルトの名無しさん
10/07/06 23:01:51
>>218
小学生でも朝鮮・中華の小学生だから
220:デフォルトの名無しさん
10/07/06 23:07:14
>>214
上から順に
行列の行単位で動くポインタ
関数ポインタ
ポインタ配列
ポインタ配列
行列の行単位で動くポインタ
行列やポインタ配列の要素の型、つまりテンプレート引数に相当する部分は気にしない。
昔のJavaはそうだったというかむしろシンプルでわかりやすいとか言われて普及した。
221:デフォルトの名無しさん
10/07/06 23:28:34
>>216
>2は多段のポインタなので
>普通の二次元配列として扱うと遅い
これマジ?
ケースバイケースだろうけど、乗算して加算して参照より、
参照してさらに参照のが速いのかと思ってた。
222:デフォルトの名無しさん
10/07/06 23:43:30
>>221
F-22とスピットファイアくらい違う
223:デフォルトの名無しさん
10/07/07 00:00:13
>>214
ポンタはわからねえな
224:デフォルトの名無しさん
10/07/07 00:08:27
>>223
上から順に
ポインタ
ポインタ
配列
配列
ポインタ
なのは分かるよね。
後は、ポインタだったらポインタの部分を削除して型を見て、
配列だったら配列の部部を削除して型を見る。
そうすると、
配列のポインタ
関数のポインタ
関数のポインタの配列
関数のポインタのポインタの配列
関数のポインタの配列のポインタ
となる。
合ってる?
225:デフォルトの名無しさん
10/07/07 00:11:02
>>180の
int (*((*func(void))[]))(void)
これ鬼みたいだな
しかしプログラムを読むと大して難しい事をやっているわけではない
Cの宣言はどうしてこんなに難解なのだろうか
226:デフォルトの名無しさん
10/07/07 00:12:49
>>222
どっちが速いのかすら分からん。
あー、もしかしてキャッシュに乗らない?
あんまりその世界で生きてないんで
どう動くのかサッパリ。
227:デフォルトの名無しさん
10/07/07 00:17:46
>>225
アセンブリをやれば簡単に読めるようになる
228:デフォルトの名無しさん
10/07/07 00:33:24
int (*((*func(void))[]))(void)
は保育園レベルでちゅよ
この程度すぐに解らんと保育園レベル未満の国語力ってことでちゅ
229:デフォルトの名無しさん
10/07/07 00:44:13
>>225
リンク先は見てないけど、そんなに難解?
ちゃんと()付いてるし。
まず一見してfunc(void)な関数の宣言だろ。
*付いてるから返値はポインタ。
さらに[]なんで配列のポインタ。
次の*で、ポインタの配列のポインタ。
で、最後にint ()(void)なんで、つまりこの宣言は
そういう関数へのポインタの配列のポインタを返す、引数voidな関数funcの宣言。
長々書いて違ってたら、凄い恥ずかしいんだが、どないだろ?
230:デフォルトの名無しさん
10/07/07 01:14:43
>>229
>長々書いて違ってたら、凄い恥ずかしいんだが、どないだろ?
どのように解析するか自信ないのか?
コンピラー(C言語)の構文解析ルールをよく知らないってこと?
コンピラーはfunc(void)が関数の宣言ってどうしてそう判断するん?
職業PGにとって構文解析って基礎中の基礎事項で学校で当然習っているじゃないの
それすら知らないのに職業PGやってるって人居ないよね
趣味PGなら自分が必要と感じたら勉強してみるか程度で良いけど
231:デフォルトの名無しさん
10/07/07 01:26:06
>>221
キャッシュへのプリロードするのに間接参照だと予測不能。
232:デフォルトの名無しさん
10/07/07 01:41:39
書き方を修正。「$T」じゃなくて「T$」に変えてみた。
・char , int は型である。
・Tが型ならば、T[N]は型である。(Tの配列と解釈する)
・Tが型ならば、T$は型である。(Tへのポインタと解釈する)
・T,U1,U2,…,Umが型ならば、T(U1,U2,…,Um)という記号列は型である。(関数と解釈する)
・宣言方法は「T a;」とする。
233:デフォルトの名無しさん
10/07/07 01:46:37
以下、具体例。(長文失礼します)
具体例(カッコは適宜省略) C言語での表記法
↓ ↓
int$ a; ( int* a; )
(int$)$ a; ( int** a; )
(int$)[N] a; ( int* a[N]; )
(int[N])$ a; ( int (*a)[N]; )
(int(char))$ f; ( int (*f )(char); )
(int$)(char) f; ( int* f (char); )
int(char$) f; ( int f (char*); )
((int(char))$)[N] f; ( int (*f [N])(char); )
((int(char))$$)[N] f; ( int (**f [N])(char); )
(((int(char))$)[N])$ f; ( int (*(*f )[N])(char); )
$が入ってないものは>>199と
全く同じになるので省略しました。
234:デフォルトの名無しさん
10/07/07 02:27:17
>>232の定義に
・Tが型ならば、T[ ]は型である。
をつけ加えると、>>180の
>int (*((*func(void))[]))(void)
これも232の形式で書けて
((((int(void))$)[ ])$)(void) func;
となります。
また、T[N]$ と書いたとき、これを(T[N])$と読むことは出来ても
T([N]$)と読むことは出来ないし、T$$とかT$[N]なども同様のことが
言えます。よって、ある程度カッコを省略できて、結局、
次のように表記できます。
((int(void))$[ ]$)(void) func;
235:デフォルトの名無しさん
10/07/07 04:45:01
関数ポインタ関連の表記は参考サイトや本を読みながらじゃないと読めん
あれ何とかならんかったんか
236:デフォルトの名無しさん
10/07/07 04:58:29
typedef すれば大抵解決
237:デフォルトの名無しさん
10/07/07 07:18:47
>>230
煽りか本気か知らんが、職業PGに夢見すぎ
238:デフォルトの名無しさん
10/07/07 07:30:54
関数ポインタが読みにくいという事はCでC++モドキのプログラムを
バリバリ書くのは不可能に近いって事ですね
それか無駄な時間を多量に要するか
239:デフォルトの名無しさん
10/07/07 11:32:30
>>238
他の言語に比べて積極的な気持ちになりにくいかな?
ただ、昔読んだテキストエディタのソースでは、入力文字のアスキーコードを引数にして各入力処理関数に飛ぶように、関数ポインタの配列が使われていて感動した。
日本語処理をさせるのは難しそうだけど。
240:デフォルトの名無しさん
10/07/07 13:03:10
perlよりマシだな
241:デフォルトの名無しさん
10/07/07 13:53:02
エセクラスならgtk2が頑張ってなかったっけ?
242:デフォルトの名無しさん
10/07/07 14:11:48
gtk++/gtkmm よりも gtk の方が出来が良いという
243:デフォルトの名無しさん
10/07/07 17:04:48
>>229
あってますね
規則に従って変換したら、>>234になったw
int(void)*[]* (void) func
244:デフォルトの名無しさん
10/07/07 18:29:24
>>235
>>232-234の書き方だと、日本語の語順そのままで
宣言できます。たとえば、
・(戻り値int,引数charの関数)へのポインタ
が欲しかったら、そのまま
(int(char))$ pfunc;
と書けます。>>180の
>int (*((*func(void))[]))(void)
だったら、これを日本語読みすると
(((戻り値int,引数voidの関数)へのポインタ)の配列)へのポインタ)
を戻り値とする、引数voidの関数
となるので、この語順そのままに
(int(void))$[]$ (void) func;
と書けます。
245:デフォルトの名無しさん
10/07/07 21:45:29
>>244
君は度々出て来るようだけど、結局主張は何?
246:デフォルトの名無しさん
10/07/07 22:04:51
>>245
>>232-234の書き方なら、C言語よりも
ずっと読みやすい表記法で関数ポインタが表記できる、
ということです。
247:デフォルトの名無しさん
10/07/07 22:05:17
>>245
型の表記は関数型言語スタイルがいいですね、ということです
248:デフォルトの名無しさん
10/07/07 22:08:02
typedef の方が判りやすいよ
249:デフォルトの名無しさん
10/07/07 22:29:47
>>248
typedefの方法は>>232-234と同じようなもんです。
あなたにとってtypedefが分かりやすいなら、
ほぼ同程度に232-234も分かりやすいことになります。
たとえば、C言語で
typedef int (*PFUNC)(char);
と書いておけば、もはや
PFUNC pfunc;
と書くだけで「(戻り値int,引数charの関数)へのポインタ」が
宣言できるようになりますが、このときの「PFUNC」という記号列は、
>>232-234で言うところの「(int(char))$」という記号列と
全く同じ役割をしています。つまり
Func ≡ (int(char))$
ということです(誤解を招きそうな式ですが)。
別の言い方をすれば、「PFUNC pfunc;」と同じ語順の宣言が
最初から可能なのが>>232-234ということです。
250:デフォルトの名無しさん
10/07/07 22:39:24
ou....
× Func ≡ (int(char))$
○ PFUNC ≡ (int(char))$
251:デフォルトの名無しさん
10/07/07 22:41:50
んなことは言われんでもわかっとる
(int(char))$
よりも
PFUNC
の方が判りやすいだろって話
252:デフォルトの名無しさん
10/07/07 22:52:58
>>246
よく分かった。
新しい言語、文法を語りたいだけなら、引っ込んで黙れ。
そういうスレがあるし、そっち行け。
ポインタが分かりづらいのはCの文法が悪いから、とか
それなりのコト言うのかと思えば、ただのアホかよ。
253:デフォルトの名無しさん
10/07/07 22:55:49
>>251
どうですかね。「PFUNC」と書いてしまうと、中身が
見えなくなって抽象的になってしまう弊害があります。
(int(char))$だったら、そのまま読めます。
しかも日本語の語順のまま読めます。
僕にとってはint(char)$ の方が読みやすいです。
ただし、PFUNCという記号列を日常的に
typedef int (*PFUNC)(char);
の意味で使っている人だったら、その人にとっては
PFUNCという記号列は全く抽象的では無いわけですから、
その人にとっては、PFUNCの方が読みやすいかもしれません。
254:デフォルトの名無しさん
10/07/07 22:59:14
ひとつのプロジェクトに
独自のGC、newが複数混在してると
最高にわかり辛い
それぞれが読みやすいものでもな
255:デフォルトの名無しさん
10/07/07 23:02:06
>>252
>ポインタが分かりづらいのはCの文法が悪いから、とか
>それなりのコト言うのかと思えば、ただのアホかよ。
え?それって同じことですよね?
「ポインタが分かりづらいのはCの文法が悪いからだ!」
という意見を煮詰めて行ったら、どのみち
「では、文法をこのように変えたらどうだろうか(例えば232-234のように)」
という意見にならざるを得ないでしょ?
256:デフォルトの名無しさん
10/07/07 23:09:36
// それぞれが読みやすい
typedef int (*PFUNC)(char);
typedef PFUNC T[N];
// 混在すると分かり辛い
typedef int (*T[N])(char);
257:デフォルトの名無しさん
10/07/07 23:48:51
混在してると分かりづらくなる文法が悪い?どっちが悪い?混在が悪い?文法が悪い?
258:デフォルトの名無しさん
10/07/07 23:58:37
>>255
ならんよ。
だってその表記を見ても、Cのポインタが
理解できるようになりそうにないもの。
言語変えて済む話ならポインタのない言語を選べばいい。
259:デフォルトの名無しさん
10/07/08 00:17:00
>>258
言ってることが矛盾してませんか?あなたにとって、
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見は"それなりの意見"なんですよね?(>>252にそう書いてあるし。)
でも、これは「Cの文法を改良すればポインタが分かるようになる」と
言っているのと同じことですよ。
一方であなたは
>言語変えて済む話ならポインタのない言語を選べばいい。
と言ってますから、結局あなたは
「Cの文法を改良すればポインタが分かるようになる」
という意見を全否定しているわけです。つまり、あなたは
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見を"それなりの意見"としつつも全否定しているわけです。
260:デフォルトの名無しさん
10/07/08 00:22:48
●Cのポインタの文法は分かりづらい
●文法を変えたらもはやCではない
これは矛盾しないぞ
261:デフォルトの名無しさん
10/07/08 00:38:11
>>260
これはひどいww
というのはさておき、
>●Cのポインタの文法は分かりづらい
これは単に文法の煩雑さを嘆いているだけであって、
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見とは全く別物ですよね。
262:デフォルトの名無しさん
10/07/08 06:58:00
>>259
それなりの意見というのは、少なくとも
ポインタで引っかかる理由を言っている点においてそれなり。
それを解決する方法として、別の文法を考えるという
アプローチは全否定してるよ。
理由はCのポインタの理解に役立たないから。
そんなに矛盾してる?
263:デフォルトの名無しさん
10/07/08 07:16:57
全否定はつられて言いすぎた。
なにがしかのモデル的に、理解の役に立つならいいんじゃないの?
「僕の考えた宣言の文法はスバラシイんです」
だから何なんだよ?
264:デフォルトの名無しさん
10/07/08 07:26:12
Cを普通に勉強すれば済む話。
どっかの馬の骨の自分ルールはもうお腹一杯。しかも読みやすくなってないし。
265:デフォルトの名無しさん
10/07/08 07:48:01
>>263
>「僕の考えた宣言の文法はスバラシイんです」
>だから何なんだよ?
それだけです。少なくとも>>235みたいな人の役には立ちますよね。
まあ、文法なんて結局は慣れの問題ですが。
>>264
あなたはCの文法に毒されすぎです。結局は慣れの問題に終始しますが、
それにしてもCの文法は「変」ですよ。誰でも一度はそう思うはずです。
熟練するほど忘れていく感覚ですが。
266:デフォルトの名無しさん
10/07/08 08:11:43
>>264
>どっかの馬の骨の自分ルールはもうお腹一杯。
「自分ルール」と呼べるほど独りよがりな書き方では無いでしょう。
日本語読みの語順に忠実な表記を採用しているだけです。
ていうか、日本語読みの単なる省略記法です。
ポインタの宣言を日本語読みしたら、「intへのポインタ」
「(戻り値int,引数charの関数)へのポインタ」のように、
必ず「Tへのポインタ」という言い回しをするわけです。よって、
日本語読みに忠実なポインタ宣言の表記法は「T$ p;」とか
「T* p;」になります。
配列の宣言は必ず「Tの配列」という言い回しをしますから、
「T[N] a;」とか「T[ ] a;」という表記法が忠実です。
C#の場合は、配列の宣言はT[ ]ですよね(採用した理由は違うでしょうけど)。
関数の宣言は「戻り値T,引数U1,U2,…,Unの関数」と言いますから、
「T(U1,U2,…,Un) func;」という表記法が忠実です。
これがそんなに「自分ルール」ですかね?
267:デフォルトの名無しさん
10/07/08 08:16:40
(長文ゴメンナサイ)
さて、どのような宣言の日本語読みも、構文解析のように分解すれば
「Tへのポインタ」「Tの配列」「戻り値T,引数U1,U2,…,Unの関数」に
分解できますから(ただし、ここでは構造体やクラスは考えないことにします)、
これらに忠実な表記を採用すれば、自動的に日本語読みと同じ語順の宣言になります。
この過程をよく見ると、単に日本語読みの省略記法を作っているだけの話ですよね。
>>229が良い例ですが、宣言されたポインタを理解するとき、あるいは相手に説明するとき、
やっぱり"日本語読み"に直して理解するわけです。それは「>>232-234の表記法に直して理解する」
と言っているのと同じことです。なぜなら、232-234は日本語読みの省略表記だからです。
僕は232-234を強要するつもりはありません。
でも、232-234を無闇に否定する人は、日本語を否定してるのと同じことですよ。
268:デフォルトの名無しさん
10/07/08 08:54:37
>それだけです。
だから無意味だっつってんの
>少なくとも>>235みたいな人の役には立ちますよね。
立たない。
結局Cの宣言は読めないまま。
269:デフォルトの名無しさん
10/07/08 09:18:04
日本語でしか通用しない新規ルールイラネ。世界中で通用するCをマスターした方がいい。終了。
270:デフォルトの名無しさん
10/07/08 09:27:21
Cの文法はよくわからない。たぶん頭のよくない人が作ったんだろう。
よし頭のいい俺がもっといいルールを作ってやろう。
↓
出来た!これで皆便利になるし、俺に感心するはずだ。
たぶんこういう思考回路なんだろうな・・・。
まさしく中二病ってやつだな。
見てるこっちが恥ずかしくなるよ。
271:デフォルトの名無しさん
10/07/08 09:30:46
他人のオナニーを見たいわけがない罠
272:デフォルトの名無しさん
10/07/08 09:42:31
俺は目に入るコード量が減るからtypedef使うけど、最初からC言語がその文法だったらと思うな
日本語読みというより、型の遠い順だね(Cもそうなんだけど見ため的に)
273:デフォルトの名無しさん
10/07/08 10:03:28
>>232が得意げに自分ルールを披露したら賞賛されるどころか袋叩きにあっててワロタ
274:デフォルトの名無しさん
10/07/08 10:41:00
Cの時代は終わってる
275:デフォルトの名無しさん
10/07/08 11:12:03
すきにすりゃいいんだけどな
typedefしようがスマートポインタ使おうが
他人が使う事になれば苦労するって話
276:デフォルトの名無しさん
10/07/08 11:40:44
確かにコーディング規約も命名規則もないところで、typedefは使ってほしくはないな
277:デフォルトの名無しさん
10/07/08 11:57:47
個人的はtypedefを探すのにかかる時間次第かな。
2、3分くらいで見つかるようならtypedefして貰う方が読みやすい。
278:デフォルトの名無しさん
10/07/08 12:44:57
> typedefを探す
意味が分かんないんだけどどういうこと?
279:デフォルトの名無しさん
10/07/08 13:05:09
>>278
日本人ではないな?
だからどう、ということもないが
280:デフォルトの名無しさん
10/07/08 16:04:04
>>278
ある定義名について、それをtypedefで宣言している文を探す、ということ
281:デフォルトの名無しさん
10/07/08 16:05:08
>>279
日本人だよ
IDEなら言うまでもなく
非IDEでもタグファイルを作っておけば一瞬
最悪Grepしてもそんなに時間が掛かるものじゃない
探すという感覚が分からないんだよね
強いて言えば
coする程ではないが少し気になるものを
Webブラウザ上で眺めてるときかな?
と思ったりもしたけどそれはtypedefに限った話ではないしなぁ
282:デフォルトの名無しさん
10/07/08 21:17:44
元の定義読んで意図理解する必要があるのは変わらないからな
メモリ確保がごっそり独自になってる事なんて
よくある事なんだけど
仕様読んで実装全部書き直して
移植したりとかめんどくせーから嫌いです
283: ◆QZaw55cn4c
10/07/08 23:06:14
>>265
Cの文法のどの点が変なのかわからない。多分毒されすぎたんですね。
さしつかえなければ教えてください。
284:デフォルトの名無しさん
10/07/08 23:33:48
>>268
>だから無意味だっつってんの
まあ、ポインタ自体の話をしたい人には無意味でしょうね。
>結局Cの宣言は読めないまま。
ああ、そういう意味なら確かに。あなたは正しい。でも、>>235の
>あれ何とかならんかったんか
この部分への1つの回答には なってますよね。
>>269
新規ルールではなく、既存のルールです。あなたは既に
このルールを使ってます。なぜなら、232-235は日本語読みの
単なる簡略表記に過ぎないからです。
あなたが日本語の語順で関数ポインタなり何なりを捉えたとき、
それは232-235を使っているのと全く同じことです。
あと、英語読みとも親和性は高いですよ。
日本語読みの語順を逆順にしたのが英語読みですから。
285:デフォルトの名無しさん
10/07/08 23:37:28
アンカミス...
× 232-235
○ 232-234
>>270
賞賛される必要はありませんが、無闇に否定されるのは
おかしいです。なぜなら、232-234は日本語読みの単なる
簡略表記だからです。これを否定するのは>>229の説明方法を
否定するのと同じことですよ。
>>271
オナニーと言えるほど独りよがりな文法では無いでしょう。
intがN項の配列 a;
戻り値int,引数charの関数へのポインタ pfunc;
このような日本語のベタ書きと全く同じ表現をしているのが232-234です。
こういう表現形式を無闇に否定するのは、>>229の説明方法を否定するのと
同じことですよ。
286:デフォルトの名無しさん
10/07/08 23:50:46
>>283
関数ポインタ周辺の宣言における表記の語順が、
自然言語の語順から かけ離れているところ。
日本語読みの語順と全然違うし、英語読みの語順とも全然違う。
287:デフォルトの名無しさん
10/07/09 01:36:19
語順はどうでもいいけど
その定義の通るコンパイラ(またはプリコンパイラ)はもう実装出来てんの?
288:デフォルトの名無しさん
10/07/09 06:35:18
反論かと思ったら同じこと繰り返すだけのキチガイか
289:デフォルトの名無しさん
10/07/09 07:19:55
使用と宣言を一致させる、ってのはスルーなの?
290:デフォルトの名無しさん
10/07/09 10:31:20
ポインタがわからなくてこのスレ開いたが
もう嫌だ何これorz
291:デフォルトの名無しさん
10/07/09 12:50:36
このスレって何について話すスレなの?
292:デフォルトの名無しさん
10/07/09 13:44:36
>>281
IDEの機能や、grepを使うのは充分「探す」だろう
293:デフォルトの名無しさん
10/07/09 16:05:01
>>290
たとえば、どんな所がわからないの?
引っかかってるところを(それがどうして分からないのか)知る為に、色々教えてくれると思うが
294:デフォルトの名無しさん
10/07/09 18:23:46
>>149はいい線いってるね
最終的に型につくならよかった
295:デフォルトの名無しさん
10/07/09 18:39:53
>>292
後者はそうだね、自業自得だけど。
でも前者は違うな。
>>292
↑というアンカーに対し292のレスを探すとは言わないでしょ?
カーソル合わせりゃToolTipが表示される(IDE) ← 探すとは言わない
クリックすればリンクに飛ぶ(tag) ← 探すとは言わない
ページ内を検索する(Grep) ← 探すとは言うかもしれないけど自業自得
296: ◆QZaw55cn4c
10/07/09 19:31:47
>>286
演算子の結合順位が頭に入っていないと、たしかに読みづらいかもしれません。
297:デフォルトの名無しさん
10/07/09 19:33:05
覚えられなくてカッコを多用
298:デフォルトの名無しさん
10/07/09 19:50:24
>>294
int* p;は型についてるように見えるけど
int *p;はそう見えない
後者はどう解釈したらいいん?
299:デフォルトの名無しさん
10/07/09 19:55:23
型は宣言から識別子抜いたものだって教わりませんでした?
300:デフォルトの名無しさん
10/07/09 20:08:56
>>299
識別子抜いても意味合いは同じじゃない?
(int*)
int (*)
後者は型についてるように見えない
301:デフォルトの名無しさん
10/07/09 20:25:53
「括弧内の宣言子は、括弧なしの宣言子と同一となるが、
複雑な宣言子の結合が括弧によって変更されることがある。」
演算子の結合順序を変えるような括弧じゃない限り
論じるのは無駄。何を言いたいのかさっぱり不明。
302:デフォルトの名無しさん
10/07/09 20:47:48
>>301
記号操作の話ならそれでいいけど、俺は意味論的な話をしてるんだが
どうレスしたらいいものか
303:デフォルトの名無しさん
10/07/09 20:56:16
セマンティクスとも違う別の何かだろ。
ポインタの話ですらない。
304:デフォルトの名無しさん
10/07/09 21:01:15
括弧の位置なら単なる文法論の話じゃないのかな。
意味論なんて言うなら、ますます括弧なんて重要じゃない。
要するにどうでもいいような文字の置き方に
さも意味があるような話を意味論って言ってるんじゃないのかね。
305:デフォルトの名無しさん
10/07/09 21:24:51
ポインタより重大なのが、
#define N 1
という使用方法。
N かまわず置き換える。
306:デフォルトの名無しさん
10/07/09 21:26:55
定数なら定数でいいし、文にまで使うのは分かりにくくなると思うけどな
307:デフォルトの名無しさん
10/07/09 21:30:21
>>305へのレスですか?
定数Nを #defineするのは、辞めた方が良いよ。
関数名や、変数名で大文字のNが含まれたら全替えする。
これにより、マクロを含めて#define全面禁止をモットーにした。
308:デフォルトの名無しさん
10/07/09 21:32:16
本当の意味の定数でいったら、
constは変更不可能なだけで定数じゃない。
#defineが定数にあたるけど、別にどうだっていいよねー。
309:デフォルトの名無しさん
10/07/09 21:43:55
>>302
意味論てのが何か分からんけど、識別子を評価する方法も
型で表現しようとしてるから、*が右に寄るんじゃないか?
言葉遊びするなら、int *pは
intへのポインタな変数p、ではなく、
*pとして評価すると(実体があれば?)intの値が得られる識別子p、
という解釈。
関数や配列の宣言も全てそう。
規格の文面なんて後付けだしな。
今テキトーに考えた。
310:デフォルトの名無しさん
10/07/09 21:47:39
>>308
C言語乙
311:デフォルトの名無しさん
10/07/09 21:52:45
>>307
あなたの日本語は間違いではありませんが、内容は嘘ですね。
312:デフォルトの名無しさん
10/07/09 21:53:45
>>298
型を明示する陽表式ではなく、
「この条件を満たす何らかの型」という
陰伏式で解釈したらどうでしょう。
>int *p;はそう見えない
・識別子はpである。
・pの型は「演算子*による戻り値 *(p) の型がint型であるような、何らかの型」である。…(1)
この解釈だと、*は直接的には型に付きません。
ただし、(1)を満たす型はまさに(int*)ですから、
結果的には(int*)型の変数を宣言していることになり、
*は間接的には型についてると言えます。
313:デフォルトの名無しさん
10/07/09 21:56:17
>>309が既に同じこと言ってましたorz
314:デフォルトの名無しさん
10/07/09 22:17:50
そんな話してたらまたあのキチガイが出てくるぞ
315:デフォルトの名無しさん
10/07/09 22:27:15
>>313
一緒にすんな
316:302
10/07/09 23:04:10
>>309,>>312
これだ!!!こんな解釈がほしかった
やっと腑に落ちたわ、ありがとう
意味論ってのはあれだ、すまんかった
言葉のアヤってことでw
317:デフォルトの名無しさん
10/07/09 23:38:07
>>298
int a,b; a*b a * b a* b a *bすべて同じであるように
int* c; int *c; ・・・も同じint * cになる
みんなするどいね
例)int *a,b;は結合規則により(一度*が右結合して、型になる)
(int ((*a),)b) → int (*a), b;→ int *aと(,)int b
int *a→ int *(a)→(a)を評価するとint *が返り値つまり型となる
318:デフォルトの名無しさん
10/07/10 01:04:04
昔のCではint *p;のみでint* p;はダメじゃなかったっけ?
319:デフォルトの名無しさん
10/07/10 01:28:20
>>128でも言われてるな
320:デフォルトの名無しさん
10/07/10 01:52:09
>>318
存じませんが、K&Rあたりでそう記述されてたからとかそのあたりでしょうか?
>>319
ありがとうございます、笑われただけで禁止はされていないみたいですね
wikiには方言もあったと書いてるので、これかもしれませんよ
まぁ、寝ます
321:名無しさん@そうだ選挙に行こう
10/07/10 16:06:31
ひさびさの2ちゃんなんだけどそろそろ前橋ポインタ本を越える文章って出てきた?
322:名無しさん@そうだ選挙に行こう
10/07/10 16:14:20
で、そろそろポインタでひっかかるポイント分かったのか?
323:名無しさん@そうだ選挙に行こう
10/07/10 17:03:51
・変数とメモリの関係がイメージ出来ない
・ポインタを絡めた宣言が理解出来ない(しづらい?)
今のところ出て来たポイントはこの辺?
324:名無しさん@そうだ選挙に行こう
10/07/10 17:22:57
>>323
よく挙げられる理由の典型例じゃん
これじゃ他のポインタスレと変わらんなあ…
325:名無しさん@そうだ選挙に行こう
10/07/10 17:56:25
>>322はポインタとポイントを掛けたかっただけでは
326:名無しさん@そうだ選挙に行こう
10/07/10 18:24:49
>>
↑
これがポインタ
327:名無しさん@そうだ選挙に行こう
10/07/10 19:01:40
C言語のポインタがわかりやすい言語ってある?
328:名無しさん@そうだ選挙に行こう
10/07/10 19:06:38
アセンブラへの展開見れば一目瞭然。
329:名無しさん@そうだ選挙に行こう
10/07/10 21:36:43
文法はそう記述したら、そうなるわけだから、詰まる要素ではないだろう
ポインタを知る為にメモリの状態とアドレスをPrintfとか使ってチマチマ
やってた時、頭が沸騰しそうだったな
覚える為に、ここら辺の関係ない所で時間がかかり過ぎるのが問題じゃないかな
330:名無しさん@そうだ選挙に行こう
10/07/10 21:57:43
俺はそんなところで時間かから無かったよ
331:名無しさん@そうだ選挙に行こう
10/07/10 22:05:30
文法を理解しているというのなら、
ポインタの中身なんて理解する必要なっしんぐ。
C言語のプロトコルに従って書いてりゃどこでも動くコードのいっちょ上がり。
と言いたいところだが、そうもうまくいかないと思う。
332:名無しさん@そうだ選挙に行こう
10/07/10 22:15:05
TOEIC満点のやつは英語で嘘をつかない、なんて保証があると思う?
333:名無しさん@そうだ選挙に行こう
10/07/10 22:21:55
誰か翻訳頼む
334:名無しさん@そうだ選挙に行こう
10/07/10 23:32:31
指を見るな
月を見ろ
335:名無しさん@そうだ選挙に行こう
10/07/11 01:52:01
文字列処理や勉強の時のscanf()で何度も不正な処理起こしたC言語初心者時代
普通の高級言語なら実行時エラー、エラーメッセージで分かる内容のところを
いきなりOSからエラー返されたらビビるって
336:名無しさん@そうだ選挙に行こう
10/07/11 02:21:19
いや
エラーでりゃましなほうさ
337:名無しさん@そうだ選挙に行こう
10/07/11 10:28:09
ポインタ挫折歴3年の俺が来ましたよっと
char *s = "test";
なんでこういうことが出来るのかいまだに理解できない
char s[] = "test";
とは違うの?
338:名無しさん@そうだ選挙に行こう
10/07/11 10:41:38
>>337
前者と後者は本質的に違う。
前者は読み取り専用領域に置かれた文字列へのポインタを保持している。
後者は【文字の配列】そのもの。
まず、C言語のFAQでも見ようか。
URLリンク(www.kouno.jp)
URLリンク(www.kouno.jp)
339:名無しさん@そうだ選挙に行こう
10/07/11 10:54:02
どのレベルで分からんのかが分からんなぁ。
ちょっと嘘を交えて言うと
"test"は、プログラム開始時にOSが用意してくれる5バイトの
書き換え不可な配列として解釈される。
char *s = "test"; は、アドレスを指す4バイト変数sを作って
OSが用意した"test"の先頭のアドレスを代入する。
char s[] = "test";は、OSが用意した"test"と同じサイズの(5バイト)
配列を作って、"test"の内容をコピーする。
違いは大体こんなもん。
どこが嘘かは、興味があるならまた別途。
何故そう書けるのか、と言われると、Cが文法として、
そういう機能を持ってるから、としかよう言わんなぁ。
340:名無しさん@そうだ選挙に行こう
10/07/11 11:12:20
int main(int ac, char **av)
{
char *a = "test";
char *b = "test";
char c[] = "test";
char d[] = "test";
printf("%d", a == b);
printf("%d", c == d);
printf("%d", a == c);
return 0;
}
341:名無しさん@そうだ選挙に行こう
10/07/11 11:37:13
俺の彼女をボインだ!って言われるようにするにはどうすればいいですか?
342:名無しさん@そうだ選挙に行こう
10/07/11 12:11:05
>>337
前者
_s: dc.l __lbl
__lbl: dc.b 'test', 0
後者
_s: dc.b 'test', 0
343:名無しさん@そうだ選挙に行こう
10/07/11 12:11:56
引っかかりそうな所には近づかない・逃げるという方法もあるな。
scanfとか初期化式とかは、ポインタと少しは関係あるが、
関係ない部分で引っかかってる感じもする。
あまり関係ない所に全力でぶつかったり、教える側も全力で教えようとしていたら
それは学習コストは高くつくに決まっている。
自ら望んで全力で引っかかるのは構わないが、
「なぜ引っかかることを望んだのか」を他人に問い詰めるのは迷惑だ。
344:名無しさん@そうだ選挙に行こう
10/07/11 12:26:25
>>341
まず童貞を捨てる。
345:名無しさん@そうだ選挙に行こう
10/07/11 12:55:12
char *s="test";
sprintf(s,"Hello world");
正常に動くようですがこのまま使って大丈夫でしょうか?
346:名無しさん@そうだ選挙に行こう
10/07/11 12:57:49
はいはい、ネタは自分の頭の中でやってくれ
それが嫌なら窓を捨ててペンギン村にようこそ
347:名無しさん@そうだ選挙に行こう
10/07/11 13:00:39
>>345
だめです。
というより
char *s = "test";
という使い方はほとんどしないから忘れてもいいかと。
348:名無しさん@そうだ選挙に行こう
10/07/11 13:07:40
const char *s = "fuck me please!!"
ならいいよ
349:名無しさん@そうだ選挙に行こう
10/07/11 13:39:11
そこはfackだろ
350:名無しさん@そうだ選挙に行こう
10/07/11 14:12:44
>>345
char *s="test";
*s="Hello world";
でいいじゃん
351:名無しさん@そうだ選挙に行こう
10/07/11 15:00:55
s="Hello world";
352:名無しさん@そうだ選挙に行こう
10/07/11 15:11:27
配列は関数に渡すとポインタに変換される
ポインタはprintfされるとアドレスに変換される
暗黙に二度の変換を受けるという理不尽な仕様
353:名無しさん@そうだ選挙に行こう
10/07/11 15:24:41
おいおい。
全て間違ってる。
354:名無しさん@そうだ選挙に行こう
10/07/11 16:13:29
#include <stdio.h>
int main(int ac, char **av)
{
char *a = "test";
char *b = "test";
char c[] = "test";
char d[] = "test";
printf("%d\n", a == b);
printf("%d\n", c == d);
printf("%d\n", a == c);
c[0] = 'C';
printf("%s\n", c);
try{
a[0] = 'A';
printf("%s\n", a);
}catch(...){
printf("catch\n");
}
return 0;
}
どうしたら Segmentation fault を出さないように出来ますか?
355:名無しさん@そうだ選挙に行こう
10/07/11 16:16:22
cでtrycatchとかありえない
356:名無しさん@そうだ選挙に行こう
10/07/11 16:19:02
ポインタは変数のある場所を指している(キリッ)って説明がわかりにくい
「指してる」ってなんだ?と思ってた
はじめにscanfや関数の引数としての使い方から説明するから単体での理解がしにくい
アドレスを格納する変数ならそう言って欲しい。分かりやすくしようとしてわかりにくくなってるよたぶん
あと変数宣言の説明を軽くスルーしたり、ポインタをポインタ型とかint*型とか言わないのも問題な気がする
ポインタだけ特別枠の別物みたいにみえる
プログラミング習いたての人との共通認識を探ろうとしないのも分かりにくさに拍車をかけてる
難しいんだよー、だから分からなくても仕方ないんだよー、俺のせいじゃないよーってか
分からせる気ないだろうと
357:名無しさん@そうだ選挙に行こう
10/07/11 16:41:32
英語で言えば
ある場所を指している=ポインタ
だからな
ポインタは変数のポインタ(キリッ)
じゃ判らん罠
358:名無しさん@そうだ選挙に行こう
10/07/11 16:50:14
再帰的定義だよ
359:名無しさん@そうだ選挙に行こう
10/07/11 16:51:40
URLリンク(ja.wikipedia.org)(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
ポインタ (pointer)とは、あるオブジェクトがなんらかの論理的位置情報でアクセスできるとき、
その位置を表現する変数の事をいう。有名な例としてはC/C++でのメモリアドレスを表すポインタが挙げられる。
なるほどなるほど~
360:359
10/07/11 17:00:11
>>359
変数って書いてあるけど、値のことだよね。
ポインタとは、オブジェクト(≒変数)の位置を表現する値を指す。
C/C++ではメモリアドレスを使用するのが一般的。
ポインタに対して演算を行うことにより、オブジェクトを取得したり、
またオブジェクトに隣接する位置のオブジェクトのポインタを
取得することができる。
ああ、こう書いちゃうと分からないんだよなあ。
やっぱ箱のポンチ絵無しには説明は無理だわ。
で、更に変数宣言がどういうものなのか書こうとすると
rationaleとか持ってこないと荷が重い。
361:名無しさん@そうだ選挙に行こう
10/07/11 17:02:11
だからアセンブラに落とせば一発だっつーのに
362:名無しさん@そうだ選挙に行こう
10/07/11 17:03:07
アセンブラにCみたいな複合型ねーだろ。
363:名無しさん@そうだ選挙に行こう
10/07/11 17:03:12
ワロタw
結構いるよね、ほのめかしはするけど実は答え知らない自称上級者
364:名無しさん@そうだ選挙に行こう
10/07/11 17:04:01
>>362
ある夜
365:名無しさん@そうだ選挙に行こう
10/07/11 17:05:31
>>364
値の出し入れ以外に
まともな文明の利器があったなんて知りませんでした。
もちろん人が解釈するものじゃないよね?
きちんと文法なんだよね?
366:名無しさん@そうだ選挙に行こう
10/07/11 18:35:29
ポインタはクイックソートをする為だけにある。
それ以外の用途では不要。
367:名無しさん@そうだ選挙に行こう
10/07/11 18:38:49
>>366
おまえ楽な仕事なんだな
368:名無しさん@そうだ選挙に行こう
10/07/11 18:43:51
>>360
ポインタと言った場合、ポインタ型のことか、
ポインタ型の変数のこと。
値はアドレス
369:名無しさん@そうだ選挙に行こう
10/07/11 19:32:13
クラスメンバへのポインタで質問です
class Inner{
pubilc:
void hogehoge();
int fugafuga;
};
class Base{
public:
Inner *in;
void hoge();
int fuga;
};
Base b;としたとき
b.hoge は &Base::hoge
b.fuga は &Base::fuga
b.in は &Base::in
でいけると思うのですが
b.in->hogehoge
b.in->fugafuga
相当のアドレスを得るにはどうしたらいいのでしょうか?
370:名無しさん@そうだ選挙に行こう
10/07/11 22:22:12
C++ちゃんと知らんけど
「いけると思うのですが」の時点で
いけてないことないか?
371:デフォルトの名無しさん
10/07/11 23:57:30
普通に&Inner::hogehogeじゃダメなの?
372:デフォルトの名無しさん
10/07/12 00:13:22
でいけると思うのですが
373:デフォルトの名無しさん
10/07/17 08:34:26
ぬるぽ
374:デフォルトの名無しさん
10/07/17 11:21:28
ポインタはすんなり理解できたけど「逆参照」だけはずっと意味不明だった。
なんだよこの訳語は。
375:デフォルトの名無しさん
10/07/17 11:57:59
デリファレンスでいいだろ
376:デフォルトの名無しさん
10/07/17 12:28:15
俺なら訪問と訳して全国のポインタ脱落組を3000人くらい救っていたな。
377:デフォルトの名無しさん
10/07/17 13:30:16
入門書の間違いなんて、たまたまそれに嵌って痛い目にあったりでもしない限り、
いちいち覚えちゃねえよ。
複数言語やってりゃ、記述が間違っていても何となく回避してるし。
子どもの時に乗った三輪車の善し悪しなんぞ誰もわからんのと同じ。
ぐだぐだ言うのは、三輪車をとっかえひっかえしている池沼と、書いた著者くらいのもん。
378:デフォルトの名無しさん
10/07/17 14:44:43
それはそうかも
379:デフォルトの名無しさん
10/07/17 14:57:17
>>375
デリとな
380:デフォルトの名無しさん
10/07/17 18:26:10
>>377
複数言語やってても、そこにポインタ扱う言語が無かったらやっぱ引っかかるよ
381:デフォルトの名無しさん
10/07/17 21:35:13
>>373
Javaじゃないからガッしてくれないよ
382:デフォルトの名無しさん
10/07/17 22:55:15
スマポで引っかかりました。
詳細は以下から。
class Dog : public IAnimal
というクラスがあって、これをスマポでインスタンスを生成すると
void fanc(IAnimal animal)
に入れられなくなります。
どう書けばいいんですか?
383:デフォルトの名無しさん
10/07/17 22:57:19
>>380
間接参照の概念さえあれば大体何がやりたいのかは分かる
384:デフォルトの名無しさん
10/07/17 23:00:17
>>382
そのスマートポインタをデリファレンスすれば委員で内科医?
言語が判らんから具体的には答えられないが。
385:デフォルトの名無しさん
10/07/17 23:12:08
>>382
アセンブラやればわかるようになる
386:デフォルトの名無しさん
10/07/17 23:12:10
C++(VC10)です
↓こういうふうに書いたら駄目なんですか?
何で入らないのかわかりません
std::shared_ptr<IAnimal> dog_ptr(new Dog());
387:デフォルトの名無しさん
10/07/17 23:16:15
>>386
ポインタを実態を必要とする関数に渡したいなら、>384の言うように逆参照すればいい。
もしかして、単項*演算子も知らないのか?
388:デフォルトの名無しさん
10/07/17 23:18:59
>>382
auto_ptr<Dog> p(new Dog());
func(*p);
389:デフォルトの名無しさん
10/07/17 23:54:24
うーん何言ってるかよくわからないのはポインタを避けて通ってるからなのですかね
とりあえず.get()って付けたら入りました
func(dog_ptr.get());
全く意味わからないですが急場しのぎって感じで満足してます
やっぱもってるなってことで
390:デフォルトの名無しさん
10/07/18 00:01:10
その程度で満足できるんなら勝ちでいいよ
391:デフォルトの名無しさん
10/07/18 00:37:28
>>389
メモリの絵を描いて理解するんだ。
392:デフォルトの名無しさん
10/07/18 00:54:50
たとえばK&Rは第5章がポインタで第6章が構造体だが
ポインタは避けるが構造体 (クラス) は避けないって感覚は異常だよ
ふつうに考えるとポインタよりもクラスのほうが難しいはずだよ
なぜか知らないがクラスが難しいと言うのは恥ずかしい
ポインタが難しいと言うのは恥ずかしくないという空気に支配されている気がする
393:デフォルトの名無しさん
10/07/18 02:43:01
知らんがな
394:デフォルトの名無しさん
10/07/18 03:00:05
何かあるとK&Rという空気に支配されている気がする
395:デフォルトの名無しさん
10/07/18 03:11:20
3連休だしプログラミングの勉強しようぜ
スレリンク(news板)
396:デフォルトの名無しさん
10/07/18 07:46:40
>>392
ポインタのほうが構造体よりずっと難しい
ポインタは存在しないオブジェクトを指す可能性があるし、表記が複雑になる
構造体のほうが難しいと勘違いするのはポインタを理解していないからだ
397:デフォルトの名無しさん
10/07/18 11:21:38
逆をいえば、存在しないオブジェクトを指さなくて構文が複雑にならない
ようなポインタなら問題ないんだよな
JavaやPythonの間接参照に引っかかるようなヤツはそうそうおるまい
398:289
10/07/18 14:02:41
ポインタ難し・・・・^^;
399:デフォルトの名無しさん
10/07/18 15:27:09
ポインタや構造体のどこが難しいのか理解できない。
Win32APIのほうがよっぽどマンドクセ。
400:デフォルトの名無しさん
10/07/18 15:32:39
%pに細工して
printf("%p", p)の出力を
〒100-0014 東京都千代田区永田町1丁目7-1
とかにすればイメージ沸きやすいと思う。
アドレスと値を同列に扱えてしまうのがコンピュータの強みでもあるが
混乱の基なんだよ。
401:デフォルトの名無しさん
10/07/18 16:42:46
哲学的な話になりそうだなw
402:デフォルトの名無しさん
10/07/18 21:56:05
もう黙ってアセンブラから入るしかないのでは?
というか、我々の頃は、ちょっと言語がわかるようになったら、自然とそうなっていたような気がするのですがね。
403:デフォルトの名無しさん
10/07/18 22:05:16
ポインタは間接参照を表現するものとしては
無駄の多い構文になってるのがアレなだけで
こういうアプローチ以外は不可能ってほど難しいものじゃないだろ
アセンブリなんてしなくてもよろしい
404:デフォルトの名無しさん
10/07/18 22:40:32
そんなものやって役に立つの?