2012年09月プログラム21: なぜポインタで引っかかる人が多いのか (796) TOP カテ一覧 スレ一覧 2ch元 削除依頼
文字コード総合スレ part7 (921)
MVVMについて語ろう (384)
【.cmd】 バッチファイルスクリプト %9 【.bat】 (300)
Rubyについて(アンチ専用) Part004 (747)
雑談スレ 4 (777)
Visual Studio 2012 Part4 (348)

なぜポインタで引っかかる人が多いのか


1 :2010/06/30 〜 最終レス :2012/11/02
なぜポインタで引っかかる人が多いのか
引っかかる人は何に困惑しているのか

2 :
ポインタは概念のようなものなので、知ってすぐ使える標準関数やSTL等と違い「何に使えるか」が不明瞭だから

3 :
*だから

4 :
なぜ雑談スレや質問スレに書き込まずにスレを立ててしまうのか。
クソスレ立てる人はバカなのか死ぬのかpンジーなのか。

5 :
物理メモリにデータをおいてるってイメージがないとね

6 :
ポインタって訳すと「指し示す」だろ。
それを*をつかって値を書き換えたらポインタじゃないじゃん。
参照するまでは許す!でもいじったらポインタじゃない!

7 :
数値扱いにもなるのが理由じゃないかな。
それ故に今扱ってるのがデータなのか、アドレスなのかワケが分からなくなる。
アドレス書くべきところにデータを書いてしまったり、逆をしたりしたときに
予測不能な挙動を引き出してしまい、何が起きたのか分からなくなる。
ポインタ型と数値型が明確に区別されて、キャストしないと数値にできず
型エラー出すなら引っかかりにくいと思う。

8 :
ポインタはね、メモリのアドレスでしょ。
そんなことは言われればだれだって理解できるんです。
要するに計算用紙の座標がポインタですから。
でも複合型の文法を出した途端、頭の中で処理できなくなるんです。
加えて、配列がポインタとかウソの説明をうけてごらんなさい。
ほら、分からなくなった!
そうこうしているうちに関数ポインタの説明まで行くでしょ、
そこまで行ったらなーんとなく概念では分かるけど、
文法は全くわからんちーん。
アドレスだから数値と一緒で計算できるとか勘違いするようになる。
配列のポインタが配列の先頭要素指してるから
キャストエラーを無視してもいいとか頭の中が沸いてるんじゃないかと
思う発送をしだすようになる。

9 :
配列がポインタ、は嘘なんだが
言語仕様からして割と混同されてるだろ
あれでは分からなくなるのも無理はないかと

10 :
でも別にそんなのどうだってよくね?
物理メモリのどっかにあるその領域の先頭を指してるもん的な
意味でしか使ってないぞ>配列
あくまで俺はって話しだけど
いちいち配列の先頭とポインタとでごっちゃになっちゃうような使い方してるのって
組んでるプログラムも怪しくねーか?
俺みたいに物理メモリのどっかを指してるモノってとらえてると
配列もポインタって言っちゃう人がいるのかもね
ただ、その場合連続してるもんとしてないもんと脳みそに入ってないとダメだけど

11 :
配列式aをa[0]に自動変換できる一部の場合(要するにsizeofとか以外)、
a[2]=2[a]が*(a+2)と等しいことを取って配列と等しいことを指して、
配列とポインタが等しいなんて言う人がいるんだよなあ。
まあもっともポインタが引っかかる人はそれ以前だと思うが。

12 :
では配列とポインタはどこが違うのだろうか。
正確な答えを自分は知らない。

13 :
>>12
int a[10];
int *b;
この時、aは定数、bは変数
a[0]はアドレスa+0を参照する
*bは変数bが保持する値をアドレスとしてメモリを参照する
printf等でaとbを参照すると、どちらからもアドレスを得られるので混乱の元となる

14 :
等しいものとして扱うとどんなバグが発生するのか例を出して

15 :
領域が連続しているかどうかぐらいの違いしか見えないな
でもポインタのアドレスずらして計算なんてぶっちゃけいまやらないからまったく害がないなw

16 :
ここはポインタを理解できない人の原因を探るスレッドだろ

17 :
使う→間違える→考えるの繰り返し
わからない人はどれもやっていない

18 :
アセンブラもやってようやく理解といった感じ

19 :
プログラムのお勉強のいいところは
やる環境さえあれば、身についてしまうことだ。

20 :
int a[10];
int *b=a;
で、sizeof(a)=40, sizeof(b)=8;

21 :
>>18
俺もそうだったな。学生時代にBASIC→C言語やった時には
全く理由の解らない現象に悩んだもんだ。
メモリの状態によっては期待通りの結果が出たり出なかったりするからまたタチが悪い…

22 :
勉強に使った本が悪いんじゃないかな
[C言語ポインタ完全制覇」とか使ってみて理解できないなら別の要因だろうけど
それと自分で理解を深めたい時、どういった確認(プログラム)すればいいのかわからない

23 :
>>20みて思った
俺いまだ32bitのアプリ作ってるわ

24 :
64bitは甘え

25 :
・アドレス値の変更可否
・sizeofの値
違いはこれくらいかな。

26 :
アセンブラやってからだと全く困らないんだけどねー。

27 :
char *name[]とか見たらウンザリする。
これってname[0]、name[1]などはアドレスを意味するんですよね?

28 :
>>27
そうだっけ?

29 :
>>2
メモリアドレスという、非常に具体的なものなのだが。

30 :
java出身者はこの辺まるでダメだね
なんでこんな糞を量産してるの?ってぐらいダメだね

31 :
珍班AIは糞スレ

32 :
javaにポインタはないと言ってる香具師は
ぬるぽしたことがないんだろうか

33 :
>>32
本当はjavaでも理解してなきゃならないよな
でもさっぱりわかってねーのがほとんどなの

34 :
見て見ぬふり出来るということ

35 :
Z80とC言語を同時期に教えれば、ポインタではまず引っ掛からない
高専電気科は同時期に教えてた

36 :
>>32
Java, Cどちらもできるけど、「Javaにはポインタは無い」でいいよ。
ポインタが存在する、っていう説明でも別にいいけど。
あるのはあくまで参照。ポインタ演算は不可能。配列も大概アクセス遅いし。
Java出身者が引っかかるのはC++のオブジェクトが
Cで言うオブジェクトと近くて、要するに構造体で値型なところだろう。
>>25
あと&演算子も配列とポインタじゃ変わってくる。

37 :
うんと昔、はじめてCを勉強した頃を思い出してみると、
int i;
char buffer[100];
char *ptr = buffer;
scanf("%d", &i);
scanf("%s", ptr);
printf("%d", i);
printf("%s", ptr);
なにこれ?なんでscanfではポインタだけ&がなくて、printfでは両方&がないの?
って不思議に思ったな。
この辺でつまづくんじゃね。って一番最初だが。

38 :
>>35
おれ6809だったけど、ポインタでは引っかからなかった

39 :
まあ、でも別に半年もすれば大抵の人間が理解しちゃうし
2〜3年たっても理解できない奴なんていないし
大した問題じゃないんだけどなw

40 :
理解できない奴は2年も経たずに離脱するからな。

41 :
理解出来ないものに2年も係わるなよ

42 :
だから、「2年も経たずに」って書いてあるじゃん。

43 :
開発1年半ぐらいの奴が、関数の引数で**pとせずに*pとしてハマってて、
試しに簡略なメモリマップ書かせてみたら、書けなかった
という話を開発のリーダに聞いたんだが、ある意味すごいな

44 :
ポインタはわかるけど、引数がポインタのポインタとかになってるとわけわかめ

45 :
>>43
意味不明なことやらせんなよ
Windowsのはきついだろw

46 :
プログラマの人材募集に応募してきたプログラマの面接時の珍回答の例:
・「ダブルポインタは大丈夫ですけどトリプルポインタは自信がありません」
・「Cの入門書を3冊読んだから書いたことがなくても大丈夫」
・ランバラルの台詞を引用する

47 :
たまたま知る限り全ての処理系でポインタの実装がメモリアドレスを格納する変数なだけで
規格上はポインタがメモリアドレスである保証は無い

48 :
>>47
実際、Cインタプリタで、ポインタの実装が(実装言語の)配列インデックスである例はあるよ。

49 :
それって翻訳の処理が規格通りじゃないから
そもそも規格準拠の処理系じゃないんじゃね?
どういう解釈になるんだろ

50 :
>1
俺みたいなやつがいるから

51 :
PICなんかはコード領域とデータ領域が物理的に分離されてるからな

52 :
たしかに何に使えるのかのイメージが湧かない
極力使わないように回避出来ちゃいそうな気もした

53 :
>>52
アセンブラのインデックスアドレッシングを拡張したもんだから、
ハード寄りのプログラミングでは必須。
目次なしでも辞書を引けないことはないが時間かかり過ぎ、というのと似ている。

54 :
>>52
配列とインデックスを別々にすると変数や引数が多くなって気持ち悪い

55 :
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 :
>>55
そんなゴミみたいな例を出すからわからなくなる
大事なのはイメージ
物理メモリにおいてある領域にアクセスしようとしてる仕組みのイメージを
脳みそに描くことであって
そんな読みにくいコードが読めるかどうかはプログラムの能力とちっとも関係ない

57 :
>*ip + n = n;
なんだこりゃ

58 :
よくわかってない人間が、うっかりすると書いてしまうことがある。
だから、なぜ望んだ動作をしないのかわからず、引っかかるんだ。
読みやすい書き方を提示してやれば、ポインタで引っかかる人間は激減する。

59 :
>>55
後半はバグっていて話にならない(>>57のとおり)
前半は何が聞きたいのかわからない。ポインタに1を足してるという点では等価だが、
評価順序とかアセンブラコードとか言い出したら等価ではないが、質問のポイントが書いていないので
答えようがない。
結論:>>55はど素人。引っ込んでろ。

60 :
初期化してないものを演算するな

61 :
>>60
上のはメモリに対する演算ではなく、ポインタの値を変化させてるだけだから、
参照してない以上、何も問題はない。

62 :
>>59
いちいち罵倒せずにはいられんのか。情けない奴。

63 :
ポインタ自体は説明すれば分かってくれる。
問題は表記だな。 Cのポインタ関連の表記が悪い。

64 :
>>62
罵倒?
ど素人に引っ込んでろと書いたら罵倒なのか?
あんまり詳しくない方は書かないでもらえますか、とでも書けばいいのか?(ワラ

65 :
>>63
でも代替案も却って煩雑だったりするし、
今更ポインタの文法が変わるわけがないので、
慣れてちょうだいとしか言いようがない。
一番いいのはC言語使わないことだけどね。

66 :
>>64
バカを晒さないようお願い申し上げます。

67 :
>>66
*ip + n = n;
とか書いちゃうバカに言われてもwwww

68 :
>>67
それは私ではありません。横で見てて見苦しいので
重ねてバカを晒さないようお願い申し上げます。

69 :
>>64
罵倒だとも。それがわからない程度の人間というわけでもあるまい?

70 :
>>63
BASICにもVARPTRとかVARSEGとかあるけどCのポインタで躓く人には
分からないよ
アセンブラ学んだりしてメモリの存在意識してからじゃないと
スっと理解するのは難しいんだろうな
いきなりC言語から始めると値しか視界に入らないと思う

71 :
ジョエル・オン・ソフトウェア
http://bit.ly/8YScmk
">私のささやかな経験から言わせてもらうと、伝統的に大学のコンピュータ
サイエンスのカリキュラムで教えられているもので、多くの人がうまく理解
できないものが2つあった: ポインタと再帰だ。
"

72 :
短縮URLなんて全くクールじゃねえから。ソースはきちんと示せ

73 :
>>71
サンクス。クール内容だった。ポインタの理解が能力の見極めになるのはアセンブリ
言語を知らない人だけだろうな。知ってればレジスタ間接のようなものかですむ。逆に
アセンブリ言語知らなくてポインタを理解できる人は尊敬してしまう。どうやって理解に
至ったのかぜひ聞いてみたい。

74 :
俺ほとんどアセンブリ言語知らないけどポインタは理解できたぞ。
はっきりいってポインタはアセンブリ言語知ってるどうのじゃなくて、
どういう型システムがあってああいう文法になるのかっていうことが
ポイントなんだと思うよ。

75 :
再帰が理解できないって
高校数学で数列が理解できないレベルだろ
池沼認定

76 :
アセンブラなんて知らなくてもポインタは理解できるだろ
大事なのは、いまいじってるデータが物理メモリのどっかにおかれていて
そこにアクセスする仕組みがポインタだと理解することだ
一番面倒なところはプログラムの記述といくらにらめっこしてても理解できないっていうところかなぁ?
概念を理解しないといけないってのは義務教育ではあまりないからな
再帰はツリー構造のデータをいじらせれば一発で理解できるから
そんなに重要じゃないと思うけどね
はじめに教える人間がタコだと苦労しちゃうのかも・・・

77 :
>>74.,>>76
アセンブリ言語知らないと理解できないとは言っていない。知っていれば少しも
難しいものではないと言っている。ほとんど知らないとかではなくまったく知らない
人がどう理解していったのかを知りたい。そういう人を知らないので聞いてみたい。

78 :
>>77
データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
って必要にせまられたら一発で理解できたけど
画像とかさ
Aパートでロードした画像をBパートでもう一回使いたいんだけど?的な場面で

79 :
>>77
俺も同意。
BASICから初めて、その後C言語をやった時はさっぱりだったが
情報処理試験のためにCASLをやったらあっさり理解できるようになった。

80 :
配列とポインタの違いとかもアセンブラ知ってると理解が速いわな。
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 :
むむっ久しぶりなんで間違えた予感。
>lea _buffer, -(sp) #配列を引数に渡す場合
こんなアドレス形式はないな。
pea _buffer
だった。失礼。

82 :
テレビの中身を知らなくても、テレビを操作することはできる感じでポインタは使うことはできたけど
レジスタとメモリがどのように使われるのかを体感したら、理解が深まったのは覚えてる

83 :
おまえらレベルの低いところで理解できたつもりになっててワロスw

84 :
週末だというのに煽るしかやることがないなんて可哀想

85 :
賞賛からはほとんど得るものはない
人間は失敗から学んで成長する生き物

86 :
>>78
サンクス。
> データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
それだとポインタを使わなくても普通にできることでは?
> 画像とかさ
> Aパートでロードした画像をBパートでもう一回使いたいんだけど?的な場面で
言語を限らないとメモリーコピー、参照渡しなどポインタを使わない方法もある。
意地悪く書いたけどポインタを使えていると思う。上から目線ですまぬ。

87 :
> データはメモリにおいてあるんだからそこにアクセスする方法が必要になるだろ?
そこにアクセスする方法にアクセスする方法だろポインタっつーのは

88 :
どうやって理解するも何もそのままだろうが

89 :
理解出来ない奴が理解出来ない

90 :
番号付き箱にモデル化されたメモリでの説明で理解した。
アセンブリは知らん。

91 :
>>87
ポインタってそんなに複雑なものか?
>>80のコンパイル結果を見ればただの long 定数があるだけだ。
これがポインタの正体。つまりポインタは int や long と同じようにメモリ上にとられる
エリア。それをデータのアドレスを入れるために使う。
このプログラムはぬるぽになる。本来の意味でぬるぽが使えるのに感動!

92 :
>>86
>それだとポインタを使わなくても普通にできることでは?
できねーだろ
ハンドル使ってもポインタは回避できないと思う

93 :

知らないことは誰だってあるけど、いいやんとか言って違いも調べず思考停止するやつは向上心もう少し持とうぜ

94 :
と、アンカーの使い方もわからない雑魚がいっております

95 :
>>92
aというメモリー上のデータにアクセスしてbという変数に入れる。
b = a;
どこにポインタを使う必要がある?

96 :
>>95
元の話題とまったくつながりが見えないんだけど
なんの話してるの?w

97 :
>>95 は固定長データしか扱ったことないんだよ
そっとしておいてやれよ…

98 :
アセンブリ言語を覚えたら
複雑な関数ポインタをスラスラ書けるようになっちゃうの?

99 :
アドレスにまつわる文法はアセンブリの方がわかりやすいかもな

100 :
>>96
>>87でポインタを使わなければデータにアクセスできないと書いているからそりゃ無い
だろと書いている。揚げ足取りに近いのだけど。
Cを使って大量のデータを使いまわしするということならポインタについてはそうだろう。
だから後に言語を限らなければとわざわざ書いている。
>>98
スラスラ書けるようになるかどうかはわからないがCでなぜポインタを取り入れたか、
何を実現したかったは理解できるようになる。

101 :
>Cでなぜポインタを取り入れたか、
>何を実現したかったは理解できるようになる
それはポインタの理解とは無関係

102 :
>>101
俺も同意見。
アセンブリ言語を理解したとして、
結局あの文法が正確に分かるようになるのかというと別だと思う。
たとえば、 const int (* const (*)(void))(void) なんてのがあったとしよう。
これはアセンブリ言語を知っていたとしても
ポインタ自体に精通していなければ文法上の
意味を正確に掴みかねると思われる。
裏でどういう値が動いているかは分かると思うが。
俺自身アセンブリ言語に詳しくないから
そう思うだけなんだけど識者の人はどう考えているの?

103 :
ポインタで引っかかる人はアセンブリ言語を知っていれば簡単にわかる程度の
ところで引っかかっていると思うが。

104 :
アセンブリの感覚だと、とりあえずvoid*にして後でキャストすればいいと思えるし
constはただの自己満足だとわかる。
必要最小限のサブセットと、自己満足のための高度な内容を分けて考えるべき。

105 :
int x=100;
int y=50;
int *p=&y;
int z=x/*p;
どうしてCはポインタの記号に*を採用したのか*/

106 :
>>104
あくまで>>102は例だ。
本当に箱を並べたポンチ絵程度のものが分からないことを
アセンブリ言語を知っていれば分かるようになるのか、
それともC言語的な文法も踏まえたことをアセンブリ言語を
知っていれば分かるようになるのか、そういうことを言いたいだけ。
ポインタで引っかかるって言っても、
↑の2種類はいると思うけどね。

107 :
ポインタと文法は別
ポインタはわかるが文法がわからないという話は聞いたことがない
だから文法自体は悪くない
悪いのは、文法以前で引っかかってる人に文法を踏まえさせること

108 :
ポインタの配列とか
ポインタのポインタとか
配列のポインタとか
言ってる人は判ってるなと思うけど
ダブルポインタって言ってる香具師は
馬鹿じゃねーのと思う

109 :
int **x; ←*が2つついてダブルポインタ
ではないの?

110 :
そうだよ

111 :
ポインタ自体は難しいと感じないんだけど
ポインタの配列、ポインタのポインタ
使うプログラムって難しく感じる
配列が多次元になったり
連結させたりするとな

112 :
おまいら
int main(int argc, char *argv[]) を使う派?
それとも
int main(int argc, char **argv) を使う派?

113 :
後者。引数のブラケットほど虚しいものはない。

114 :
Javaですねわかります

115 :
なぜJavaで引っかかる人が少ないのか
typedef void *Object;
typedef Object *Vector;
int main(int argc, Vector argv)

116 :
*p=10000;

117 :
めんどくさいときは構造体に入れて関数に渡すわ

118 :
yes we can

119 :
int* p;
int *p;
int * p;
アスタリスクの使い方がポインタの理解を阻害する

120 :
>>100
>>>87でポインタを使わなければデータにアクセスできないと書いているからそりゃ無い
>だろと書いている。揚げ足取りに近いのだけど。
は?>>87俺じゃねぇし
まったく話が見えない

121 :
都合悪いから「俺じゃねぇ」ですね

122 :
>>120
すまない。アンカー間違えてた。 >>78だった。
>>100のレスが無くても>>78にたどり着くので流れは分かると思うが分からないのなら
おれには説明できない。

123 :
>>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 :
意味を考えなくても文法知識をいじり倒すだけで正解を導けるという
思い込みのはげしい人が多いのはなぜか。

125 :
規格書が全てですが何か
コンパイルできるかできないかはシンタックスが正しいか正しくないかであって実行して悪魔が出るかどうかはセマンティクスに違反しているかしていないか
ポインタなんて単なる数値だよ
*をいくつ使うかで表現できる階層が変わるだけ、C言語でオブジェクト指向っぽく連想配列でも実装すれば理解できるよ
ポインタは複合型であり、構造体や共用体、ポインタ、配列などの複合型の不完全型をシンプルに表現できる抽象データ型なだけであって難しいことなど無い

126 :
Cを始めるにあたって、規格から調べる人は控えめに言ってマレでしょう。
普通は入門書や、入門webサイトを見る。
初めて見るソース、ソースから受ける第一印象はとても大事。

127 :
難しいことを難しく表現することは誰にでも出来る。
難しいことをやさしく表現することは、能力が無いと出来ない。
能力が著しく足りないと、簡単なことを難しく表現してしまう。
という言葉を思い出した。

128 :
>>119
C++ が普及する前の C のときは事実上
FILE *f;
だけだったはずで
FILE * f; とか
FILE* f; とか
書きかたしていると笑われたもんだ
なぜか C++ で本来の
HOGE *h;
は影を潜め
HOGE* h;
という書き方が横行するようになった

129 :
 char* p,r;
でまた混乱。
なんで*が実質右ってことを忘れてんの?

130 :
>>128
>>123 みたいなアホのせいだな pgrw

131 :
>>123
> char *p;
>char型の*pを宣言してるように見えてた。
それで合ってる
何か変な本読んで混乱させられたんだな
かわいそうに

132 :
ここは"なぜポインタで引っかかる人が多いのか"を考えるスレ。
初心者が起こす勘違いを考えるスレ。

133 :
対象者が何につまずいているのかを想像する能力がなければ、
真の意味で教えることは難しい。
教える側に対象者のつまずきを理解する能力が無い場合、
対象者が理解できるかどうかは対象者の能力に依存する。

134 :
>>133
そうだな
簡単な話が理解出来ないのは
耳が悪いのかも知れないし
そもそも話を聞いてないのかも知れないし
頭が悪いのかも知れない

135 :
ポインタは正常に動くのにたまに変になることがある
int a[10];
a[10]=100;
みたいにやると、稀におかしくなる
コンストラクタとかifとかで複雑になってくると
よく見ると
int * p;
*p=100;
みたいなことを平然とやってたりする。
短いプログラムだとこんなことはしないだろうけど
複雑なプログラムだと初心者はわけがわからなくなる。
これが初心者にとって難しいんだろうな。

136 :
>>135
> a[10]=100;
正常に動くことがあるから、誤解の種になるよね。
必ず異常動作すれば気づくんだが。
char *p="abc";
*p='A';
これが正常に動く環境があって、
しばらく平気でそういう記述してた時期があった。

137 :
char* pの書き方だけは許さない。
こういう書き方をしている人物こそポインタで引っかかったままだと言える。

138 :
>>137
Microsoftのソフト開発者は全員そうだな。

139 :
結構、ポインタって文法の丸暗記で何とかなったりするからなぁ
int (*ptr)[10];
int a[100]; //mallocの代わり
ptr = (int (*)[10])a;
↑これを理解するのに結構時間かかった、特に関数の引数にしたときとか
アドバイスもらって、アセンブラ入門を勉強したら理解できるようになったんだよな
多分、実際のメモリ範囲確保とインデックスによるアドレス指定が理解の助けになったと思う

140 :
>>137
char *p[10];
char (*p)[10];
*がpに付くのなら上記は同じ意味になるだろう。
*が宣言に付くからこそ(*p)とすることで違う意味になる。
そういう意味からは
char* p;
のほうがしっくり来る。
俺は char *p; と書くけどね、char* p0,p1; のことがあるからね。

141 :
やたら記述にこだわってて内容理解してそうにない書き込みが多いところが恐怖

142 :
C#では
int* p,q,r;
ってやったらpもqもrも
CやC++でいう
int *p,*q,*r;
みたいに、全部が*つけたようになるな
アンセーフモードでしか実行できないけどね
Microsoftのポインタに対する意識が明確に現れてるな

143 :
>>126
第一印象に敏感な人は重症化しやすい、という意味では大事かもしれないが
本来は、印象なんてあやふやなものには鈍感なほうが良い
>>141
上のほうで、文法より意味を考えようぜっていう正論が出たから
逆の書き込みをすれば色々釣れるだろうと思ってるのかもしれん

144 :
char *p;
char (*p);
上記は同じものを指すが、結果として同じものをさすだけであって、
その意味合いは異なる。
前者は"char*型のpの宣言"であり、
後者は"pはポインタであって、そのポインタはcharを格納するアドレスのポインタ"。
それが理解できなければ、
char *p[10];
char (*p)[10];
は理解できない。

145 :
ホント記述弄り好きだな
こんなの覚えてもしょーがねーだろ

146 :
>>145
しょうがなく無いぞ
char *p[10];
char (*p)[10];
どっちの意味でも使うことあるから。
宣言の*が型に付くことを知っていれば、
前者のpが配列、後者のpがポインタだと理解しやすい。

147 :
int a[10][10];

148 :
それは別にポインタが難しいからじゃなくて、C言語が難しいから。
文法云々というか、プログラマの責任がデカい部分。

149 :
>>146
*(p[10]) か (*p)[10] かの違いだよ。前者の括弧は冗長だから書かないだけ。
*は前置単項演算子だから、被演算子は常に後ろに付く。型に付くことはない。

150 :
なにいってるんだ
int * p
の*は演算子ですらないぞ
*p=&x
みたいのでpの←の*は演算子だけど。

151 :
>149
知ったかは口はさむな

152 :
説明する能力がなければ、真実を伝えることが難しい例。
説明する能力があれば、真実でなくても実質問題の無い考え方を伝えることが出来る例。

153 :
mallocだのなんだの使うより
new int
のほうがわかりやすいよね

154 :
>>144
意味合いも型も全く同じ。
どちらも*演算子を適用するとcharになる。
>>146の意味合いは演算子の
結合が異なるから意味が異なって当然:
・char *p[10] =>char *(p[10]) => pに[]したあと*すればcharになる
・char (*p)[10] => pに*したあと[]すればcharになる
変数の記述と同じように演算子を適用したら、
最終的に一番左に書いたcharやらが取得できるのがポインタの文法。

155 :
ポインタで引っかかる人が多い、というより
Cのポインタで引っかかる人が多い、の方が正確だろうな。
C以外でポインタで引っかかる人の話はほとんど聞かない。
Cのポインタも、言語規格を読めば別に難しくないが、直感では理解しにくい。

156 :
とりあえず複数変数宣言を一行でやるのやめろや・・・
見づらくて仕方ない。

157 :
>>131
あってないだろ
*pが変数名ならポインタ使用するときpって書くなよ
*とpを分解するなよ
*とpがくっついて初めてIDなんだろ?って思った
あくまでpはchar*型の変数だろ
だから*演算子でポインタpの値参照できるんだし

158 :

char *p
*pはchar型であってるよ
*pは変数名じゃないよ
pが変数名だよ。

159 :
char * p
「char型」の「ポインタ(*)」の「変数p」と言った方がいいかな。

160 :
*pの型がcharとかは関係なくて
char *p;で宣言される変数はp
てだけだろ。
*pは宣言されてない。
配列とかでも同じだからなぁ。
特に分かりづらいと思ったことなかった。

161 :
幅WID, 高さHEIのint型の二次元配列arrayを動的に確保したい。
1)arrayの宣言文を書け。
2)arrayのメモリ確保文を警告レベル最大でも警告が出ないように書け。
3)arrayの要素アクセス方法、具体的にはarray中の横からw番目、縦にh番目の要素に0を代入する文を書け。

162 :
>>159
char*型の変数pでいいよ。
変数名取り除いたのが型の名前だし。
>>161
とりあえずC99禁止しようか。

163 :
>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 :
前の問題の答も出さずに勝手な問題積み上げてバカじゃないの

165 :
スレタイとは何の関係もない話題になった。

166 :
*********************************************p

167 :
*は2つあれば十分
3つ以上使うコードがあっても、void**とキャストを使うコードに変換できる

168 :
変換できることに意味はないな。適当にtypedefし直せば充分。

169 :
バイナリエディタで機械語書かせれば一発で理解できると思うんだ

170 :
誰も>>161には答えられない、と。

171 :
興味が無ければ答えない。当たり前だと思うが。

172 :
今まさに仕事でその手のコードを書いているからめんどくさいw
CPUとGPUの違いやsimdの演算効率の違いを考慮して、
AofSとSofAを切り替えたりxyzの順序を変えたりの詰め替えばっかりw

173 :
>>170
配列へのポインタでいいのか?

174 :
>>161
1) int *array;
2) array = (int*) malloc(sizeof(int) * WID * HEI);
3) array[h * WID + w] = 0;
Java使いでちゃんとしたCのコードなんか書いたことないんだけど、
これでいいのかな?このスレにいる詳しい人添削頼む。
あと>>163も同じように処理しちゃまずいのかな。

175 :
>>174
2次元配列と書いてるから、array[WID][HEI}の形にしないと駄目だろうね
>>161の条件だと↓でもよさそうだけど、>>163はひと手間かけないといけない
int (*array)[HEI] = (int (*)[HEI])malloc(sizeof(int) * WID * HEI);

176 :
一回でメモリ確保せよとはあるけど必要充分にとは書いてないから、
3次元分のメモリとポインタ分のメモリを確保してポインタの配列をこさえればいいんだけどね。

177 :
>>163
>ただし、縦、横、奥は実行時に与えられ、特定のtype_t型に依存するコードは書いてはならない
これは↓がだめだという意味?
typedef char (*type_t)[w][d];
type_t array = (type_t)malloc(sizeof(int) * h * w * d);

178 :
1行目
typedef int (*type_t)[w][d];
ね。

179 :
typedefしなくていいのなら、
for文で回しながらmallocして、
for文で回しながらfreeすれば出来そうだけど。
(そこまでするんならいっそ1次元でとって、添え字演算したほうがすっきりしそうだが・・・)
>>163 は出来るのかね。

180 :
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10787.txt
自分で書いていて途中で嫌になってきた
typedefを使わないとほとんど読めないプログラムになってしまうのが
ポインタの問題だな
関数へのポインタの配列へのポインタを返す関数
(関数は配列を返す事ができないので配列へのポインタで返す)
でも無駄な事を一段やってるような気がするな
配列だと分かっているんだから配列を変えそうとせず、ポインタで配列の
先頭アドレスを返せば簡単になるような気もする

181 :
いや違うかこれ以上簡単にならんな
関数は配列を返す事が出来ないんだから、配列へのポインタを
返すと書かなければならない
本当はそうではないのだが、Cの文法がそう書く事を許さない仕様に
なっている
こういう場合は関数宣言の方を変えて、配列を返すのではなく関数への
ポインタのポインタを返すと書けば簡単になるだろう
但しそう書くとプログラムが何をやっているのかますます不明瞭になり、
ほとんど読み解く事が困難になってしまう

182 :
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10788.txt
こんな感じ
これなら一段間接参照が減る
さて寝よう

183 :
array[h * WID + w]でいいよ
ひとつ言えることは
ポインタで引っかかる人は、文法や型にこだわる
問題を出されると出題者に盲従する傾向がある
だったら、文法や型や規格書などに従うのを一度やめてしまえばいい
たとえばアセンブラを使ってみるとか

184 :
それでいいなら、int array[W][H];も必要ないね

185 :
[W][H] じゃなくて [H][W] だというところには誰も突っ込まないんだなw

186 :
言いたいことそんな所じゃないだろうからな。

187 :
メモリのスキャン方向が変わるから実行速度等に影響が出るんだが

188 :
>>175から持ってきて、あんまり考えずに成形しただけだから気にするな
>array[h * WID + w]でいいよ だけだったら異論はないよ
あとあと、楽とわかってるから静的に2次元配列として宣言するんだよね
動的確保でも、その楽にする方法があるから、(言い方を借りれば)文法にこだわるんじゃないか
まぁ、これも>問題を〜の1文がなければ、そうですねって話だけど

189 :
>>79
俺と全く同じ奴がいる・・・

190 :
>>184
array[WID][HEI] と array[h * WID + w] は等価ではない

191 :
>>190
なぜ、俺にこのタイミングでレスするんだ
安価は>>175にしてくれよな

192 :
アホ曝しage
184 デフォルトの名無しさん [sage] 2010/07/06(火) 10:38:36 ID: Be:
    それでいいなら、int array[W][H];も必要ないね

193 :
>>183
良くない。
array[h][w]という表記ができない言語(例えばアセンブラ)ならそれでもいいが、
言語仕様で出来るのにやらないと、後から読んだ者を混乱させる。
理由があってわざとやらないのか、書いた奴が知らなかっただけなのか判断つかないからな。
それに、hとかwとかなら array[h*WID+w]でもarray[h][w]でも大差ないが、もっと複雑な式に
なった時に、[h][w]形式の方が断然読み易くなる。
ぶっちゃけ、二次元ポインタを使いこなせない奴の言い訳にしか見えない。

194 :
どうでもいい。
個人的にはベタバッファにポインタアクセスのが分かりやすいし、使いやすい。
C++は知らんがCなら慣れの問題。

195 :
array[i][j] と記述したくなるのは、ベクトルやマトリックス周辺だけかな。
数式をそのままに近い形式で記述したい という意図だけどね

196 :
結果あわせるだけならどっちでもいいんだけれども
配列のアライメントや入れ替えがあるから、用途によるよね

197 :
>>190
どう等価じゃないんですか?

198 :
array[4][5]とarray[5][4]は違うと言っている。

199 :
こういう書き方はどうか?(長文失礼)
・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 :
ご苦労さん

201 :
>>193
記述の問題ならマクロ導入すりゃいいでしょう

202 :
まあな。w

203 :
ポインタに1足したら、2byteとか4byteとか進む?
ポインタってアドレスなんだろ?
そんなもん1進むに決まってるんじゃないのか?

204 :
オブジェクト(要するに型)のサイズ分進む。
sizeof演算子で進む量を得ることが出来る。

205 :
>>197
判ってて聞いてるんだろうけど
array[h * WID + w] と array[w][h] はポイントしているアドレスが違う
array[h * WID + w] と array[h][w] が同じ場所を指さないと
共同開発してる仲間に迷惑だろ?
そんなことも知らないからポインタスレに来てるんですねわかります

206 :
前者は連続した領域にmallocすることが求められるが、
後者は離れた領域にmallocしても一向にかまわない。

207 :
そろそろ>>163の見本お願いします

208 :
>>207
まあ、あせるな
みんな、なかなかいい線いってるよ
もう少し検討が深まるのを待とう

209 :
>>208
これはだめなの → >>177
C89ならw,dが変数でも通ったけど。

210 :
>209
>208ではありませんが、コンパイラとコンパイルオプションを示してみてください
また、可能であればコンパイラのバージョンも示してみてください

211 :
>>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 :
昨日、下記のソースをいじってら通ったんで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 :
てか何が出来たら「三次元的に扱え」たコトになるのよ?
条件が色々付いてるけど、根本的な要求が分からん

214 :
下記のポンタ何を指すが書きなさい
15秒以内の回答できて小学1年レベルらしい
int (*a)[N];
int (*f )(char);
int (*f [N])(char);
int (**f [N])(char);
int (*(*f )[N])(char);

215 :
>>214
日本人ではないな?
だからどう、ということもないが

216 :
m行n列の二次元配列をメモリ上に表現する場合
1 サイズm*nの一次元配列として確保
2 サイズmのポインタの配列とサイズnの一次元配列m個
1の利点 ポインタの配列分メモリが必要無い
2の利点 列を削除追加できる
2は多段のポインタなので
普通の二次元配列として扱うと遅い
中継用のポインタ使う必要があるので可読性は低い

217 :
2 はargvですね

218 :
小学生すごいな、即答出来ても15秒で書けないな

219 :
>>218
小学生でも朝鮮・中華の小学生だから

220 :
>>214
上から順に
行列の行単位で動くポインタ
関数ポインタ
ポインタ配列
ポインタ配列
行列の行単位で動くポインタ
行列やポインタ配列の要素の型、つまりテンプレート引数に相当する部分は気にしない。
昔のJavaはそうだったというかむしろシンプルでわかりやすいとか言われて普及した。

221 :
>>216
>2は多段のポインタなので
>普通の二次元配列として扱うと遅い
これマジ?
ケースバイケースだろうけど、乗算して加算して参照より、
参照してさらに参照のが速いのかと思ってた。

222 :
>>221
F-22とスピットファイアくらい違う

223 :
>>214
ポンタはわからねえな

224 :
>>223
上から順に
 ポインタ
 ポインタ
 配列
 配列
 ポインタ
なのは分かるよね。
後は、ポインタだったらポインタの部分を削除して型を見て、
配列だったら配列の部部を削除して型を見る。
そうすると、
 配列のポインタ
 関数のポインタ
 関数のポインタの配列
 関数のポインタのポインタの配列
 関数のポインタの配列のポインタ
となる。
合ってる?

225 :
>>180
int (*((*func(void))[]))(void)
これ鬼みたいだな
しかしプログラムを読むと大して難しい事をやっているわけではない
Cの宣言はどうしてこんなに難解なのだろうか

226 :
>>222
どっちが速いのかすら分からん。
あー、もしかしてキャッシュに乗らない?
あんまりその世界で生きてないんで
どう動くのかサッパリ。

227 :
>>225
アセンブリをやれば簡単に読めるようになる

228 :
int (*((*func(void))[]))(void)
は保育園レベルでちゅよ
この程度すぐに解らんと保育園レベル未満の国語力ってことでちゅ

229 :
>>225
リンク先は見てないけど、そんなに難解?
ちゃんと()付いてるし。
まず一見してfunc(void)な関数の宣言だろ。
*付いてるから返値はポインタ。
さらに[]なんで配列のポインタ。
次の*で、ポインタの配列のポインタ。
で、最後にint ()(void)なんで、つまりこの宣言は
そういう関数へのポインタの配列のポインタを返す、引数voidな関数funcの宣言。
長々書いて違ってたら、凄い恥ずかしいんだが、どないだろ?

230 :
>>229
>長々書いて違ってたら、凄い恥ずかしいんだが、どないだろ?
どのように解析するか自信ないのか?
コンピラー(C言語)の構文解析ルールをよく知らないってこと?
コンピラーはfunc(void)が関数の宣言ってどうしてそう判断するん?
職業PGにとって構文解析って基礎中の基礎事項で学校で当然習っているじゃないの
それすら知らないのに職業PGやってるって人居ないよね
趣味PGなら自分が必要と感じたら勉強してみるか程度で良いけど

231 :
>>221
キャッシュへのプリロードするのに間接参照だと予測不能。

232 :
書き方を修正。「$T」じゃなくて「T$」に変えてみた。
・char , int は型である。
・Tが型ならば、T[N]は型である。(Tの配列と解釈する)
・Tが型ならば、T$は型である。(Tへのポインタと解釈する)
・T,U1,U2,…,Umが型ならば、T(U1,U2,…,Um)という記号列は型である。(関数と解釈する)
・宣言方法は「T a;」とする。

233 :
以下、具体例。(長文失礼します)

具体例(カッコは適宜省略)  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 :
>>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 :
関数ポインタ関連の表記は参考サイトや本を読みながらじゃないと読めん
あれ何とかならんかったんか

236 :
typedef すれば大抵解決

237 :
>>230
煽りか本気か知らんが、職業PGに夢見すぎ

238 :
関数ポインタが読みにくいという事はCでC++モドキのプログラムを
バリバリ書くのは不可能に近いって事ですね
それか無駄な時間を多量に要するか

239 :
>>238
他の言語に比べて積極的な気持ちになりにくいかな?
ただ、昔読んだテキストエディタのソースでは、入力文字のアスキーコードを引数にして各入力処理関数に飛ぶように、関数ポインタの配列が使われていて感動した。
日本語処理をさせるのは難しそうだけど。

240 :
perlよりマシだな

241 :
エセクラスならgtk2が頑張ってなかったっけ?

242 :
gtk++/gtkmm よりも gtk の方が出来が良いという

243 :
>>229
あってますね
規則に従って変換したら、>>234になったw
int(void)*[]* (void) func

244 :
>>235
>>232-234の書き方だと、日本語の語順そのままで
宣言できます。たとえば、
・(戻り値int,引数charの関数)へのポインタ
が欲しかったら、そのまま
(int(char))$ pfunc;
と書けます。>>180
>int (*((*func(void))[]))(void)
だったら、これを日本語読みすると
(((戻り値int,引数voidの関数)へのポインタ)の配列)へのポインタ)
を戻り値とする、引数voidの関数
となるので、この語順そのままに
(int(void))$[]$ (void) func;
と書けます。

245 :
>>244
君は度々出て来るようだけど、結局主張は何?

246 :
>>245
>>232-234の書き方なら、C言語よりも
ずっと読みやすい表記法で関数ポインタが表記できる、
ということです。

247 :
>>245
型の表記は関数型言語スタイルがいいですね、ということです

248 :
typedef の方が判りやすいよ

249 :
>>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 :
ou....
× Func ≡ (int(char))$
○ PFUNC ≡ (int(char))$

251 :
んなことは言われんでもわかっとる
    (int(char))$
よりも
    PFUNC
の方が判りやすいだろって話


252 :
>>246
よく分かった。
新しい言語、文法を語りたいだけなら、引っ込んで黙れ。
そういうスレがあるし、そっち行け。
ポインタが分かりづらいのはCの文法が悪いから、とか
それなりのコト言うのかと思えば、ただのアホかよ。

253 :
>>251
どうですかね。「PFUNC」と書いてしまうと、中身が
見えなくなって抽象的になってしまう弊害があります。
(int(char))$だったら、そのまま読めます。
しかも日本語の語順のまま読めます。
僕にとってはint(char)$ の方が読みやすいです。

ただし、PFUNCという記号列を日常的に
typedef int (*PFUNC)(char);
の意味で使っている人だったら、その人にとっては
PFUNCという記号列は全く抽象的では無いわけですから、
その人にとっては、PFUNCの方が読みやすいかもしれません。

254 :
ひとつのプロジェクトに
独自のGC、newが複数混在してると
最高にわかり辛い
それぞれが読みやすいものでもな

255 :
>>252
>ポインタが分かりづらいのはCの文法が悪いから、とか
>それなりのコト言うのかと思えば、ただのアホかよ。
え?それって同じことですよね?
「ポインタが分かりづらいのはCの文法が悪いからだ!」
という意見を煮詰めて行ったら、どのみち
「では、文法をこのように変えたらどうだろうか(例えば232-234のように)」
という意見にならざるを得ないでしょ?

256 :
// それぞれが読みやすい
typedef int (*PFUNC)(char);
typedef PFUNC T[N];
// 混在すると分かり辛い
typedef int (*T[N])(char);

257 :
混在してると分かりづらくなる文法が悪い?どっちが悪い?混在が悪い?文法が悪い?

258 :
>>255
ならんよ。
だってその表記を見ても、Cのポインタが
理解できるようになりそうにないもの。
言語変えて済む話ならポインタのない言語を選べばいい。

259 :
>>258
言ってることが矛盾してませんか?あなたにとって、
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見は"それなりの意見"なんですよね?(>>252にそう書いてあるし。)
でも、これは「Cの文法を改良すればポインタが分かるようになる」と
言っているのと同じことですよ。
一方であなたは
>言語変えて済む話ならポインタのない言語を選べばいい。
と言ってますから、結局あなたは
「Cの文法を改良すればポインタが分かるようになる」
という意見を全否定しているわけです。つまり、あなたは
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見を"それなりの意見"としつつも全否定しているわけです。

260 :
●Cのポインタの文法は分かりづらい
●文法を変えたらもはやCではない
これは矛盾しないぞ

261 :
>>260
これはひどいww
というのはさておき、
>●Cのポインタの文法は分かりづらい
これは単に文法の煩雑さを嘆いているだけであって、
>ポインタが分かりづらいのはCの文法が悪いから、とか
↑この意見とは全く別物ですよね。

262 :
>>259
それなりの意見というのは、少なくとも
ポインタで引っかかる理由を言っている点においてそれなり。
それを解決する方法として、別の文法を考えるという
アプローチは全否定してるよ。
理由はCのポインタの理解に役立たないから。
そんなに矛盾してる?

263 :
全否定はつられて言いすぎた。
なにがしかのモデル的に、理解の役に立つならいいんじゃないの?
「僕の考えた宣言の文法はスバラシイんです」
だから何なんだよ?

264 :
Cを普通に勉強すれば済む話。
どっかの馬の骨の自分ルールはもうお腹一杯。しかも読みやすくなってないし。

265 :
>>263
>「僕の考えた宣言の文法はスバラシイんです」
>だから何なんだよ?
それだけです。少なくとも>>235みたいな人の役には立ちますよね。
まあ、文法なんて結局は慣れの問題ですが。
>>264
あなたはCの文法に毒されすぎです。結局は慣れの問題に終始しますが、
それにしてもCの文法は「変」ですよ。誰でも一度はそう思うはずです。
熟練するほど忘れていく感覚ですが。

266 :
>>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 :
(長文ゴメンナサイ)
さて、どのような宣言の日本語読みも、構文解析のように分解すれば
「Tへのポインタ」「Tの配列」「戻り値T,引数U1,U2,…,Unの関数」に
分解できますから(ただし、ここでは構造体やクラスは考えないことにします)、
これらに忠実な表記を採用すれば、自動的に日本語読みと同じ語順の宣言になります。
この過程をよく見ると、単に日本語読みの省略記法を作っているだけの話ですよね。
>>229が良い例ですが、宣言されたポインタを理解するとき、あるいは相手に説明するとき、
やっぱり"日本語読み"に直して理解するわけです。それは「>>232-234の表記法に直して理解する」
と言っているのと同じことです。なぜなら、232-234は日本語読みの省略表記だからです。
僕は232-234を強要するつもりはありません。
でも、232-234を無闇に否定する人は、日本語を否定してるのと同じことですよ。

268 :
>それだけです。
だから無意味だっつってんの
>少なくとも>>235みたいな人の役には立ちますよね。
立たない。
結局Cの宣言は読めないまま。

269 :
日本語でしか通用しない新規ルールイラネ。世界中で通用するCをマスターした方がいい。終了。

270 :
Cの文法はよくわからない。たぶん頭のよくない人が作ったんだろう。
よし頭のいい俺がもっといいルールを作ってやろう。

出来た!これで皆便利になるし、俺に感心するはずだ。
たぶんこういう思考回路なんだろうな・・・。
まさしく中二病ってやつだな。
見てるこっちが恥ずかしくなるよ。

271 :
他人のRーを見たいわけがない罠

272 :
俺は目に入るコード量が減るからtypedef使うけど、最初からC言語がその文法だったらと思うな
日本語読みというより、型の遠い順だね(Cもそうなんだけど見ため的に)

273 :
>>232が得意げに自分ルールを披露したら賞賛されるどころか袋叩きにあっててワロタ

274 :
Cの時代は終わってる

275 :
すきにすりゃいいんだけどな
typedefしようがスマートポインタ使おうが
他人が使う事になれば苦労するって話

276 :
確かにコーディング規約も命名規則もないところで、typedefは使ってほしくはないな

277 :
個人的はtypedefを探すのにかかる時間次第かな。
2、3分くらいで見つかるようならtypedefして貰う方が読みやすい。

278 :
> typedefを探す
意味が分かんないんだけどどういうこと?

279 :
>>278
日本人ではないな?
だからどう、ということもないが

280 :
>>278
ある定義名について、それをtypedefで宣言している文を探す、ということ

281 :
>>279
日本人だよ
IDEなら言うまでもなく
非IDEでもタグファイルを作っておけば一瞬
最悪Grepしてもそんなに時間が掛かるものじゃない
探すという感覚が分からないんだよね
強いて言えば
coする程ではないが少し気になるものを
Webブラウザ上で眺めてるときかな?
と思ったりもしたけどそれはtypedefに限った話ではないしなぁ

282 :
元の定義読んで意図理解する必要があるのは変わらないからな
メモリ確保がごっそり独自になってる事なんて
よくある事なんだけど
仕様読んで実装全部書き直して
移植したりとかめんどくせーから嫌いです

283 :
>>265
Cの文法のどの点が変なのかわからない。多分毒されすぎたんですね。
さしつかえなければ教えてください。

284 :
>>268
>だから無意味だっつってんの
まあ、ポインタ自体の話をしたい人には無意味でしょうね。
>結局Cの宣言は読めないまま。
ああ、そういう意味なら確かに。あなたは正しい。でも、>>235
>あれ何とかならんかったんか
この部分への1つの回答には なってますよね。
>>269
新規ルールではなく、既存のルールです。あなたは既に
このルールを使ってます。なぜなら、232-235は日本語読みの
単なる簡略表記に過ぎないからです。
あなたが日本語の語順で関数ポインタなり何なりを捉えたとき、
それは232-235を使っているのと全く同じことです。
あと、英語読みとも親和性は高いですよ。
日本語読みの語順を逆順にしたのが英語読みですから。

285 :
アンカミス...
× 232-235
○ 232-234

>>270
賞賛される必要はありませんが、無闇に否定されるのは
おかしいです。なぜなら、232-234は日本語読みの単なる
簡略表記だからです。これを否定するのは>>229の説明方法を
否定するのと同じことですよ。
>>271
Rーと言えるほど独りよがりな文法では無いでしょう。
intがN項の配列 a;
戻り値int,引数charの関数へのポインタ pfunc;
このような日本語のベタ書きと全く同じ表現をしているのが232-234です。
こういう表現形式を無闇に否定するのは、>>229の説明方法を否定するのと
同じことですよ。

286 :
>>283
関数ポインタ周辺の宣言における表記の語順が、
自然言語の語順から かけ離れているところ。
日本語読みの語順と全然違うし、英語読みの語順とも全然違う。

287 :
語順はどうでもいいけど
その定義の通るコンパイラ(またはプリコンパイラ)はもう実装出来てんの?

288 :
反論かと思ったら同じこと繰り返すだけのキチガイか

289 :
使用と宣言を一致させる、ってのはスルーなの?

290 :
ポインタがわからなくてこのスレ開いたが
もう嫌だ何これorz

291 :
このスレって何について話すスレなの?

292 :
>>281
IDEの機能や、grepを使うのは充分「探す」だろう

293 :
>>290
たとえば、どんな所がわからないの?
引っかかってるところを(それがどうして分からないのか)知る為に、色々教えてくれると思うが

294 :
>>149はいい線いってるね
最終的に型につくならよかった

295 :
>>292
後者はそうだね、自業自得だけど。
でも前者は違うな。
>>292
↑というアンカーに対し292のレスを探すとは言わないでしょ?
カーソル合わせりゃToolTipが表示される(IDE) ← 探すとは言わない
クリックすればリンクに飛ぶ(tag) ← 探すとは言わない
ページ内を検索する(Grep) ← 探すとは言うかもしれないけど自業自得

296 :
>>286
演算子の結合順位が頭に入っていないと、たしかに読みづらいかもしれません。

297 :
覚えられなくてカッコを多用

298 :
>>294
int* p;は型についてるように見えるけど
int *p;はそう見えない
後者はどう解釈したらいいん?

299 :
型は宣言から識別子抜いたものだって教わりませんでした?

300 :
>>299
識別子抜いても意味合いは同じじゃない?
(int*)
int (*)
後者は型についてるように見えない

301 :
「括弧内の宣言子は、括弧なしの宣言子と同一となるが、
複雑な宣言子の結合が括弧によって変更されることがある。」
演算子の結合順序を変えるような括弧じゃない限り
論じるのは無駄。何を言いたいのかさっぱり不明。

302 :
>>301
記号操作の話ならそれでいいけど、俺は意味論的な話をしてるんだが
どうレスしたらいいものか

303 :
セマンティクスとも違う別の何かだろ。
ポインタの話ですらない。

304 :
括弧の位置なら単なる文法論の話じゃないのかな。
意味論なんて言うなら、ますます括弧なんて重要じゃない。
要するにどうでもいいような文字の置き方に
さも意味があるような話を意味論って言ってるんじゃないのかね。

305 :
ポインタより重大なのが、
#define N 1
という使用方法。
N かまわず置き換える。

306 :
定数なら定数でいいし、文にまで使うのは分かりにくくなると思うけどな

307 :
>>305へのレスですか?
定数Nを #defineするのは、辞めた方が良いよ。
関数名や、変数名で大文字のNが含まれたら全替えする。
これにより、マクロを含めて#define全面禁止をモットーにした。


308 :
本当の意味の定数でいったら、
constは変更不可能なだけで定数じゃない。
#defineが定数にあたるけど、別にどうだっていいよねー。

309 :
>>302
意味論てのが何か分からんけど、識別子を評価する方法も
型で表現しようとしてるから、*が右に寄るんじゃないか?
言葉遊びするなら、int *pは
intへのポインタな変数p、ではなく、
*pとして評価すると(実体があれば?)intの値が得られる識別子p、
という解釈。
関数や配列の宣言も全てそう。
規格の文面なんて後付けだしな。
今テキトーに考えた。

310 :
>>308
C言語乙

311 :
>>307
あなたの日本語は間違いではありませんが、内容は嘘ですね。

312 :
>>298
型を明示する陽表式ではなく、
「この条件を満たす何らかの型」という
陰伏式で解釈したらどうでしょう。
>int *p;はそう見えない
・識別子はpである。
・pの型は「演算子*による戻り値 *(p) の型がint型であるような、何らかの型」である。…(1)
この解釈だと、*は直接的には型に付きません。
ただし、(1)を満たす型はまさに(int*)ですから、
結果的には(int*)型の変数を宣言していることになり、
*は間接的には型についてると言えます。

313 :
>>309が既に同じこと言ってましたorz

314 :
そんな話してたらまたあのキチガイが出てくるぞ

315 :
>>313
一緒にすんな

316 :
>>309,>>312
これだ!!!こんな解釈がほしかった
やっと腑に落ちたわ、ありがとう
意味論ってのはあれだ、すまんかった
言葉のアヤってことでw

317 :
>>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 :
昔のCではint *p;のみでint* p;はダメじゃなかったっけ?

319 :
>>128でも言われてるな

320 :
>>318
存じませんが、K&Rあたりでそう記述されてたからとかそのあたりでしょうか?
>>319
ありがとうございます、笑われただけで禁止はされていないみたいですね
wikiには方言もあったと書いてるので、これかもしれませんよ
まぁ、寝ます

321 :
ひさびさの2ちゃんなんだけどそろそろ前橋ポインタ本を越える文章って出てきた?

322 :
で、そろそろポインタでひっかかるポイント分かったのか?

323 :
・変数とメモリの関係がイメージ出来ない
・ポインタを絡めた宣言が理解出来ない(しづらい?)
今のところ出て来たポイントはこの辺?

324 :
>>323
よく挙げられる理由の典型例じゃん
これじゃ他のポインタスレと変わらんなあ…

325 :
>>322はポインタとポイントを掛けたかっただけでは

326 :
>>

これがポインタ

327 :
C言語のポインタがわかりやすい言語ってある?

328 :
アセンブラへの展開見れば一目瞭然。

329 :
文法はそう記述したら、そうなるわけだから、詰まる要素ではないだろう
ポインタを知る為にメモリの状態とアドレスをPrintfとか使ってチマチマ
やってた時、頭が沸騰しそうだったな
覚える為に、ここら辺の関係ない所で時間がかかり過ぎるのが問題じゃないかな

330 :
俺はそんなところで時間かから無かったよ

331 :
文法を理解しているというのなら、
ポインタの中身なんて理解する必要なっしんぐ。
C言語のプロトコルに従って書いてりゃどこでも動くコードのいっちょ上がり。
と言いたいところだが、そうもうまくいかないと思う。

332 :
TOEIC満点のやつは英語で嘘をつかない、なんて保証があると思う?

333 :
誰か翻訳頼む

334 :
指を見るな
月を見ろ

335 :
文字列処理や勉強の時のscanf()で何度も不正な処理起こしたC言語初心者時代
普通の高級言語なら実行時エラー、エラーメッセージで分かる内容のところを
いきなりOSからエラー返されたらビビるって

336 :
いや
エラーでりゃましなほうさ

337 :
ポインタ挫折歴3年の俺が来ましたよっと
char *s = "test";
なんでこういうことが出来るのかいまだに理解できない
char s[] = "test";
とは違うの?

338 :
>>337
前者と後者は本質的に違う。
前者は読み取り専用領域に置かれた文字列へのポインタを保持している。
後者は【文字の配列】そのもの。
まず、C言語のFAQでも見ようか。
http://www.kouno.jp/home/c_faq/c6.html#0
http://www.kouno.jp/home/c_faq/c1.html#32

339 :
どのレベルで分からんのかが分からんなぁ。
ちょっと嘘を交えて言うと
"test"は、プログラム開始時にOSが用意してくれる5バイトの
書き換え不可な配列として解釈される。
char *s = "test"; は、アドレスを指す4バイト変数sを作って
OSが用意した"test"の先頭のアドレスを代入する。
char s[] = "test";は、OSが用意した"test"と同じサイズの(5バイト)
配列を作って、"test"の内容をコピーする。
違いは大体こんなもん。
どこが嘘かは、興味があるならまた別途。
何故そう書けるのか、と言われると、Cが文法として、
そういう機能を持ってるから、としかよう言わんなぁ。

340 :
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 :
俺の彼女をボインだ!って言われるようにするにはどうすればいいですか?

342 :
>>337
前者
_s: dc.l __lbl
__lbl: dc.b 'test', 0
後者
_s: dc.b 'test', 0

343 :
引っかかりそうな所には近づかない・逃げるという方法もあるな。
scanfとか初期化式とかは、ポインタと少しは関係あるが、
関係ない部分で引っかかってる感じもする。
あまり関係ない所に全力でぶつかったり、教える側も全力で教えようとしていたら
それは学習コストは高くつくに決まっている。
自ら望んで全力で引っかかるのは構わないが、
「なぜ引っかかることを望んだのか」を他人に問い詰めるのは迷惑だ。

344 :
>>341
まずRを捨てる。

345 :
char *s="test";
sprintf(s,"Hello world");
正常に動くようですがこのまま使って大丈夫でしょうか?

346 :
はいはい、ネタは自分の頭の中でやってくれ
それが嫌なら窓を捨ててペンギン村にようこそ

347 :
>>345
だめです。
というより
char *s = "test";
という使い方はほとんどしないから忘れてもいいかと。

348 :
const char *s = "fuck me please!!"
ならいいよ

349 :
そこはfackだろ

350 :
>>345
char *s="test";
*s="Hello world";
でいいじゃん

351 :
s="Hello world";

352 :
配列は関数に渡すとポインタに変換される
ポインタはprintfされるとアドレスに変換される
暗黙に二度の変換を受けるという理不尽な仕様

353 :
おいおい。
全て間違ってる。

354 :
#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 :
cでtrycatchとかありえない

356 :
ポインタは変数のある場所を指している(キリッ)って説明がわかりにくい
「指してる」ってなんだ?と思ってた
はじめにscanfや関数の引数としての使い方から説明するから単体での理解がしにくい
アドレスを格納する変数ならそう言って欲しい。分かりやすくしようとしてわかりにくくなってるよたぶん
あと変数宣言の説明を軽くスルーしたり、ポインタをポインタ型とかint*型とか言わないのも問題な気がする
ポインタだけ特別枠の別物みたいにみえる
プログラミング習いたての人との共通認識を探ろうとしないのも分かりにくさに拍車をかけてる
難しいんだよー、だから分からなくても仕方ないんだよー、俺のせいじゃないよーってか
分からせる気ないだろうと

357 :
英語で言えば
ある場所を指している=ポインタ
だからな
ポインタは変数のポインタ(キリッ)
じゃ判らん罠

358 :
再帰的定義だよ

359 :
http://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF_(%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
変数って書いてあるけど、値のことだよね。
ポインタとは、オブジェクト(≒変数)の位置を表現する値を指す。
C/C++ではメモリアドレスを使用するのが一般的。
ポインタに対して演算を行うことにより、オブジェクトを取得したり、
またオブジェクトに隣接する位置のオブジェクトのポインタを
取得することができる。
ああ、こう書いちゃうと分からないんだよなあ。
やっぱ箱のポンチ絵無しには説明は無理だわ。
で、更に変数宣言がどういうものなのか書こうとすると
rationaleとか持ってこないと荷が重い。

361 :
だからアセンブラに落とせば一発だっつーのに

362 :
アセンブラにCみたいな複合型ねーだろ。

363 :
ワロタw
結構いるよね、ほのめかしはするけど実は答え知らない自称上級者

364 :
>>362
ある夜

365 :
>>364
値の出し入れ以外に
まともな文明の利器があったなんて知りませんでした。
もちろん人が解釈するものじゃないよね?
きちんと文法なんだよね?

366 :
ポインタはクイックソートをする為だけにある。
それ以外の用途では不要。

367 :
>>366
おまえ楽な仕事なんだな

368 :
>>360
ポインタと言った場合、ポインタ型のことか、
ポインタ型の変数のこと。
値はアドレス

369 :
クラスメンバへのポインタで質問です
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 :
C++ちゃんと知らんけど
「いけると思うのですが」の時点で
いけてないことないか?

371 :
普通に&Inner::hogehogeじゃダメなの?

372 :
でいけると思うのですが

373 :
ぬるぽ

374 :
ポインタはすんなり理解できたけど「逆参照」だけはずっと意味不明だった。
なんだよこの訳語は。

375 :
デリファレンスでいいだろ

376 :
俺なら訪問と訳して全国のポインタ脱落組を3000人くらい救っていたな。

377 :
入門書の間違いなんて、たまたまそれに嵌って痛い目にあったりでもしない限り、
いちいち覚えちゃねえよ。
複数言語やってりゃ、記述が間違っていても何となく回避してるし。
子どもの時に乗った三輪車の善し悪しなんぞ誰もわからんのと同じ。
ぐだぐだ言うのは、三輪車をとっかえひっかえしている池沼と、書いた著者くらいのもん。

378 :
それはそうかも

379 :
>>375
デリとな

380 :
>>377
複数言語やってても、そこにポインタ扱う言語が無かったらやっぱ引っかかるよ

381 :
>>373
Javaじゃないからガッしてくれないよ

382 :
スマポで引っかかりました。
詳細は以下から。

class Dog : public IAnimal
というクラスがあって、これをスマポでインスタンスを生成すると
void fanc(IAnimal animal)
に入れられなくなります。
どう書けばいいんですか?

383 :
>>380
間接参照の概念さえあれば大体何がやりたいのかは分かる

384 :
>>382
そのスマートポインタをデリファレンスすれば委員で内科医?
言語が判らんから具体的には答えられないが。

385 :
>>382
アセンブラやればわかるようになる

386 :
C++(VC10)です
↓こういうふうに書いたら駄目なんですか?
何で入らないのかわかりません
std::shared_ptr<IAnimal> dog_ptr(new Dog());

387 :
>>386
ポインタを実態を必要とする関数に渡したいなら、>384の言うように逆参照すればいい。
もしかして、単項*演算子も知らないのか?

388 :
>>382
auto_ptr<Dog> p(new Dog());
func(*p);

389 :
うーん何言ってるかよくわからないのはポインタを避けて通ってるからなのですかね
とりあえず.get()って付けたら入りました
func(dog_ptr.get());
全く意味わからないですが急場しのぎって感じで満足してます
やっぱもってるなってことで

390 :
その程度で満足できるんなら勝ちでいいよ

391 :
>>389
メモリの絵を描いて理解するんだ。

392 :
たとえばK&Rは第5章がポインタで第6章が構造体だが
ポインタは避けるが構造体 (クラス) は避けないって感覚は異常だよ
ふつうに考えるとポインタよりもクラスのほうが難しいはずだよ
なぜか知らないがクラスが難しいと言うのは恥ずかしい
ポインタが難しいと言うのは恥ずかしくないという空気に支配されている気がする

393 :
知らんがな

394 :
何かあるとK&Rという空気に支配されている気がする

395 :
3連休だしプログラミングの勉強しようぜ
ttp://tsushima.2ch.net/test/read.cgi/news/1279349199/

396 :
>>392
ポインタのほうが構造体よりずっと難しい
ポインタは存在しないオブジェクトを指す可能性があるし、表記が複雑になる
構造体のほうが難しいと勘違いするのはポインタを理解していないからだ

397 :
逆をいえば、存在しないオブジェクトを指さなくて構文が複雑にならない
ようなポインタなら問題ないんだよな
JavaやPythonの間接参照に引っかかるようなヤツはそうそうおるまい

398 :
ポインタ難し・・・・^^;

399 :
ポインタや構造体のどこが難しいのか理解できない。
Win32APIのほうがよっぽどマンドクセ。

400 :
%pに細工して
printf("%p", p)の出力を
〒100-0014 東京都千代田区永田町1丁目7−1
とかにすればイメージ沸きやすいと思う。
アドレスと値を同列に扱えてしまうのがコンピュータの強みでもあるが
混乱の基なんだよ。

401 :
哲学的な話になりそうだなw

402 :
もう黙ってアセンブラから入るしかないのでは?
というか、我々の頃は、ちょっと言語がわかるようになったら、自然とそうなっていたような気がするのですがね。

403 :
ポインタは間接参照を表現するものとしては
無駄の多い構文になってるのがアレなだけで
こういうアプローチ以外は不可能ってほど難しいものじゃないだろ
アセンブリなんてしなくてもよろしい

404 :
そんなものやって役に立つの?

405 :
アセンブリは知らなくても良いけど、メモリ上でプログラムが
どうやって動いてるかの概要ぐらいは分かってないと、
ポインタまわりのデバッグはやりづらいね。

406 :
>>403
無駄が多いと感じる原因は「型」。
メモリ上には型がない。なぜなら必要ないから。
型がなくてもプログラムが動くことが分かれば、
ポインタが (構文の見た目ほどには) 難しくないことが分かる。

407 :
>>406
そのような「型の必要がない」という事実を体験するには、アセンブラをやるのが手っ取りばやい、と。

408 :
byte, word, dword, qword ...

409 :
>>408
masm か‥‥‥。

410 :
masm は構造体も使えたな

411 :
メモリアドレスを指す、参照でしょ?

412 :
ポインタで引っかかるのはC言語のせいだと思う
Cって、ポインタ依存度高過ぎる上に
そのポインタの扱いがフリーダムだからなぁ…
ポインタ依存度低めで、扱いがそこそこ厳しめなDelphiだと
ポインタで引っかかった経験はあまり無いぞ

413 :
Delphi って ObjectPASCAL だろ

414 :
TurboPascal for Windows

415 :
>>412
えーと、つまりポインタ自体の概念は難しくない。
そこに掛かる、文法や、派生概念が捕らえ方を
面倒にしてる。
ってこと?

416 :
>>415
そんな感じかな?
例えば、C言語で
「純粋な参照渡し」が使えたり
ポインタに厳格な型があって明示的なキャストをしたとき以外では互換性が無かったり
文字列型をコア機能として持ってたり
動的配列をポインタを使わず使えたり
ポインタを利用するような標準ライブラリがそもそもほとんど無かったら?
本当にメモリを扱いたい時にしか使わない概念になってたら
ポインタで引っかかる人は相当に少なかったと思う

417 :
配列か…
配列の制限の多さにビビッタ覚えがあるなぁ。
配列を返すためにも、ポインタを使うんだよ。
と、師匠に言われて、俺の価値観が崩壊した。

418 :
>>415
typedef使えばすっきりするからやってごらん

419 :
もともとアセンブラで書いてた人用の物だから仕方ないね

420 :
たしかにポインタの概念自体は馬鹿でも理解できるものだと思うな

421 :
>>416
C#のアンセーフポインタみたいな感じ?

422 :
俺はそのアンセーフポインタとやらを詳しくは知らんが
要は本当にメモリアドレスを扱う以外には使う必要がないってことか?
だとしたらまあそこそこ合ってるかな
ポインタ自体も出来る限り安全であるべきだとは思うが

423 :
今となっては、安全でないところが、Cのポインタの利点だからなぁ・・・

424 :
Cはポインタのせいで最適化がしづらくなっている。
バグもでやすいしね。
一番いいのはCを使わないことだ。

425 :
低レイヤー向けの使いやすい言語を作ろう。
って話はないのかな。

426 :
LLVM。

427 :
>>425
Cがあるじゃん

428 :
>>424
ほとんどの言語はヒープのせいで最適化しづらい。
バグがいやなら、一番いいのは最適化を諦めることだ。

429 :
ぼっとんネタ
http://www.atmarkit.co.jp/news/200909/07/lltv02.html

430 :
>>427
Cの領域にGoが侵食し始めてるな。
あと5年もすればC?なにそれ?Cobolとかいうやつ?みたいな扱いになるよ。

431 :
カーネルの実装やらC++がいる時点でそれはないわwww
業務開発ではもうC使わないけどな

432 :
>>425
Dがあるじゃん

433 :
ポインタのポインタのポインタで初めのポインタに繋がったらどうなるの?

434 :
普通は型エラーになるよ。

435 :
元彼の元彼の元彼で初めのエイズに繋がったらどうなるの?

436 :
アッー!

437 :
ご冥福をお祈りします

438 :
int hoge(int a[10])
{
  int b[10];
  return *a;
}
aはポインタなのにbは配列
ポインタと配列は似ているとかいう解説にかなり混乱したもんだ
スタック・ヒープ・文字列あたりがメモリのどこに確保されるかも
一緒に覚えないとポインタはいつまでたっても和歌ランと思う

439 :
この10とかも飾りだしなぁ

440 :
仮引数に[数字]使ってもいいけど、
それが許されるのは配列へのポインタとかだな。
要するに可変長配列とか多次元配列の要素とか。

441 :
しなくていい(実際の業務では必要ない)表現のフェイクが多すぎて混乱してるだけじゃね?
配列は領域が単に連続してるだけで先頭だけみたらポインタ
違うとかそういうもんじゃなくて比べられないだろ
ポインタの指す先が問題なんであって・・・
mallocでとった領域だって連続してるし
char *p = (char*)malloc(sizeof(char)*100);
char p[100];
とかどう違う?とか聞いたらまた混乱してしまうんだろか?w
こんなもんの違いなんてそう意識することないと思うけどねw

442 :
Cのよいところはポインタを無駄にちりばめすぎてて
理解してないとろくなコードをかけないところだな。
ASSERT(ポインタを理解している);と先頭に書いてあるようなもん。
中には五里霧中なままコード書いて金もらってる猛者もいるけどさw

443 :
>>441
こいつはバカすぎる

444 :
sizeof(p)
p=(char*)0

445 :
>>443
夏休みだなw

446 :
俺から見たら>>444の回答を知った上で>>441の言ってることはもっともだと
思うけど、人によって違うのか
ここら辺もポインタと配列の違いという話をするときに誤解しやすい要因かもね

447 :
>>441は何が言いたいのかよく分からない
配列もポインタも大差ないと言いたいのか?

448 :
ぶっちゃけこの違いを意識できないヤツがメモリリーク起こすんだから、「そう意識することはない」というのは乱暴だと思うw

449 :
>>441 は多次元配列を考察すれば納得できると思う。

450 :
>>444
sizeof(p)は微妙だな
ソースまたぐと正常な値返ってこないからなw

451 :
本質的には(アセンブラ的に見れば)
どちらも同じ。

452 :
>>451
わかる人からすればもっともな意見だとも思う
ただ、言語仕様的には明確に違うし、教える側がその辺はしょって初心者に説明するのが混乱の元だと思う
よく分からない例え、不正確な同一視は問題の先送りにしかならないんだよなぁ
いつかまとめて乗り越えなきゃいけない日が来る

453 :
int main

454 :
つまづく

455 :
配列のコピーとポインタのコピーは明確に違う
その点はjavaだろうとpythonだろうと引っかかる人は引っかかる

456 :
ポインタ
□→□□□□

457 :
でっていう

458 :
下記は完全に同じ意味ですか?
 p->a;
 (*p).a;
同じだとしたら、なぜわざわざ
 ->
という演算子を用意したのでしょうか?
由来とかあったら教えてください。

459 :
Cの目的の一つにタイプ量を減らすことってのがあったな。

460 :
(void)p->a->b->c;
(void)(*(*(*p).a).b).c;
いちいち先頭に戻って挿入するなんて考えられない
(void)p[0].a[0].b[0].c;
これもなんか嫌だよ

461 :
どんだけネストしてんだよw

462 :
超巨大構造体ですか?

463 :
(void)foo->super(foo)->hoge(foo->super(foo));
(void)(*(*(*foo).super)(foo)).hoge)((*(*foo).super)(foo));
一時変数使えよって感じだな
DirectXとかlibjpegとかCore Foundationでは構造体と関数ポインタでこんなことやっていたと思う
オブジェクト指向っぽく書けるから良く使う手法だけどね

464 :
>>460
> (void)(*(*(*p).a).b).c;
配列のポインタとか、関数のポインタとかが複数からむと、そんな記述に現実なるじゃん。
何故構造体だけが -> なんてものを用意されて優遇されているのか。

465 :
配列[]も関数()も構造体->も後置
*だけが前置

466 :
優遇前 (*p).a *(p+i) (*p)()
優遇後 p->a p[i] p()

467 :
関数ポインタpfに対して(*pf)();とpf();が同じになるのだから、
ドット演算子もこの仕様に変えたら
p.a.b.c;
って書けるじゃん。

468 :
ポインタの問題 初級
int a[10];
a[0]=10;
a[1}=20;
a[2]=a[0]+a[1];
このとき、a[2]はいくつになるか答えなさい

469 :
それは配列

470 :
30?

471 :
それよりコンパイルが通るのかそれ

472 :
ポインタ関係ないだろ

473 :
int *x

474 :
汚い尻穴だなあ

475 :
int* x

476 :
C++をやるようになってからは、以前よりポインタを使わなくなったな。

477 :
ポインタでひっかかるってよく言うけど、具体的にポインタの何でひっかかるの?
初期化せずに使うミスをするとかそういうこと?

478 :
>>477
こうゆう書き方とかしちゃうんじゃね?
*ptr++  ptr+sizeof(*ptr)
正直なんでポインタで引っかかる人がいるのか理解できない

479 :
時間をかければ理解できるが無駄な時間がかかりすぎる気がする
もっと近道は無いのか
無いなら無いことを証明するべきじゃないか
と愚痴っているうちに時間が過ぎて行きます

480 :
x=20;
p=&x;
*p=30;
これで、pしか変更してないように見えるはずなのにxが30になる
これがポインタのすべてだろ

481 :
>>480
そんな程度なら参照でも挫折するだろ

482 :
こういうのだろ。
struct node {
int value;
struct node *next;
}
struct node *list = ???;
struct node *n;
// 略
struct node **tmpnext = &n->next;
struct node *orgnode = n->next - sizeof (int);

483 :
ミスった。
struct node *orgnode = tmpnext - sizeof (int);

484 :
>>477
本来ポインタとは、ポインタが何かを理解してる人間だけが使えばいいところを
C言語は初心者ですらポインタと無関係ではいられないからだろう。

485 :
ポインタ周りの日本語訳が酷いってのが関係してると思うな
どうしてそんな言葉を当てちゃったのみたいな
まあ俺自身まだポインタのとこまで勉強してないからよくわからんが

486 :
昔内輪ではやったネタなんだけど
車輪だな
しかも劣化した汚ねぇ車輪だな
車輪(スポーク)はケツの皺だな
∴ 汚ねえケツだなぁ
ってことで
>>482
のような小汚いソースを見るとTDNを思い出す

487 :
2重ポインタあたりは引っかかると思う。
char** t = (char**)malloc(10*sizeof(char*));
int i;
for( i=0; i<10; i++){
t[i] = (char*)malloc(100*sizeof(char));
}
こんなふうにメモリ取ってこなきゃならんのをけっこう忘れると思う。
あとは
int test(int a[5][10])
のような引数の時とか微妙に型チェックがめんどくさかった気がする。

488 :
//引っかかる言語
int[] a;
a[0] = 0;
#引っかからない言語
my @a;
$a[0] = 0;

489 :
>>487 は判ってないひと

490 :
大きいオブジェクトを生身で渡すとか
ローカルで定義された参照を返すとか

491 :
ひたすらもし〜でなければを繰り返して切り分けるより
宣言多くなるかもだけど実質中身同じだしってことか

492 :
>>488
それさ、単に宣言してない変数を
自動的に作るってだけじゃね?

493 :
>>487
ポインタ変数を参照渡ししたい場合もあるのですが、それがかなわないので、しかたなしに2重ポインタになる局面は多いと思います。
とはいっても何とかなった場面もありましたが。
http://hibari.2ch.net/test/read.cgi/tech/1280653311/663

494 :
2重ポインタw

495 :
しかたなしに、という表現の意図がわからん。
ポインタはなるべく使うべきでないというドクトリンでもあるのか?
ポインタを使えばできることはポインタを使えばいいだけのことだろ。

496 :
>>495
C++ なら参照渡しにするでしょうね。そのほうがわかりやすい。
int func(int &*p)

497 :
constでない参照の乱用がわかりやすい?どこの初心者だよ。

498 :
>>497
それは参照を理解していないだけでしょう?

499 :
こんな場所なら初心者でも熟練者でも同じように発言できるからなあ。
どっちが正しいか客観的に判断する方法もないし。
「あんたがわかってないだけでしょ」って言ったもん勝ちか。

500 :
ポインタの一次元配列を、二重ポインタって呼ぶんだ
へー

501 :
まじで?
初めて聞いた。
int **a;これが二重ポインタだと思ってた。

502 :
なんか、会社ってところはどこもそうなのかも知れないけどさ
良い人から辞めちゃうよね
んでもって、腹黒い人とか、他人を動とも思わない人とか、
図々しい人とか、・・・そんなのばかりがテコでも動かないぜって
感じで居座り続ける・・・
会社って、こうやってダメになっていくんだと思う
それはそのまんま居座り族・牛耳り族が社会をダメにしていくって
ことなんだ。。。

503 :
 二 重 ポ イ ン タ な ん て 言 葉 は な い

504 :
>>499
それもそうですねえ。
ちょうど宿題スレでポインタのポインタを扱う(正確にはポインタのポインタを使いたいところを使ってはいけない状況に縛られる)状況でプログラムを作成したので、
もののついで、1) ポインタのポインタを使うプログラム、2) ポインタの参照を使うプログラム、を実際に書いてみました。
私の感性では、やっぱり参照を使ったほうがわかりやすい、と思うのですが、どうでしょうかね。
出題内容:http://hibari.2ch.net/test/read.cgi/tech/1280653311/615
ポインタのポインタを使って書いたもの:http://codepad.org/MpmPDEc3
参照を使ったもの:http://codepad.org/nHqWWH51

505 :
>>504
その程度の問題だったらポインタのポインタも、ポインタの参照も使わずに出来るよ。
ポインタだけで出来るから頑張って作ってみ。

506 :
>>505
ポインタだけでつくっています。
http://hibari.2ch.net/test/read.cgi/tech/1280653311/689

507 :
じゃあ最初からそれ出せばいいじゃん・・・
何で無駄なポインタのポインタやら、ポインタの参照やら使ったプログラム書くんだか。

508 :
>>507
>>506 では、2分木に対するデータの追加を扱っていますが、
ポインタのポインタをつかわなければ、
struct node *root;
root = add_node(root, data);
という形になり、これでは再帰が深くなると無駄な代入が繰り返されてしまいます。
本当に代入が必要なのはデータの追加が行われたところのノードですから、そのようにコードをかいて、
sturcut node *root;
add_node(&root, data)
という形にするのが本当だと思います。
参照を使うと、
struct node *root;
add_node(root, data)
とかけますし、add_node() 自体の記述でも、* や & を省くことができます。
具体的なコードの記述例は >>504 のリンク先を参照してください。

509 :
>>508
>ポインタのポインタをつかわなければ、
>struct node *root;
>root = add_node(root, data);
>という形になり、これでは再帰が深くなると無駄な代入が繰り返されてしまいます。
それはロジックが悪い。
そんなに代入を繰り返さなくても出来る。考えてみ。
>参照を使うと、(略)* や & を省くことができます。
参照でコードが短くなるのは当然だが、同時に、「値が変化している」という情報も失われる。
以下のような例がありえる。
struct HOGE* hoge;
func1(hoge);
func2(hoge); //ここで内容をいじっている!
func3(hoge);
これは以下のようにしたほうが「中で何かしている」感じがわかりやすくなる。
func1(hoge);
func2(&hoge);
func3(hoge);
値を変える参照は、短くなるからと無闇に使うと危険ですよ。

510 :
>>509
>それはロジックが悪い。
>そんなに代入を繰り返さなくても出来る。考えてみ。
いや、二分木や線形リストに関しては、ポインタのポインタを使わない限り、無駄な代入が繰り返されてしまいます。
ポインタのポインタを使わずにスマートな方法があるというのなら、それは是非知りたいところです。実例を示してください。
>値を変える参照は、短くなるからと無闇に使うと危険ですよ
それはそうですね。後から読むときにわかりにくいのは事実です。

511 :
「参照を理解してない人」に教えてもらってどうすんだ?あ?
無礼な言葉を吐くだけ吐いて、出来ないとなったら教えてください、かよ。おめでたいガキだな。

512 :
>>511
コードを示してください。
私はすでにポインタのポインタを使ったもの、参照をつかったもの、ポインタのポインタを使っていないものの3種を示しています。
時間はたっぷりありますから、アイディアだけでも示してください。
話はそれから。

513 :
バカバカしい。
無礼者に使う時間などないよ。
おまえよりもうちょっとマシな誰かが、気が向いたらコード書いてくれるかもしれないから、それまで待ってれば?

514 :
>>513
よく検討もせずに
>それはロジックが悪い。
というほうがよっぽど無礼ですね。こちらは動くコードを書いた上で意見を述べているのですけれども。
コードを示してください。
話はそれから。

515 :
そこのロジックの悪さはきちんと検討して発言してるよ。
代替コードも書いている。
おまえにタダで見せる気にならないだけだ。
誰か奇特な人が見せてくれるまで口あけて待っとけ。

516 :
>>515
何か既視感があるな・・・

517 :
>>515
口だけなら「コードを書いている」といくらでもいえます。
それに「見せるきにならない」といいますが、
仮に見せていただければ、私はただただ低頭して「私が馬鹿でした」と発言して消えるでしょう。
それはあなたにとっては、大満足なのではないですか
動くコードを見せて実証することで、私の今までの発言を全否定できるにもかかわらず、それをせずにうそぶくのみ。
これでは、実証するアイディアなりコードなりがないと推測せざるをえません。推測ですけれどもね。
コードを示してください。
話はそれから。

518 :
>>517
おまえが馬鹿(というよりは、低レベル)なことは、俺にとってははっきりしてるからな。
別にこんな便所のラクガキの場所で示す必要も無い。
逆に、示してやればおまえのレベルを引き上げてしまう。バカバカしい。
ど素人はど素人のまま、学生の宿題でもやってるのがお似合いだよ。
だいたい、教えて欲しいなら、最初の暴言を謝るのが順序だろう。それもせずにただ出せなんて図々しい。

519 :
ポインタのポインタなんて、Win32のCOMみたいな使い方をする程度かな
ふつーに
struct data *alloc_root(void);
int add_data(struct data *root, char *name, char *tel);
とか作る

520 :
>>518
ひとつ可能性があるとすれば、非再帰的に記述することですかね。
線形リストならば、それは可能ですが、2分木だと結構むずかしくなります。たぶん各ノードにワークエリアを設けて
戻るノードを記憶しなければならないでしょうね。
昔書いた非再帰的なコードをあげておきます。ポインタのポインタは使っていますが。
http://codepad.org/n3raxalm
私は再帰的なアルゴリズムのみしか念頭にありませんでした。
もし非再帰的に記述することを示唆しておれば、大変失礼いたしまた。

521 :
binary treeで戻る?

522 :
>>521
ええ、binary tree でノードの追加なり総なめを行うのなら、親ノードの位置を逐一記録しておかなければならないでしょうね。
ノードを追加したら、追加されて新しく親ノードになったところをなんらかの形で覚えておかないといけないでしょう。
もしかすると、ノードごとにワークを持つ必要はないかもしれませんが。(>>520 はノードごとにワークをもっていました。)

523 :
親ノードとかいらねーよアホ
バイナリツリーでそんな実装するわけねーだろ

524 :
たしかに非再帰に書くのなら、いらないみたいですね。
http://hibari.2ch.net/test/read.cgi/tech/1280653311/735

525 :
char *name[]ってどういう意味なんでしょうか?

526 :
char **name;

527 :
>>526
ありがとう!

528 :
えっ

529 :
アセンブラでメモリの番地は理解していても
C言語での書き方で悩む事もあるんだよ
>>55みたいな

530 :
constの位置とかもな

531 :
面倒なので括弧を付ける

532 :
>>530
const は一番近い場所にある token が変更不可能になる
っていう理解で桶?

533 :
int const *
近いってどっちだよ、ってなるぞ

534 :
暗記したほうがマシ、というか十分。
理屈を抜きにするから応用利かないけど。
この二つ暗記な。
int *p[] ポインタの配列
int *const p コンストポインタ
だからこそ、
配列のポインタが (*p)[] だと想像できるし、
コンストintへのポインタが int const *だと分かる。

535 :
そんなにむずかしくないだろ
constが後置修飾になってるほうがポインタそのものをconstにしてるだけ
int const もconst int も int を定数にしてるだけなんだし

536 :
いや
いまは
int const * p;

int * const p;
の違いの話をしているんじゃまいか

537 :
イメージ的には、
ポインタの配列は(*p)[] これだし、
constポインタはconst (int *)pこう書きたい。
イメージどおりには行かんね。

538 :
>ポインタの配列は(*p)[] これだし、
hds

539 :
const int *p

540 :
const int *p;
int const *p;
int * const p;

541 :
de?

542 :
掛け算以外のアスタリスクがあまり出てこないプログラムを心がけてますよ

543 :
>>542
それは C の最強の武器を放棄したに等しい。

544 :
>>540
kwsk

545 :
const int *p => const int の ポインタ
int const *p => const int の ポインタ
int * const p => int の const ポインタ

546 :
1行目と2行目の違いが判らんのだが

547 :
違いはない

548 :
えっ

549 :
int main() {
int i = 100, j = 200;
const int *a, *b; // const int
int const *c, *d; // const int
int *const e = &i, *const f = &i; // intへのconstポインタ
int const *const g = &i, *const h = &i; // const intへのconstポインタ

*a = j; // error: assignment of read-only location
*b = j; // error: assignment of read-only location
*c = j; // error: assignment of read-only location
*d = j; // error: assignment of read-only location

e = &j; // error: assignment of read-only variable `e'
f = &j; // error: assignment of read-only variable `f'

*g = j; // error: assignment of read-only location
*h = j; // error: assignment of read-only location
g = &j; // error: assignment of read-only variable `g'
h = &j; // error: assignment of read-only variable `h'

return 0;
}

550 :
ちょい修正:
const int *a, *b; // const intへのポインタ
int const *c, *d; // const intへのポインタ

551 :
えっえっ

552 :
* の左側に const があるか右側にあるかだけですべてが決まるんだよ
* が複数ある場合も何番目の * と * の間に const があるかで意味が決まる

553 :
難しいのー

554 :
far * near * とかに比べると、ああらくちんだ〜。

555 :
>>522
巡回するなら普通はスタック使うだろ?
ってマジレスしたらいかんかったのだろうか
>>523
仕様によってはあり得る

556 :
>>555
この問題、宿題スレの方で実際にコードを書いていただき、戻る位置をおぼえない方法を示していただきました。
すぱっと非再帰に書き下すきれいなコードでした。>>524
でも、二分木は再帰で書きたいもの、とちょっと負け惜しみ。

557 :
スタティックな変数を使えば再帰でも書ける
最適化を考えると大概再帰よりループ展開の方が速い
どっちでも書けるようになったほうがいいぞ

558 :
>>557
それもそうですね。精進します。

559 :
だから言ったじゃねえかよ。
あと、再帰でも、無駄なコピーなしに実装できる。
絶対できないとか頑張ってないで、ちょっと考えてみ。

560 :
学生だと思うけど若い割に頭硬そうだよな
アルゴリズム関係は向いてないんじゃないかね

561 :
>>559
二重ポインタか参照を使わないと無理ではないでしょうか?

562 :
出来るって言ってんのにわからんガキだな〜
人を疑う前に少しは考えろよ

563 :
>>552
嘘書くなよ

564 :
嘘ってこともないだろ。判り難い説明ではあるが。

565 :
面倒だから型の左側以外に const 使うなよ。
const int* a とかにしとけ。
int const *aとか使わんだろ。

566 :
int * const a

567 :
const int const *a;

568 :
>>567
勉強しなおそうね

569 :
>>567
int const * const a;
or
const int * const a;

570 :
>>569
上と下はどうちがうの?

571 :
>>570
かわらない。

572 :
えっ

573 :
>568
修飾子が被っているが無視されるので問題ない
まぁ、書いた人はそんなこと意図していなかっただろうけど

574 :
>>571
どっちが正しいっていうか一般的っていうか

575 :
どっちも正しい

576 :
const int const * const a;

577 :
だから被ってるって、まぁいいけどね

578 :
ひっかけ問題みたいだから。

579 :
>>573
被ってはいないだろ

580 :
>>579
○ const int
○ int const
× const int const
○ const int * const
○ int const * const
× const int const * const
○ const int *
○ inst const *
× const int const *
○ int * const
○ int *

581 :
>>580
> ○ const int *
> × inst const *
○ int const *
inst になってしまそうになる気持はわかる

582 :
int const C::* p; // Cはクラス型
C* c;
c->*p;

583 :
我々のポインタ。いやらしい・・・

584 :
ぬるぽ

585 :
int const * const ** const *p;
コンストintへのポインタへのコンストポインタへのポインタへのコンストポインタでOK?

586 :
間違ってるぞ

587 :
指定子に対する const 以外はすべて後方から修飾。
(指定子に限りどちらからでも修飾可能)
マンバポインタといっしょで *const で一塊と見たほうがわかりやすいね。
int *p;
int ( *func )();
int *const q = p;
int ( *const funk )() = func;
class C;
int C::* r;
int ( C::* funx )();

588 :
う〜、マンバ!!

589 :
char *abc[][3] = {
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
};
で初期化出来ますが、
*abc[][3] の配列(というか *abc[][3] を指すポインタ)は、
char **xyz[][3] = {abc, def, ...};
じゃ代入出来ないんですけど、
どう書いたら良いでしょうか?

590 :
*[][3]のポインタは、*(*[][3])ね
*abc[][3]に対して、abcは*(*)[3]ね
&abcは、*(*)[][3]ね
char *(*xyz)[3] = abc;
{abc, def, ...}は、配列とかにしたいんだろうから
char *(*xyz[])[3] = {abc, def, ...};
配列にしたいので、xyz[]になる

591 :
ありがとうございます
char *(*xyz[])[3] = {abc, def, ...};
ならいけますが
 char *(*xyz[])[3] = {
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
...
};
は無理ですよね?

592 :
char *xyz[][4][3] = {略};
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
}
が[4][3]
""が*
その配列なので、[]
char *(xyz[])[4][3]の方がわかりやすいかな

593 :
あ、説明不足でした。すみません。
char *abc[][3] = {
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
...
...
...
};
なら縦方向に可変長に出来るのに、
 char *(*xyz[])[3] = {
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"fgh", "cde", "@ab"},
{"aho", "baka", "shine"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"}
},
{
{"xyz", "uvw", "rst"},
{"opq", "lmn", "ijk"},
{"aho", "baka", "shine"}
},
...
...
};
は無理ですよね?
ってことです。

594 :
馬鹿には無理

595 :
馬鹿ばっかだな。
**、が何示してるか分からないだろ。

596 :
>>593
二次元配列へのポインタを[]を使わないで書けるようにまずはなれ

597 :
>>71
> ">私のささやかな経験から言わせてもらうと、伝統的に大学のコンピュータ
> サイエンスのカリキュラムで教えられているもので、多くの人がうまく理解
> できないものが2つあった: ポインタと再帰だ。
> "
なんか再帰が苦手だったというか、最初ハノイの塔とかでも自分で自分を呼ぶというのが
どうもよくわからなくて苦労したが、同じ名前の関数を呼ぶと考えたらあっさり理解できたな
初心者の頃。
でもトレースするのはやっぱり苦手。

598 :
>>597
自分で自分を呼ぶと考えるからややこしいんだよ。
例えば階乗なんてこれだけだ。
自然数nの階乗とは:
nが0か1の場合、1
そうでない場合、n-1の階乗にnをかけた結果
これをCでそのまま書くだけ。
unsigned factrial(unsigned n)
{
if (n == 0 || n == 1) return 1;
return factrial(n - 1) * n;
}
ハノイの塔だろうがフィボナッチ数列だろうがツリー探索だろうがみんなこれの応用だ。
なんなら解説してもいいけど、ここではスレ違いだな。

599 :
すみません
末尾再帰は単純なループに置き換え可能だそうですが
>>598 はどうなりますか?

600 :
>>599
考え方をちょっと変える必要がある。
>自然数nの階乗とは:
>nが0か1の場合、1
>そうでない場合、n-1の階乗にnをかけた結果
ここで、n-1の階乗を返す関数の代わりにn-1の階乗にnをかけた結果を返す関数を用意する。
unsigned fact_sub(unsigned n, unsigned r)
{
if (n == 0 || n == 1) return r; // 0! * r or 1! * r
return fact_sub(n - 1, n * r); // (n-1)! * r
}
これを呼ぶように>598を書き換える。
unsigned factrial(unsigned n)
{
return fact_sub(n, 1);
}
C++なら、unsigned factrial(unsigned n, unsigned r = 1)としてしまえば一関数で済む。
尤も、こんなことするまでもなく最近のgccは>598をループに書き換えるけどね。

601 :
再帰は自分自身を呼び出したとき、関数の最初に戻るのではなく
呼び出したところに関数と同じ内容のブロックがあり、
それが延々と続いてるとイメージすれば分かりやすい
それはまさにツリーと同じ構造だ

602 :
なるほど、そういう馬鹿げた置き換えイメージを持っているから、実際に
再帰で書けと言っても書けない奴が多いのか、再帰のロジックを読める
くせに書けない奴が多い理由がわかった。

603 :
そういう書けない人には
「まずuntilループに書き換える」
「ループ内で再代入する変数は全て引数として渡す」
って2点を教えてやれ

604 :
またいつもの再帰番長か。

605 :
アセンブラやらないからだよ

606 :
末尾最適化が出来る再帰と出来ない再帰があるな
例えばアッカーマン関数は末尾最適化出来ない

607 :

ttp://kmaebashi.com/programmer/pointer.html
>K&Rによれば、Cの宣言は、「変数が現われ得る式の構文を真似た(P.114)」そうである。
>しかし、本質的に全く異なるものを無理に似せようとしたため、
>結局わけのわからない構文になってしまっている。
># Cの作者Dennis Ritchieが最近開発した新しい言語 Limboは、一見
># C like だが、宣言の構文はしっかりPascal風のものに直してある...
># ずるい(^^;

608 :
変数宣言の*と、デリファレンスの*で混乱したのを思い出すわ。
同じ*だと思っていたからどうにも理解できなかったわ。

609 :
もしもポインタの*が後置きだったら……
前置版 → 後置版
int *p; → int p*;
int (*p)[99]; → int p*[99];
int *p[99]; → int p[99]*;
int *(**p[5])[3][2]; → int p[5]**[3][2]*;
int (*pf)(void) → int pf*(void);
int (*(*(*(*pf)[5])(void))(void))[3]; → int pf*[5]*(void)*(void)*[3];
結果:
後置版はカッコを付けなくても一意的に意味がつくので、
宣言がすっきりする
後置版の方が本来は読みやすいはずだが、今のところ、
個人的にはかえって読みにくい(「*p」表記に毒されてしまったのか^p^)

610 :
宣言の読み易さはともかく、それは実行コーディングの使い易さ・読み易さと
両立できるのか?

611 :
掛け算との使い分けは?

612 :
>>610
使い易さ・読み易さが格段に落ちることは無いと思う
ポインタpに対して、(*p)という記述を自発的に封印して
p[0]という記述に統一した場面を想像すればいい
この場合、実行コーディングの使い易さ・読み易さが
格段に落ちることは無いよね
(*seito).kokugo = 100; → seito[0].kokugo = 100;
*(*hoge).(*fuga) = NULL; → hoge[0].fuga[0][0] = NULL;
後置版の場合、(*p) が p* に置き換わるだけだから、これは
*p が p[0] に置き換わったのと同じことで、やっぱり
使い易さ・読み易さが格段に落ちることは無いのでは?
(*seito).kokugo = 100; → seito*.kokugo = 100;
*(*hoge).(*fuga) = NULL; → hoge*.fuga** = NULL;

613 :
>>611
p* = 10; と p *= 10; の区別が紛らわしいって話だよね
それは別の記号を使えばいいだけでは…
ポインタの「*」には、*のかわりに@を使うことにする、とか
p@ = 10; p *= 10;

614 :
玉突き衝突的にあちこちいじりまくるなら
そのままでよさそうだな

615 :
>>614
弄りまくるも何も、文法的には何も弄ってないのだが…
仮に弄っているように見えたとしても、>>612-613で全て完結してる
(*p) のかわりに p[0] を使う文法は、今のままのC言語で普通に使える。
後置版を考えるというのは、「全ての(*p) を p[0] に統一しましょう」
と言っているのと同じことで、実は何も弄ってないでしょ?
( (*p)は前置き表現なのに対し、p[0]は後置き表現 )
ただ、それなら「p*」とか「p@」とか書かないで
「p[0]」でいいじゃんって話になるなw

616 :
メタやメタメタな話をすると速攻思考が固まる人がいるけど
ポインタもその類の気がする。

617 :
つまり、アリス以下なんだな。

618 :
>>609では前置版とか後置版とか書いたけど、実行コーディングのときは
p[0]っていう後置版が存在してるから、わざわざp* などという後置版を
新設する意味は無かった。単にp[0]を使えばよいのだった

ならば、宣言時にもp[0]を拝借して、「int p[0];」を
ポインタの宣言として使ったらどうか?
今のC言語では、「int p[0];」という宣言は使われてない(コンパイラに怒られる)。
従って、この宣言に何か意味をつけて使用しても、問題は起きない

619 :
使用例
int *p; → int p[0];
int (*p)[99]; → int p[0][99];
int *p[99]; → int p[99][0];
int *(**p[5])[3][2]; → int p[5][0][0][3][2][0];
int (*pf)(void) → int pf[0](void);
int (*(*(*(*pf)[5])(void))(void))[3]; → int pf[0][5][0](void)[0](void)[0][3];

なんか微妙だ^p^
配列との区別がつきにくい…
宣言自体は読みやすい(先頭のintを無視すれば、左から右へ英語読みできる)のだが

620 :
             ___________
     ∧_∧∩ /先生!土曜日の早朝にそんなこと
    ( ´∀`)/< 考えるだけでなく、書込までするのは
 _ / /   /   \あまりにも不毛だと思います!
\⊂ノ ̄ ̄ ̄ ̄\   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ||\        \
 ||\|| ̄ ̄ ̄ ̄ ̄||
 ||  || ̄ ̄ ̄ ̄ ̄||
    .||          ||

621 :
>>620
懐かしいAAまで使って凝ってるなw
そんなお前の方がよっぽど不毛だわ

622 :
表記も分かりにくいけど
最大の問題点はC言語やそのライブラリが
ポインタ酷使し過ぎなことだと思う
・参照型が使える
・参照渡しが使える
・文字列は、基本型もしくは構造体である
・配列は明示しない限り範囲外アクセス不可
始めからこのくらいやれば
半端な知識の人間がポインタに触れることはまずなかったはずだし
本当にアドレスを扱いたいとき以外ポインタ使わなかったろうから
うっかりさんが大量発生することもなかっただろう
C/C++以外にも確かDelphiとかポインタあるはずだが
あんまりポインタで詰まるのを聞かない
それは本当に滅多に使わないからだと思う

623 :
しかし、それをやったらCが何の為に作られたかがボケてしまう。
アセンブラの代わりに使える低水準言語でなくなる事は、本末転倒だと思う。
Cをそのように使いたいなら、C++でお茶を濁せばいいだけだと思う。

624 :
参照こそイラン。
参照なんて結局んところ、[]演算子のオーバーロード時に使いたいだけちゃうんかと。
MyData &operator[](foo f)して、mydata[bar][baz]させたいだけちゃうんかと。

625 :
>>623
いや、当然C言語なんだから低水準なものは扱えるべきだよ。
何もポインタ自体を廃止しろと言ってるワケじゃない。
ポインタに依存するものが多過ぎるでしょ、って話。

626 :
配列参照だとインデックスが必要
速度を上げるためのポインタ参照だから

627 :
Cが特定の人々にとって分かりにくいのは確かだけど
別にシステムプログラミング用途で不合理、不適合ってわけじゃないからな。
変えろとか言われても知らんがな。

628 :
つまりシステムプログラミング以外をする人は全部「特定の人々」なのか
実際は何故かプログラミングの教材にすら使われる言語なのだが

629 :
だからEasy Cだかなんだか好きな言語でっちあげろよ
ごね方が謎過ぎる

630 :
Joel氏の言う通り、この程度が理解できないならこの仕事するなって事だな

631 :
つまりアレだな、スレタイに対する回答は
「高級言語でもないものを、高級言語であるかのように扱ったから」
だな

632 :
>>631 もともと高級アセンブラだ

633 :
実際には色んなところで使われちゃうから、そこが問題点

634 :
引っ掛かる人間の割合は、さほど変わっていないと思う。
先天的に才能がない人間も、プログラミングをするようになっただけなんじゃね?

635 :
先天的に才能が無い人間がいきなりCに触っちゃう機会があること自体がおかしい

636 :
Cってかっこいいの?

637 :
C△

638 :
Cが駄目ならGoを使えばいいじゃない。

639 :
これ ; デリミタっていうんだけどさ、これをつけなきゃエラーになるような
そんな言語使ってる奴ってどうみてもゴミだと思うんだけど
もしかして「;」これ打ち忘れてコンパイルエラー出すのが楽しいの?
そうか、二度と話かけんなよ
ゴミは何いってもゴミ

640 :
天使ちゃんマジ天使

641 :
∨∨∨
「「「「「 つまりアレだな、スレタイに対する回答は 」」」」」(キリ
∧∧∧∧∧∧∧∧∧∧(きリッッ!キリッッッッ!!きリッ!!!キリッッッッ!!!!

「「「「「 「高級言語でもないものを、高級言語であるかのように扱ったから」 」」」」」(←きリッッッ!!!!キリッッ!!!!
∧∧∧(キリ!!

642 :
ポインタなんて出来るだけ使わなければ良い。
Cが出た頃の昔はポインタで高効率とかあったけど、
今のコンパイラなら最適化が優れてるから
無理に使う必要ない。
ワザと判り難いプログラミングの手本見て、
真似するとか低脳な教え手から習うなよw
コンパイラがショボかった昔の技法なんだよ。

643 :
クソ本が巷に溢れてるのが悪い

644 :
>>20
sizeof(b)=8;
になるのは何で?bはint型だから4じゃないの?

645 :
すくなくともintじゃなくて
int *だわな。

646 :
アドレッシングが64BITの環境かもしれんし。

647 :
ポインタの理解に苦しむこと30年、その間書籍も20冊以上買ったが
全くモノにならなかった。
しかしついさっき、ようやく、ようやく開眼した。
ポインタ変数と、それが指し示すデータの実体を
同じメモリの中で考えるから位置関係が気になって混乱する。
メモリが一つで一直線にあるのではなく、
データ専用のメモリと、ポインタ専用のメモリが別々にあると
考えて、二つを並べることで理解できた。
つまり地面にメモリが二本垂直に突き立っているイメージ。
右のメモリにはデータがあり、
左のメモリにはポインタ変数があって右のメモリのアドレスを指している。
ポインタのポインタなら、三本めのメモリが立っていて
真ん中のメモリのアドレスを指している。
こんな簡単なことだったんだ。
人生が開けた感じ。とても清々しい気持ちだ。
次は構造体を頑張るぞ。

648 :
ポインタをインクリメントしてデータを破壊しても、原因が理解できなかったりw
30年もかかるんなら、プログラマに向いてねぇよ

649 :
ダメだこりゃ。

650 :
アドレスって名前はダテでは無いんだけどなー。
>>647の頭の中ではMapみたいにkey領域とvalue領域があるのかなー・・・。

651 :
人が人生のすばらしさに目覚めて感動しているのに
相変わらず君らはレベルの低いレスを付けるのだな。
ポインタで引っかかる人は、みな私のように
頭の中にメモリのイメージを作れずに苦労しているのだよ。
二段メモリの概念は素晴らしい。これでポインタの本を書けるかも。
私を30年も苦労させたリッチーを、卒業祝いに一発殴りたいところだが
亡くなったそうだからチャラにしてやる。
これからはプログラムを作りまくるぞー。

652 :
いや30年わからないってそれ明らかに向いてないから

653 :
俺の理解だと int *hoge; の場合、宣言してるのはhogeという変数。
*をつけると変数の中身をアドレスにしてアクセスする。アクセス先の型はintとする。
最初に*hogeはint型だが、*を外したらアドレスになる、と覚えようとしたら混乱した。

654 :
>>653
そこで多段メモリですよ。
以下のようにイメージすれば、ポインタなんて簡単だ。
先にも言ったとおり、初心者がポインタでつまづくのは、
リニアなメモリの中にデータとポインタが混在したイメージを
頭の中で処理しきれないから。
だったら、処理しやすいイメージに変えてしまえば良い。
実際のメモリ配置がコンパイラの実装に依存する以上、
このイメージが決定的にまずいということはないはず。
1.右のメモリにはデータがある
2.真ん中のメモリには1へのポインタ変数がある
3.左のメモリには2へのポインタ変数がある
4.ポインタ変数に付く*の数は、その変数のあるメモリの
何段前のメモリを見に行くかを示すものである

655 :
リンクドリストは要素の数だけメモリがあるのか。大変だな。

656 :
多段メモリ革命あげ

657 :
ポインタで躓く人って、再帰とかでもつまずくの?ポインタがわからない理由もわからないが、再帰が難しいとされる理由もわからんわ。
モナドとか理解できんのかね?

658 :
相関はあるかもしれないけれど、一致はしないよ。
ばりばりに書いているエンジニアで再帰がよく判っていない奴がしばしば居るし、
ポインタをイメージできないのに再帰を使いたがる奴が少なくとも一人居たし。

659 :
再起は段数が読めてないとスタックオーバーフローするからなー。
ポインタはホントにメモリの一点をポイントしてるだけなんだがねぇ。
そこに自分用の領域が有るかはわからんけどさ〜。

660 :
再起が難しいと言う奴が躓くのはスタックとかそういう次元じゃないだろう

661 :
※文系出身の方も多数活躍しています


662 :
読書をしない技術系の人は覚えが悪い
読解力が無いので

663 :

そもそも、ポインタの概念自体が古いから。  END。

いくら元になっているつっても、もうC言語自体古いし、使う技術者も古い。
いまどき使ってるのはサポート系の企業でしかないよ。覚える必要はない。
もう現場ではC言語は業界標準ではない。今はPHPとRubyとJavaだけ覚えていればそれ以外の言語は不要。

664 :
それはないな。
ポインタ知らないとドライバすら書けん。

665 :
>>663
Java の new にあたるのは ruby や PHP では何?

666 :
RubyはClass#newじゃないの、PHPは知らんが

667 :
PHPは普通にC++ライクなnewできたと思う。

668 :
10年以上メンテされ続けるシステムとか見てれば
ありがたみが分かるよ

669 :
逆参照だの参照外しだの言われても初心者は分からんだろ。

670 :
ポインタの参照とかね、もう
そういやどこぞで間違えた奴がいたね。

671 :
結論: ポインタとはメモリーアドレスである

672 :
否!
ポインタとは、メモリの一点を指し示すための変数である。(ドヤッ

673 :
否!
ポインタとは、ある形をした入れ物に入れるための、その空間とぴったり同じ形をしたもののことだ。

674 :
>>673
底が抜けてるんですね。わかります。

675 :
ポインタはきもちいい

676 :
Javaとかやってると、素直にプリミティブ型へのポインタが欲しくなるのも事実。

677 :
Java ってどっちからというと既存のコンポーネントを結びつけるグルー言語であり、二分木だのりストだのの構造そのものを記述するにはちょっと力不足なんだね。
苦吟苦心したのだがこれが精一杯。http://toro.2ch.net/test/read.cgi/tech/1344350210/292

678 :
ポインタ解説で炎上
http://builder.japan.zdnet.com/sp/c-programming-language/story/0,3800083430,20370255,00.htm

679 :
>>678
もう4年も前だし。その連載、今思い出したけどポインタに限らず間違いだらけでどうしようもなかった。

680 :
5年になるが‥‥忘れてもらえないのか‥‥
エピさん大活躍、C++やテンプレートの人かと思ってましたが

681 :
エピたんはC++の大御所ですから。
あの企画、編集サイドの都合があるからだろうけど、没にしない限り筆者は赤っ恥晒したまんまだね。

682 :
ホントにコンパイル試さなかったのかね?

683 :
>>678
http://s04.megalodon.jp/2008-0328-1941-14/builder.japan.zdnet.com/sp/c-programming-language/story/0,3800083430,20370255,00.htm

684 :
>>681
でもエピさんの本は、まだよくわからないんだ‥‥。

685 :
エピタフ

686 :
「ポインタはメモリ上のアドレス」みたいな表現に対して、
すべてがメモリ上とは限らない、単にレジスタである場合もある、みたいな反論を聞いたことがある。

687 :
だから?としか言いようがない的外れな反論

688 :
>>686
そういやregister変数に対してポインタ取ったらどういう形にコンパイルされるのかって規格で決まってるのかな?

689 :
>>688
レジスタ変数のアドレスは取れると規格で決まってる

690 :
>>689
§6.5.3.2 Address and indirection operators
Constraints
1 The operand of the unary & operator shall be either a function designator, the result of a
[] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
not declared with the register storage-class specifier.
これはどう訳すべきか

691 :
>>690
function designator ってなんだろう?

692 :
>>689
Cではill、C++ではwell

693 :
C++ではもはやレジスタ変数は意味がほとんどなくなってるという事だな
規格を探すと
5.3.1 Unary operators [expr.unary.op]
2 The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue
or a qualifiedid. In the first case, if the type of the expression is “T,” the type of the result is
“pointer to T.” In particular, the address of an object of type “cv T” is “pointer to cv T,” with
the same cv-qualifiers. For a qualified-id, if the member is a static member of type “T”,
the type of the result is plain “pointer to T.” If the member is a nonstatic member of class C
of type T, the type of the result is “pointer to member of class C of type T.”
これでC99と違って特にregisterに言及してない辺りなのかなあ
>>691
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Flvalue.htm
これの「関数指定子」って奴か?
JISのもあるけど読んでも意味わからん

694 :
ポインタは、どこも指していないことがある。
ポインタは生成されたが、まだ値が代入されていない。
値が代入された場合、ポインタが指しているデータは、削除されるかもしれない。
削除されても、ポインタに通知されない。
ポインタに値が代入されることで、以前、指していたデータを見失う。

695 :
「なぜ引っかかるか」
入門書にも間違いが多いからかな

696 :
「指す」だのなんだの言うからおかしいんだよな。
アドレスと、アドレス操作だけの話なのに。

697 :
アセンブラの経験ないと、その概念が理解できない罠

698 :
int *n;
*n = 5;

699 :
>>698
貴方のPCは死にました。

700 :
ダングリングポインタでぐぐるとわかる

701 :
temp = *pointer + 1;は、pointerに格納されている値(ここではtestのアドレスである101)に
1を足すという命令になります。それによってtempに格納される値は102になります。
http://wizardbible.org/31/31.txt
???

702 :
>>701
ふぇー ひどいサイトだなこりゃ

703 :
>>701
当たり前だろ
*pointer だから pointerの指す値を取り出して +1 してるだけなんだから

704 :
>>701は(*pointer)っていう値に+1してtempに代入してる。
(pointer)は変数testのアドレスを指してるので(*pointer)の中身はtestである。
んで、(*pointer)=2600ってしてるので、その瞬間にtestは2600になる。
(*pointer)+1をtempに代入しているので、tempは2601になる。
アドレスをいじる要素はないね。

705 :
ポインタ厨発生源発見!

706 :
ポインタとアドレスを混同してるバカがまだいるな。

707 :
くやしかったらアドレス以外でポインタ実装してみろ

708 :
実装がアドレスだと言ってるバカも未だに存在するんだな。

709 :
高2病っているんだな。

710 :
変数定義時につく*と、式の中に出てくる単項演算子*の関係を考えちゃうと混乱する。
俺も考えると、一番最初はそれで悩んだ覚えあり。
今は、いかなる解釈も考えないようにしている。

711 :
今月からCを勉強し始めた者です。ポインタも何となく分かったつもりだった
のですが、2次元配列(配列の配列)のところでワケわかめになってますorz
int a[3][3] = { {10,20,30,}, {40,50,60}, {70,80,90} };
このような配列を宣言した場合、
 @ &a
 A a
 B *a (または a[0])
これらのアドレスはみな同じになります。 全部違う意味をもつということは
漠然とは分かるのですが、@〜Bが具体的に何を意味しているのか、自分
では説明できません(今使っている入門書籍でもこれらの違いについては
記述がありません)。
たぶん、これが理解できていないと、配列のアドレス情報を関数へ渡したり、
他のポインタ変数へ渡す時に困ると思うのですが・・・。
アホな私でも分かるように説明して頂けないでしょうか?

712 :
>>711
->* を理解するまでに半万年かかりそうだなw

713 :
int (*b)[3][3] = &a;
int *c = *a;

714 :
>>712
初心者にも分かるように説明してやれ
それが出来ないなら、お前も同じレベルということだw

715 :
初心者に説明する必要はない
金払えと思う

716 :
俺もよーわからん。 教えてケレ

717 :
「憲法改正」は総選挙の争点になるか
安倍さんは「強い日本」「美しい日本」にしたいということで、まずは憲法9条の改正を目指す。
総裁選も盛り上がり、自民党が一気に国民の期待を集めている。
勢いに乗る安倍晋三総裁は、次期衆院選で憲法改正を争点のひとつにする意向を示している。
詳細 2012/10/21
http://www.zakzak.co.jp/society/politics/news/20121021/plt1210210709000-n1.htm

718 :
>711
int a[3][3] = { {10,20,30,}, {40,50,60}, {70,80,90} };
このような配列を宣言した場合、
 @ &a
 A a
 B *a (または a[0])
これで違いが出る理由について考えて見てはどうですか?
http://codepad.org/TGTgwWBK

719 :
http://codepad.org/0zmpInax
よく考えたら配列に+1するようなことってあまり意識したことがなかったな。

720 :
>>718
どうもご親切に有難うございます。
おっしゃるように、それぞれをインクリメントした場合のアドレスの増分
を確認してみました。
 @ &a : 0x24 = 36 バイト → 2次元配列全体のサイズ(3x3x4)
 A a : 0xC = 12 バイト → サブ配列( {10,20,30} )のサイズ(3x4)
 B *a : 0x4 = 4 バイト → サブ配列の要素(int)のサイズ(4)
( a[0]は*aと同じ)
これからいえる事は、
 @は、この2次元配列(配列の配列)をひとかたまり(?)として捉えた場合の先頭アドレス
 Aは、その中のサブ配列をそれぞれひとかたまりとして捉えた場合の先頭配列の先頭アドレス
 Bは、その先頭のサブ配列の中の先頭要素(int)のアドレス
用語が適切かどうかは別として、理解の仕方としては正しいのでしょうか?
それから、これらのアドレス(あるいはポインタ)を使って配列の中の要素を参照する場合、
AとBは使えるけれども、@はスケールが大きすぎて(?)使えない、ということになりますね?
>>719 さんも有難うございます。

721 :
全部の要素を一度に上書きとかなら(1)もあり

722 :
Javaはポインターが見えなくしていると本に書いてあった
それがJavaの理解をさまたげているらしい。


723 :
int *p,i;
i=123;
p=&i;
*p;
pはiのアドレス *pには123が
int *p;と*pは別物でしょうか?

724 :
int *p; pはポインタですよ宣言
*p はポインタpの指してる先の内容をくださいな
「*p」という同じ記号列だけど意味が違う

725 :
Java はポインタがないはずなのに
ぬるぽが多発するよね

726 :
>>724
どうもありがとう
なんかここだへんがまぎらわしい

727 :
int *p; 「*pはintですよ」
って考える方がまぎらわしくなくていいと思う。
初期化だけは注意が必要だけど。
int *p = hoge; 「*pはintですよ。ただしpはhogeにしといてね。」

728 :
int* pの方が好き。宣言してるのは変数pであって*pじゃないし。

729 :
int (*p)(void);
みたいなのはどうする?

730 :
int p, q;
q*p;
同じ *p という列でもこの例だと掛け算。 * という記号は状況によって意味がいろいろあるの

731 :
それはまずいっしょ

732 :
hoge *a[];
とか
hoge (*a)[];
とか
優先順位が判らんくて混乱する

733 :
pはint*という型は宣言していると考えればわかりやすいですか
ところでc言語って20年ぐらい続いているんだよな
その前がpascala,fortranとかこの二つの言語はどうなっている?
なんかプログラム自動的に書くツールができてPG,SEは減りそうなんだよな

734 :
>pはint*という型は宣言している
日本語でどうぞ。
>ところでc言語って20年ぐらい続いている
は?
>pascala
そんなものありません。
>なんかプログラム自動的に書くツールができてPG,SEは減りそうなんだよな
日本語でどうぞ。
まぁ、「プログラムを自動的に生成」できたとして、それを行なう為にSEは必要だね。

735 :
C言語が続いているのはハード寄りのプログラムが書けるからなんだが
それはunixというOSを書いた名残でそういう言語仕様になっている。
そのハードウェアよりのプログラムのところがポインタなんだよな
C言語自体は進化しているか分からないが、発展したのにC++という言語があるけど
元のCもつかわれている。
自分のことでもうしわけないが、組み込みの勉強をしようとポリテクに申し込んだら
落ちた。多分若者優先だったかも
ハードウェアよりのC言語を勉強するとJavaの理解もはやいと思う。

736 :
>>729
そこなんだよな。
普通の変数を 「型名 変数名 (= 初期値);」 で一般化して覚えてると
ポインタが絡んできた途端に頭の中のルールが混乱する。

737 :
>>729
自分で書くときはtypedefしとけ。

738 :
>>736
pascala->pascalですよ
>ところでc言語って20年ぐらい続いているよ
バブル崩壊あたりからあるよ
Javaは2000年あたりに知った。
pはint*というintのポイント型を宣言している
ただ上流工程のSEだけ生き残ってあとは減りそうだけどな
人海戦術から自動化していきそうだけどな

739 :
>>736-> >>734
C言語は他の言語より長く使われていることは確か

740 :
>>738
とっくの昔から自動化できる部分はじゃんじゃん自動化してる。
ITなんて自動化の固まりじゃん。
何が自動化できてないって?

741 :
Cが長く使われているのは、ポインタがあることなんだろうけどね
危険性が高いのものも同上

742 :
それだけだとポインタの無い言語も長く使われている理由が説明出来ない

743 :
型情報とポインタ情報をわざわざ別階層であつかえるんだから、
int *a, **b, c, ***d; こう書けるようにしてくれてるんだから、
int* a;
int** b;
int c;
int ***d;
などと書く必要性をまったく感じない。

744 :
見やすさだろ
int* func(); の方が int *func(); より見やすいとかその程度の理由

745 :
int p; を「int型の変数p」と訳すから混乱する。「トークンpはint型の数値を返す」と読めば
int *p; は「トークン*pはint型の数値を返す」
int (*p)(void);は「トークン(*p)(void)はint型の数値を返す」
と統一的に読める。でも直感的では無い。

746 :
どう見やすいのかサッパリわからんがw

747 :
int *a と書くのはCな人
int* a と書くのはC++な人
int * a と書くのは変な人
と習った。
そーいうもんかと思い、以後Cで書く場合はint *a、C++で書くときはint* aと書くことにしている

748 :
あ、挟まっちゃった。
>>746>>744へのレスね。一応。

749 :
C++ならこんなんもあるね
int & a

750 :
bool function(std::string & a);

751 :
関係ないが、
int* p; と書くのは許せるが、
INT _tmain(INT iArgumentCount, LPTSTR *lppszArgumentVariables, LPTSTR lpszEnvironmentVariables)
と書いた奴は許せない。

752 :
システムハンガリアンが許せないの?
argc, argvをぐだぐだにしてるのが許せないの?
LPTSTR *こういう使い方が許せないの? もっとシンプルにconst TCHAR **としないから許せないの?

753 :
mainの第2第3引数はconstじゃねーぞ。
俺はchar *argv[]の書き方が好みだ。
何故なら、char型へのポインタの配列だからだ。

754 :
仮引数での配列の宣言なんて何が嬉しいのかわからんな。
ポインタで受け取ってるだけであって配列ではないのだから。

755 :
二次元以上だと、またかわってくる

756 :
単一の要素へのポインタ(で副作用期待)なのか、
配列なのか、
表記で分けて読みやすくするのがいいかと。
何ごとも読みやすさ優先。by リーダブルコード

757 :
副作用の有無はconstで表現すれば十分じゃね?

758 :
副作用はどっちでもいいや。
単一なのか配列なのか区別するのに * と [] を使い分ければいいんじゃねってこと。
文字列操作のライブラリは軒並char *だから完全に統一とか無理だけど。

759 :
可読性と伝統と芸術性は重要だな。

760 :
実体1個のポインタ
実体は配列の先頭 終端は別途もらうか、約束事の番人で打ち切るまでにするか

761 :
参照渡し

762 :
マロックを使い出してから余裕になったわ

763 :
カロックもいいよね

764 :
リーロック最強

765 :
alloca 海峡

766 :
// realloc()の実装例
void * realloc(void * allocated, size_t size)
{
void * ptr = NULL;
if (size) {
ptr = malloc(size);
if (ptr == NULL) return NULL;
if (allocated) memcpy(ptr, allocated, size);
}
free(allocated);
return ptr;
}
#if 0
最強って言ってもそれだけではなんもできない子。
#endif

767 :
>>766のレスをした意図がまったく見えない

768 :
>>766
ptrの宣言位置がムカつく

769 :
reallocの仕様を理解していないばかりか、mallocで実装するバカ。晒しage

770 :
>>769
ほほぉ、では手本を一つ宜しく。

771 :
reallocなんて使った事ないね。

772 :
new/deleteとVirtualAllocとHeapAllocしか使わない。
そもそも、再アロケートが発生するような設計などしない。

773 :
>766 >770
見てると眠くなるコードだったので書き直した
void *realloc(void *allocated, size_t size)
{
if(size){
if(!(void *ptr = malloc(size))) return ptr;
if(allocated){
memcpy(ptr, allocated, size);
free(allocated);
}
return ptr;
}
return allocated;
}

774 :
if の () の前後はスペース空けろや

775 :
読めない奴が悪い

776 :
ptrのスコープが狭すぎる気がするんだが
そもそも初期化は式なのか

777 :
C++なら通るコード

778 :
sizeに0渡した時にfreeしてないバカ。晒しage

779 :
Cのポインタは可読性がゴミ

780 :
C++の「配列の参照」は知らないと呪文コードだな

781 :
ポインタを!演算子でチェックしてるけど、まさか、C++で使うコードじゃないよな?

782 :
>773
そもそもこれ標準ライブラリ関数のreallocと動作違うし

783 :
リーロック人気だな

784 :
mallocの実装が return realloc(NULL, size); でも構わないが、reallocの中でmallocを呼び出すことは決して有り得ない。

785 :
>>784
それは振る舞いが同等であればよいというだけの話。
規格は実装を規定しない。

786 :
frontalloc

787 :
>>781
6.5.3.3 Unary arithmetic operators ぐらい読んでから喋れ

788 :
>>787
バカ発見w

789 :
メモリのアドレスが、
1、2、3ではなく
甲、乙、丙、だったらどうなのか???
ポインタはアドレス「甲」を指す。

790 :
欧米の住所(アドレス)は、数字だけだからいいが
日本の住所(アドレス)は、漢字プラス数字だから、比喩として成り立ってない。

791 :
>>790
>欧米の住所(アドレス)は、数字だけだから
本当か?

792 :
>>766
の発言の意図がわからんw
何を狙って書いたの?w
> 最強って言ってもそれだけではなんもできない子。
これだけでも良いから説明してほしい。

793 :
>785
malloc が realloc 呼んでたらどうすんの?

794 :
mallocとreallocは同じstdlib提供者が実装するんだからそいつの責任だろ

795 :
const char const * const * const p const;

796 :2012/11/02
>>793
どうかなんのか?どうもしないだろ
TOP カテ一覧 スレ一覧 2ch元 削除依頼
【bzr】Bazaarでバージョン管理 Rev 3 (958)
くだすれC++/CLI(初心者用)part2 (614)
OpenGLスレ Part18 (925)
VB.NET質問スレ(Part39) (362)
新言語を開発したい (290)
OpenMPプログラミング (388)
--log9.info------------------
エロブタ【FKESHO】ジミブス (242)
ニフティーADSLが繋がらない (954)
niftyのhomepage2のcgi故障している (483)
そろそろPC-VANについて語ろうじゃないか (808)
ニフ板名誉毀損で第三者Rを呼びかけます (503)
FMHって・・・ (230)
鬼畜3兄弟 (461)
あぽーん (370)
FLOVET (278)
NIFTY板の廃止を申請します (384)
ニフティ鉄道フォーラム (211)
【どこまで続くぬかるみぞ】泥沼 Part6 (230)
こんにちは現役SYSOPです。 (335)
迷惑メールフォルダーについて Part3 (719)
サポートセンターいつになったら繋がるの? (358)
むしずが、はしるんですけど (392)
--log55.com------------------
【川田】火ノ丸相撲【117場所】
【尼サクラレビュー】約束のネバーランド52【掲載順操作】
【名探偵コナン】警察学校編 -Wild Police Story-【警察学校組】
週刊少年サンデー総合スレッド344冊目【好調出入禁止】
【栗山ミヅキ】保安官エヴァンスの嘘 11発目【サンデー】
【ハゼレナ】ミタマセキュ霊ティ2 【鳩胸つるん】
【ミウラタダヒロ】 ゆらぎ荘の幽奈さん 【56泊目】
Dr.STONE(ドクターストーン) ネタバレスレ Part12