ポインタの説明をしてみて初めて解かる難しさ

このエントリーをはてなブックマークに追加
1プロだよ
お前らポインタという物を初心者にも
解かるように説明しやがりください。

これが意外と苦労するんだなw
3デフォルトの名無しさん:04/05/19 17:47


│ ∧_∧ 
↓ ( ・ω・ )
■p⊂  と )
   (_(_ろ
   /⌒ヽ
  / ´_ゝ`) すいません、道に迷いましたよ・・・
  |    /    
  | /| |
  // | |
 U  .U
5デフォルトの名無しさん:04/05/19 17:47
俺はポインタが分からないという人が分からなかったが、劣化ウランが体に悪いのかどうか分からないのが分かってその気持ちがはじめて分かった
ポインタとは、ポインタである
qed
7プロだよ:04/05/19 17:50
噛み砕いて吐いて飲んだのを戻してすり潰したつもりの
説明でも (・ω・)ホエー ってして居やがります
実はポインタは現実的なプログラムに触れながら学んだ方が分かり易い。
漏れはOllydbgでクラックしながら覚えた
10デフォルトの名無しさん:04/05/19 18:49
>>8
でも、C,C++使いとかでないとポインタっていらないんじゃない?
当方++つかいだが。++でも普段はポインタだとか気にせんぞ。
インスタンスはほとんど参照カウンタつきポインタ任せ
ぬるポインター
01234567
□◆□□□□□□
 ↑P=1
  *P=◆

 ポインタのイメージ。矢印がポインタ。

 ポインタはメモリ上のアドレスを格納する変数。
よって、ポインタそのものに格納できる値は4byte(宣言時の型は、
ポインタを当てた変数を何型として扱うかと言うだけの話で、
long型の変数にchar型のポインタを当てて1Byte単位で扱う事も可能)。
 そして、アスタリスク(*)はポインタに格納された
値を操作するための修飾子。

早い話が、デスクトップとかにおいてあるショートカットアイコンが、
ポインタで、ショートカットの先にあるファイルが本来の変数or配列ってことだろ?
(説明はやっぱむりポ)
マジレスすると・・・

ヘネパタとパタヘネ(どっちがどっちだ?)を読ませる。
今使ってるコンピュータのCPUのマニュアルを読ませる。
とりあえずアセンブラで何か書かせる。
ANSI Cで何か書かせて、コンパイラでアセンブラの出力を吐かせて、読ませる。
ANSI Cの仕様書を読ませ、それぞれどんなコードを生成するのか確認させる。

以上。

必要なことを示さずに煙を巻くような説明の解説書を読むより確実。
14デフォルトの名無しさん:04/05/19 20:16
ポインタが分かる人には
ポインタが分からない人の
気持ちなんかわからない。
C初心者本によくあるような、
int n = 10;
int *p = &n;
printf("%d", *p);
こんなことちまちまやってても分かるわけない。分かる必要もない。

それより、どんどんコード書いていって、ライブラリなんかで、
どっかにごっついオブジェクトがあって関数fはそのポインタを返すとあったら、
O *p = f();
とし、
p->m;
これさえ分かれば、あとは勝手に理解できる。
>>1
やだ、2chでポインタとか配列とかについてぶつと、
なんかキチ○イが、どーでもいいことで粘着してくるから。
17デフォルトの名無しさん:04/05/19 20:58
ポインタそのものの概念は>>12の通りでそんなに難しくないと思うよ。

難しいのは、関数のパラメータとアーギュメントに、プリミティブタイプの変数
を使ったり、ポインタの変数を使ったり、配列を使ったり、リファレンスを
使ったり、複数の場合はそれらを混合したりして、そこら辺を初心者本が丁寧に
説明してないからだと思う。おまけにCの場合は、式の中で配列名を使用すると
先頭のポインタにコンパイラが自動的に読み替えたりするから尚更ややこしくなるのだが。
18名無し@沢村:04/05/19 21:10
ポインタを理解しているやつはいる。
だが、ポインタを初心者というか幼稚園にでもわかるように簡単な言葉で説明できるやつはいない。
初心者でも優秀なやつはすぐ理解してしまうから、この場合初心者というより幼稚園だな。
聞くところによると、どんなに難しいことも、簡単な要素に分解できるそうだ。
また人間が難しいことを理解する場合、簡単な要素に分解してから理解するそうだ。
だが、これにはおかしなことろがあるな…。
もしどんなに難しいことでも、簡単な要素に分解できて、難しいことを理解する場合簡単な要素に分解してから理解するとすれば、
どんなに難しいことでも簡単な言葉で説明できるはずだが、世の中は難しいことは理解できないやつがほとんどだ。
つまり実は難しいことは完全には簡単な要素には分解できず、難しいことを理解するには、難しいことを難しいまま理解するという処理が必要だという証明ではないかな?
どうよ?
もっともポインタなんて難しいことのうちには入らないけどね…
どうよ?

19デフォルトの名無しさん:04/05/19 21:11
ポインタの気持ちも知らないで・・・
ポインタは嫌いですが、ボインタンは好きです。
俺の上司はポインタをポンターと言います。
>>18
というか、その難しいものを分解すること自体が難しいんじゃないかな。
なにせ難しいものなんだから、どう分解すればいいのか分からないわけで。
23名無し@沢村:04/05/19 21:32
>>22
いや、理解した人はその難しいことを分解して理解したんだから、
自分が理解したとき分解したように分解すればいいのでは?
もっともこれは難しいものを分解できるという前提に立った上での話だけどね…
だからおれはその前提があやしいと言ってるんだ。
24名無し@沢村:04/05/19 21:34
この問題は、
難しいことは簡単な要素に完全に分解できるか?
それとも完全には分解できず難しいことを難しいまま理解しなければならない部分がどうしても残るか?
という問題についてスレを立てる必要がありそうだな…
ここまでで一つだけ確実なことは、>>20はバカだ、ということだな。
26名無し@沢村:04/05/19 21:48
おれは、難しいことは完全には簡単な要素に分解できず難しいことを難しいまま理解しなければならない部分がどうしても残るに一票だな。
というのは、難しいことを理解したやつに、どうしてそうなるのか聞くと、
「これはAだからBになるんだ」「わかるぞ、ふむふむ…」
「そしてここがBだからCになる」「うん、そこもわかる…」
「そいてここはCだからDになるというわけだ」「おい、そこはわかんないぞ。そこはちょっと飛躍があるんじゃないか?」
「どうしてよ?CだからDになる。簡単だろ?」
というわけで、聞いてるおれは、そのCからDになることろをもうちょっと簡単な要素に分解して説明してほしいんだが、
やつはCからDになる部分を難しいまま理解しているので、それ以上簡単に説明したくてもできないわけだ。
おまいらよ、こういうことってよくないか?
だからおれは難しいことを理解するには、難しいまま理解するということがどうしても必要だと思うな。
どうよ?
2722:04/05/19 21:53
>自分が理解したとき分解したように分解すればいいのでは?
いまは、理解できていない人がどうやれば理解できるようになるか、ってことを
言ってるんじゃないのか?理解した人に教えてもらえばいいって言いたいなら、
それはちょっとどうかと思う。その人が本当に全てを伝えられるとは限らないし、
なにより人から一方的に押し付けられた知識は身に付かない。

難しいまま理解しなければならないかどうかは、その問題の大きさによると思う。
まず、どんな問題も分解しようと思えば分解できるはず。定理は定義より導き出せる。
ただ、細かく分解していくことが絶対的な利点であるとは思えない。
問題の規模が小さい内はまだいいが、それが大きくなってくると分解することは
問題を逆に複雑化してしまうことになりかねない。


//漏れってこんな真面目なこと書けたんだな。ちょっと意外
どんな変数にもアドレスがあって
int a = 10;
という変数があるときaのアドレスは"&a"。

パソコンのメモリは"線形"にアドレスが...なんとかノイマンで
たとえばアドレスが1000あって、
その0003番地に変数aが存在するとすると
&aは0003

0001
0002
0003 ここが&a
0004
0005
....
....
1000
....で
0020番地に int型を指す int *pがあって、これに
p = &aとして、変数aのアドレスを格納すると

0003にあるaに10という値が入っていて
0020にあるpに0003というアドレスが入っているとき
"p"とだけ指定すると、出てくる値は"0003"
"&p"と指定すると、出てくる値は"0020"

*pと指定すると
0001
0002
&a+--->0003 ---> 3が出てくる
| 0004
| 0005
| ....
&p+--- 0020 ここに &pがあって
....
1000
あと、ポインタはデータ型に応じたアドレス演算の機能が...
<以下略>
[訂正]
- &a+--->0003 ---> 3が出てくる
+ &a+--->0003 ---> 10が出てくる

...ボロが出まくっているので寝ます。
変数とはメモリ空間上に確保されたデータ保存領域である。
32デフォルトの名無しさん:04/05/19 22:03
動的配列ってどうなってんの?
だんだん配列数増やしていったら、
メモリ上で連続したアドレスにちゃんとなるの?
33名無し@沢村:04/05/19 22:08
>>29
事実はint型が4バイトとすると、
0003番地から0006番地までの4バイトで0x20という整数を表すということだけだ。
&と書いたらどうなるか**と書いたらどうなるか*&と書いたらどうなるかなんてのは、構文解析の仕様の問題で、実際のメモリ上にあるデータとは無関係だ。
言語仕様にまどわされず、実際のデータだけを見れば問題は簡単だ。
>>24,26
文化人類学的命題ですね。阪大の中川先生が「高い/低いレベルの記述」という概念で
言語システム論として構築してらっしゃいます。
>>32
cのreallocのケースだが、

現在ポインタから連続確保できないときは、
確保できる場所を探し、そこにポインタを移動してから新しく領域を確保する。
今まで使っていた領域は自動的に新しい場所にコピーする。

どうしても確保出来ない場合は関数が失敗する。
(定義)
ある変数pが構文(略)によって宣言されているとき、
その変数pは型tへのポインタ変数であるとい、pの中身をポインタ値という。

以後、説明の簡単のためポインタ値がメモリのアドレスをあらわしているものとし、
メモリの構造とアドレスについて知識があるものとする。小文字は変数。

(定義) 
* : ポインタ値 -> 型tの値
函数*は(*pと使用したとき)アドレスpに型tの値が格納されているものとして
アドレスpの(pに続く)メモリの内容を解釈し、型tの値を返す。

(定義) & : 変数 -> ポインタ値 
変数xに対し&xはxの格納されているアドレスをポインタ値として返す。

(注意) C言語では通常、演算子は変数に適用されたとき
変数の中身に対して作用するが、&は変数自体に作用する。

(系) 上の二つの定義より、 合成* . & : 型tの値 -> 型tの値 
は恒等函数である。

...ポインタの演算やsizeofの定義、性質。

ポインタ=知っている何か、と翻訳できるものではない。
物事は何でも自分の既に知っているものに対応すると思い込んでいる
人にとっては難しいし、説明も難しいかもしれないが、
新しい概念(定義)のものが一言でわかるものでないのはあたりまえ。
37デフォルトの名無しさん:04/05/19 23:11
ポインタを理解する上で、一番重要なのは、なんの為にこんなモノを使うのかと言う
理由を理解する事だね。で、俺の理解してる範囲の解釈だが。
関数の定義の際にカッコ内にパラメータを指定する。で、呼び出し側では、アーギュメント
を関数に与えて(仮引数と引数とは使わない。こっちの日本語の方がややこしい。英語の
パラメータ・アーギュメントの方が分かりやすい)演算を行わせる。その際に、変数そのもの
を渡すと、コンパイラさんが、気を利かしてコピーを自動的に(勝手に)作ってそれを渡して
しまう訳だ。そして、そのコピーアーギュメントを受け取った関数の方は律儀に受け取ったコピー
で必要な演算を行い、終了すると、呼び出し側に戻る。この場合、例えば関数の中に計算結果などを
表示する処理が含まれていれば、その結果を見ることが出来る。しかしそうでない場合や、渡そうと
考えた変数を、関数で処理させて内容を変更し、その変数などに結果を格納しようとする場合には不都合となる。
値をそのまま渡したのではコピーを処理するだけで、且つコピーされたコピー変数は関数のスコープ
が終わると消滅してしまうので、元の変数に結果を格納したり、関数スコープ終了後にもその結果を
利用する事が出来ないのだ。

そこでポインタの出番となる。ポインタ変数を関数のパラメータとして指定しておき、変数のアドレス
を格納するポインタ変数をアーギュメントとして関数に渡せば、関数にはそのポインタ変数のコピーが
渡される。で、関数内部で、アスタリスク演算子を適用して、元の加工したい変数をポインタ変数コピー
から参照して演算を行えば、元の変数そのものを加工し、その結果を格納し関数スコープが
終了した後も保存可能となる。

ちなみに、**とアスタリスクを2つ繋げたポインタのポインタ変数というものも
出てくるが、これは、要するに、ポインタのポインタのコピーを関数に渡して、ポインタ
そのものを関数処理し、元のポインタの指す位置を演算処理して変更して結果を保存する
為のモノ。要は、関数に渡すアーギュメントはコピーが作られてしまう為、関数処理加工して
結果を保存したい対象が変数であれば、ポインタ、ポインタをそうしたいのであれば
ポインタのポインタを使用すると考えれば良いと思う。
38T.K:04/05/19 23:17
おやまあ
アセンブラ使え、アセンブラ!
もっと気楽に逝くべ

void fanc(char *p);

int main()
{
Str[] = "Hellow World.";
fanc(Str); //Strの先頭アドレスを*pへキャスト

return 0;
}

void fanc(char *p)
{
 printf("%c\n",p[0]); //*pはchar型なのでchar型の配列・変数と同様に扱える。
//ちなみに実行するとHが表示される。

p++; //ポインタに値を加算する。ココではpはchar型なので
//1Byte分ずつアドレスがずれる。ちなみに、long型を
//引数で受け取っても1Byteずつしかずれない。
//もしcharでなくlongだったなら4Byteずつずれる。
//ポインタの型とはそういうもの。

printf("%c",p[0]); //その為この関数の実行結果はeが表示される。
}

ちなみに*PはP[0]と同じである。

こんな感じだったら分かる?
実際にコンパイルしてないので動くかどうかは分からんのでよろしく。
fanc!
類似スレ

ポインタを上手に例えてみよう
http://pc5.2ch.net/test/read.cgi/tech/1030901827/
C言語のポインタってなんですか?
http://pc5.2ch.net/test/read.cgi/tech/1056082808/
>39
アセンブラなんぞ生ぬるい。インストラクションテーブル眺めながら
ハンドアセンブルが最強。

#マジでTK大ISにはこういう授業があった。
4439:04/05/19 23:45
>>43
ごもっともでございます・・・_| ̄|○
学校の授業ではないけどよくやったなぁ、と書くと、歳がばれるぅ。
ポインタが難解なのはC言語の仕様がすべて悪い
変数は、コンパイルするとアドレスになるんだよ。
i = 10; は アドレス1番地 = 10; ってなる。
ポインタ変数はアドレス型の変数なんだよ。

って覚えた。
>>43
俺の行った学校だと、
週一回の電子工学実験の1つに、マイコンというのが混じっててな・・・。

目の前にはTK-80のようなマイコンキットとマニュアルのみ。
そして、今日中にメモリエディタを作れ、という指令。

プログラムの入力はトグルスイッチで0番地から順に1バイトずつ書き込み。
デバッガなんてありません。CPUのクロックをワンショットにして、1サイクル
ずつ実行しながら、アドレスバスとデータバスの出力をLEDで確認。


#ちなみに、この実験シリーズは学生に色々と体験させるのがコンセプトで、
ハンドアセンブルした次の週には、本物の人工衛星を使わしてくれた。
やることといったら、パラボナアンテナの前に水の入ったバケツを置いて、
エラーレートのグラフを書くだけだったので、なんとかなったけど・・・。
48マジレス:04/05/20 03:21
ポインタを理解するのにC言語の記法を持ち出すと混乱する。
だから記号は使わない。
ポインタの理解はマシン語レベルで説明した方がすっきり来るはず。
(変数の概念は別に説明する必要があるだろうが)

じゃこんな流れかな?

続く
49マジレス:04/05/20 03:22
まず、計算機は、計算をするCPUとその計算結果を
書き留めているメモリとで構成されている事を説明せねばならない。
メモリが2次元的に番号を振られているなんて初心者は知らないから
それを教えてあげる。
ここで実はメモリにはプログラムも入っている事を教える。
プログラムとはCPUに対する命令の集まりで、命令には番号が振られている
ということを説明する。その番号がメモリに順番に入ったものがプログラム。
ここで、適当な例を引いて説明する。(工場内で製品が出来上がる様子など)
どんな命令があるかはさておき。
次は動作について、
メモリは、計算機は動いている時、メモリを1つ読み、それを命令だと解釈して
その番号通りの処理を行う。そして次のメモリを読み…と続けていく。
ここで計算機は処理(足し算とか引き算とか)の結果をメモリのどこかに
格納しなくちゃいけない。
その結果を格納するメモリの場所を指定するのはどうするか?
それはメモリに割り振られた番号で指定する。

ここでメモリを扱う時に2種類の値が登場していることを説明しなくてはいけない。
「計算結果の数値」と「計算結果を格納しておく場所の番号」だ。
この後者、場所を指し示している数値の事を指してポインタという。

計算機にはこの命令を出す言葉の種類がたくさんあって
(日本語、英語、中国語のように)それぞれいろんな決まりがあるけれど
この「値を格納している場所を示すもの」をポインタと名付けている。
と教えてあげればヨシ。

その働き、使い方についてはここまでの定義を理解すれば自ずと分かって来るだろう。
表記については、単なる言語毎の決まりでしかないから、
このポインタの定義をたたき込んでいれば理解はできるでしょう。
50デフォルトの名無しさん:04/05/20 11:45
C言語で扱うデータの場所を示す値→ポインタ。
アドレスを指し示すもの→ポインタ
mov ポイ ンタ
ホテルの部屋割っぽく理解している。
char型:一部屋(定員8名)
int型:二部屋
メモリのアドレス:部屋番号
変数名:予約者の名前
データ:個々の客
ポインタ:客がとってる部屋の、最初の部屋番号と客の名前を書いた札
ポインタのアドレス:札を入れた箱の番号
ポインタの変数名:札の分類名
ポインタのデータ:札
ポインタに変数を代入すること:札に部屋番号と予約者の名前を書き込む

妥当かどうかは識者にまかせる。
てか自分の中ではポインタ=札と訳し変えて理解しただけだけど。
宣言部の*と処理してるときの*は意味が違うというのがわかったときピンときた。
5453:04/05/20 15:00
ちと修正。
×ポインタ:客がとってる部屋の、最初の部屋番号と客の名前を書いた札
○ポインタ:客がとってる部屋の、最初の部屋番号と予約者の名前を書いた札
55デフォルトの名無しさん:04/05/20 16:56
ポインタはアドレスが値で参照したときの値のアドレスの値だよ
なんかさ、本屋とかでポインタの解説だけで丸々一冊っていう解説書あるし。
あれを見たら学習意欲が無くなると思うw
ポインタも自身のアドレスを持っていることを言及した解説は少ない希ガス。
おいおい,お前ら >>53 みたいな言葉遊びは止めようぜ?
混乱の元だ。 そんなのはパンピー相手の講演用。

プログラマ相手なら参考資料は16進ダンプの出力で十分だろ。
縦横にアドレスの見出し付きの奴な。
>>57
当たり前だからだろ。ポインタの説明なんて3行で終わるんだよ。

char *p = "hello, world";
printf("%c\n", *p);
printf("%c\n", *++p);

あと

printf("%c\n", p[0]);
printf("%c\n", p[1]);

でも同じだ。
つーか氏ねよお前ら。
ポインタは実は簡単で『データAがあるのはここ』の“ここ”をポインタと言う
難しいのは、“ここ”と書くために何が使われるかで、現実のマシンではアドレスと言う番地を使っている
このアドレスが色々と曲者で、ポインタを理解するためにメモリ内部の仕組みまで理解しなければならないのが
ポインタが難しいと感じる理由

間違ってる?
ポインタの概念なんか、「ここを見て」って感じで日常会話でもよく使われてるよ
いいねここ。
ここってどのスレ?

ぬるぽ。
63>>62ガッ:04/05/20 18:32
 
64名無し@沢村:04/05/20 19:34
これだけいろんなやつが入れ替わり立ち代わりポインタについて説明してくれているが、
まだ理解できないやつっているの?
住所みたいなもんだろ。
>>64
理解できない奴 =:= 理解する気が無い奴
もしくはポインタ以上のすんばらしい概念を持っている神様
>>57
?ポインタは型ですよ?
ポインタ変数がアドレスを持つ
中のデータはアドレスを持たない
C言語の宣言まわりの文法がアレだから初心者は躓くんだろ
ポインタの概念自体は誰でも理解できる
>>59ビミョーに間違ってんぞ。
*++pなんてしたらpに格納された値が更新されてp[1]とまったく同じじゃないだろ、
p[1]と同じようにしたいなら*++pじゃ無くて*(p+1)だろ。
あんのーPHP勉強しはじめた者なんすけどね、
ファイルポインタっていうのも同じような考えのモノなんでしょうか。
ファイルポインタという言葉は出てきても、それを説明している本が
目下のところ一冊もなかったので。
int *p = &a;
この書き方が理解を邪魔した
int *p;
p = &a;
と分けて書け
確かにポインタの概念自体は誰でも理解できる、
でもやっぱり今日もポインタで苦しんでいる若造はいっぱいいる、
ではポインタで悩むときってどういうときなんだろうね。
書式なのかな。
ポインタを上手に例えてみよう
http://pc5.2ch.net/test/read.cgi/tech/1030901827/l50
一応重複……。
構造体の中身が全部一致しているか調べるにはどうすれば良いんですか?
一個一個調べるしかない?
7675:04/05/20 23:15
誤爆。どうか放置してください…
>>76
(・∀・)GO BACK!!
ようはさ、ポインタがなにかとかよりも、なんでポインタ使うのかのほうが大事。
79デフォルトの名無しさん:04/05/21 14:46
ポインタで悩む原因は、式の中で、その変数がポインタなのか、ポインタを介して参照してる
変数の値なのかがよく分からなくなるからだろ。

その為にも、変数そのものと、ポインタ変数の宣言時の名前の付け方は大事。
初心者本(まぁ普通のプログラムとかでもみんなそうだが)でポインタ変数に先頭に
小文字のpが付くのは、これはポインタ変数ですよって知らせる為だよ。
Cの場合,ポインタ変数に入っているのはただの数字。
っつーのも,『はっきりと』教えて遣った方が良いと思われる。
>>73
>ではポインタで悩むときってどういうときなんだろうね。

俺も昔、C言語を勉強し始めた時 >>72 で悩んだ。
元々はアセンブラを弄っていて、ポインタの概念自体は
理解していたのだが、それでもCのポインタには悩まされた。

その後、結局はCの初期化構文が "式" に似ているのが
諸悪の根元だという事が分かるようになった。
これが悪いことなのかどうかは判断が分かれる所だと思うが、
Cのポインタを理解しにくくしている原因であることは
間違いない。
漏れはポインタを知らない、というかプログラムできませんが、
ポインタをググって軽く調べたのでたとえてみますか。

ポインタと言うのにはアドレスというものがある。
このアドレスというのは、この掲示板の>>1->>80のレスに例えられる。

例えば>>1というのは順番に割り振られた只の番号であるが、
名前欄には「プロだよ」というように記述されている。
ということは、>>1は「プロだよ」ということになる。
当然、>>2->>80についても同じことが言える。
これと同じように考えればアドレスは簡単に理解できる。
変数A(プロだよ)に割り振られたアドレスというのが、1(>>1)なのである。

・・・ここまで書いたけどポインタの概念を理解できてるってことなんで、
蛇足だからやめときます。。。(ついでに間違ってる
実際問題、何故ポインタが理解できないのか、それが理解できない。
だが一つ思うことは、人間には向き不向きがあるのだから、
ポインタが理解できないのなら、別の道を探すよう勧めるのが親切というものだ。
int hoge, *p;
で p は
p = &hoge;
って 変数に&演算子をつけたものを代入するんだから、(配列・関数名/mallocとか他は一旦忘れて)
int hoge, &p;
って具合にint型の変数に&をつけたものを代入しますよ
ってこういう風に似せていたらどうなっていた、見かけだけ変えても無駄?
今更どうやっても無理だが。
(当然C++の参照は int *ref; で。)
>>81
じゃあ、ポインタ初学者は

LPSTR p = &a;

から学ぶことにしようぜ。
86デフォルトの名無しさん:04/05/21 22:26
仕事でFORTRAN組む事なったんだけど
FORTRAN90からもポインタってあるんやね。
昔の言語と馬鹿にしてたけど90なかなか使えるかもぽ
おれが一番混乱したのはポインタは型サイズに応じて勝手に処理しやがるってこと

たとえば a+1 とか書いたらそのポインタの型に合わせて加算するくせに
a = 0x0001 とか書いたらそのままアドレス代入するじゃん

じゃあ a = (0x001)+1 とか書いたらどうなのよ?とか思ったら
コンパイラが単項にまとめて処理しちゃうでしょ

じゃあ、
a = 2,b = 3,c = 5
とあって a = b+c とやったらどこがサイズ意識して変換されるのよ?
とかそーゆうの悩んだ



あと *ptr[3] みたいなコード書いた場合とかさー
これ ptr が int *ptr[n] って宣言してあった場合と
int **ptr って宣言してた場合って結果違わない?
88デフォルトの名無しさん:04/05/21 23:46
自分はポインタ宣言するときは次のように書いてました.
long* a;
aをロングのポインタとして宣言するという意味で.いや,これが正しいと思ってたんだよ.
でも却ってこの方が混乱しにくいと思ってる.

long* a, *b;
long* a, b;
90デフォルトの名無しさん:04/05/22 01:04
>>89
もちろんそういう風にはしないですよ.
間違ってるのは分かるんですが,感覚的に自分にとっては正しい.
キャストは(int*)だしな
>>87
お前さんの場合,混乱の原因は教える側の人間が言及しなかった点ではないのか?
アドレス同士の加算は禁止だしよ。
定数代入ならキャスト必須。

実際に口で教える必要なねぇけど,レジュメには書けと…

>あと *ptr[3] みたいなコード書いた場合とかさー
>これ ptr が int *ptr[n] って宣言してあった場合と
>int **ptr って宣言してた場合って結果違わない?

どっちも一緒。どうやら,まだ混乱してるようだな(藁
>>87
>あと *ptr[3] みたいなコード書いた場合とかさー
>これ ptr が int *ptr[n] って宣言してあった場合と
>int **ptr って宣言してた場合って結果違わない?

「結果」の意味がわからんが、(CPUの)処理は違う。
>>91
そこだって(int *)でもいける
92-93
それ調べとこうと思ってまだ調べてないんだけど、つまり
配列からポインタを取り出してアクセスするのと
取り出したポインタにオフセットアドレッシングするのと
見かけが紛らわしいってことが言いたかった
つまり

mov esi,[edi+n] と

mov esi,[edi]
mov eax,[esi+n] みたいな感じ

*(ptr[n]) (*ptr)[n] ってきっちり書かないと紛らわしくないですか
いやこういうコードをこの間見かけたので
char tbl00[][3]=
{
{ 0,1,2, },
{ 3,4,5, },
{ 6,7,8, },
};

char *tbl01[]=
{
(char *)0x01000,
(char *)0x02000,
(char *)0x03000,
};

char **tbl02;

void test()
{
char v00,v01,v02;

v00 = tbl00[1][1];
v01 = tbl01[1][1];
v02 = tbl02[1][1];
}

似たようなのでこれ
どれも表記は tbl[m][n] なのに出るコードは別モノ
>>95
> *(ptr[n]) (*ptr)[n] ってきっちり書かないと紛らわしくないですか
> いやこういうコードをこの間見かけたので

意味が全く違うんだが。
98デフォルトの名無しさん:04/05/22 15:22
自分も意味は違うと思うが,演算規則うろ覚えなので過剰に括弧( ) つけているのは自分だけですか?
>>98
そもそも*ptr[3]という式の結合順位が紛らわしいという話と、
int *ptr1[n];
int **ptr2;
の違いの文脈と何の関係が?
「意味」的には、
*(ptr1[n]) = *(ptr2[n]) だし、 (*ptr1)[n] = (*ptr2)[n]。
>そもそも*ptr[3]という式の結合順位が紛らわしいという話と、

int *ptr1[n]; これはどうやって結合するんですか?

int
*
ptr1
[n]
;
> int *ptr1[n]; これはどうやって結合するんですか?
それ式じゃないし…

int *(ptr1[n]);
宣言の意味は:
ptr1は配列。なんの配列かというと、ポインタの配列。
なにへのポインタかというと、int。
結局、「ポインタがわからない」というのは、
「ポインタの絡む宣言がうまく書けない・読めない」って事なのか?
「8080 には HLレジスタペアというのがあってね、それがね..............
104デフォルトの名無しさん:04/05/23 08:03
javaはポインタが無いんじゃなくてポインタしか無い
>>28
>どんな変数にもアドレスがあって
これは誤り
scanf("%d",&a);
つまり仮引数を参照するから&をつけてそのポイント=
場所を教えるわけだ、ポインタはそうした場所=
アドレスの位置を記録する(ry
107デフォルトの名無しさん:04/05/23 09:08
で、ポインタってなによ?
教えるのがヘタなやつは,最初から厳密な定義を教えようとするのな。
109デフォルトの名無しさん:04/05/23 15:45
□■□□□…
 △←これ
掲示板で言うところの
>>107 ←これ
ポインタ?あれだよ。あれ。
なんていうかな、こう…ポイントするものっていうか、
ラベルっていうか、ただの数字っていうか…
メモリにはアドレスっていうのがあるだろ。まぁポインタそのもの
じゃあないんだけどな…まぁあれだよ。わかっただろ。
ポインタが何かなんて無理に説明する必要なし。
ストリングコピーのコードが書けたり、関数を呼んだ先で引数の値を変えたり、
呼び出し先のアドレスを格納した配列からインデックスされた値をとりだしてその関数を呼び出す
なんてことができればそれでいい。
113デフォルトの名無しさん:04/05/24 02:29
>>104
「Cはポインタがあって難しいからワカンネー」
とか言ってるサーブレットオンリーJava厨いるんですが
おまえはスカラ以外はポインタしか宣言したことねーだろう?と
小一時間問い詰めたかった。
なんだ自覚してないけど、スカラ以外がポインタか。
じゃあ知らぬ間に普通に使いこなしていたわけじゃん。
俺すげー。
知らぬ間にリッチテキスト編集したり、
知らぬ間にwwwサーフできちゃったり、
知らぬ間にボタン一つでご飯を炊いちゃったり、
俺ってすげー。
>>114-115
おまいらってスゲー!!
プレゼンで使う奴か?
118デフォルトの名無しさん:04/05/25 23:11
猟で使うイヌか?

         ∧_∧
        _( ´_ゝ`) < パワーポイントだ馬鹿
      /      )           _     _
     / ,イ 、  ノ/    ∧ ∧―= ̄ `ヽ, _
    / / |   ( 〈 ∵. ・(   〈__ >  *゛、_―
   | !  ヽ  ー=- ̄ ̄=_、  (/ , ´ノ
   | |   `iー__=―_ ;, / / /   ←>>117
    !、リ  -=_二__ ̄_=;, / / ,'
        /  /       /  /|  |
       /  /       !、_/ /   )
     / _/             |_/
     ヽ、_ヽ

         ∧_∧
        _( ´_ゝ`) < ポインターだ
      /      )           _     _
     / ,イ 、  ノ/    ∧ ∧―= ̄ `ヽ, _
    / / |   ( 〈 ∵. ・(   〈__ >  *゛、_―
   | !  ヽ  ー=- ̄ ̄=_、  (/ , ´ノ
   | |   `iー__=―_ ;, / / /   ←>>118
    !、リ  -=_二__ ̄_=;, / / ,'
        /  /       /  /|  |
       /  /       !、_/ /   )
     / _/             |_/
     ヽ、_ヽ
ポインタは、その名のとおり何かを挿すもの。
例を挙げればオティンティンはポインタ。
正しくおまーんを挿していれば良い感じ。オティンティンポインタを通じて
ぴゅっぴゅすれば挿した先を妊娠させるという遠隔操作が行える。
オティンティンポインタは別のおまーんを挿すことも出来るから、いろいろなおまーんに操作を行える。
ただしこの場合正しくポインティング先をdeleteしないとメモリリークが起きて
忘れたころに沢山の人から慰謝料やら教育費やら請求されて大変なことになる。

ポインタは何でも挿せる。
間違えて男性のアナルを刺してしまうと挿した男性を破壊してしまう諸刃の剣。
その場合、その男性はクラッシュし、OSごと落としてしまいかねない。
または挿した男性に付きまとわれて自分のOSが落ちかねない。
ウルトラセブンに出てくる車
熊田曜子
 そりゃポインターだボケ
\____ __________
       ∨
      ∧_∧          _ _     .'  , .. . ∧_∧
     ( ´_ゝ`)   _ .- ― .= ̄  ̄`:, .∴ '      (    )
    /     '' ̄      __――=', ・,‘ r⌒> _ / /
   / /\   / ̄\-―  ̄ ̄   ̄"'" .   ’ | y'⌒  ⌒i
 _| ̄ ̄ \ /  ヽ \_              |  /  ノ |
 \ ̄ ̄ ̄ ̄ ̄ ̄ \__)              , ー'  /´ヾ_ノ ←>>122
  ||\            \          / ,  ノ
  ||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄          / / /
  ||  || ̄ ̄ ̄ ̄ ̄ ̄ ̄||          / / ,'
  ||  ||           ||       /  /|  |
                       !、_/ /   〉
 熊田曜子はボインだ、だろこのエロガキ
\_____  ________
         ∨           _ _     .'  , .. ∧_∧
           ∧  _  - ― = ̄  ̄`:, .∴ '     (    )  ←>>123
          , -'' ̄     __――=', ・,‘ r⌒>  _/ /
         /   -―   ̄ ̄   ̄"'" .   ’ | y'⌒  ⌒i
        /   ノ                  |  /  ノ |
       /  , イ )                  , ー'  /´ヾ_ノ
       /   _, \                / , * ノ
       |  / \  `、             / / /
       j  /  ヽ  |            / / ,'
     / ノ   {  |           /  /|  |
    / /     | (_          !、_/ /   〉
   `、_〉      ー‐‐`              |_/

>>102 が良い事言ってんのに最近スレ荒れ気味だw

参照と非参照を両方“明示的に”行わなければいけないから、難しいように思えるんじゃないか?

読み易さ重視でいけば、この問題は Delphi とか Java とか、言語レベルでサポート出来てる
C は融通が利く分、初心者には向かないんでは?
ポインタのポインタのアドレス。
128デフォルトの名無しさん:04/05/30 04:40
ポインタが何故難しいか。
○○型へのポインタ型、その型の変数、その変数に入る値、その値が意味するもの、
の4つを全部「ポインタ」という同音異義語で呼ぶ「わかった」人がたくさんいるから。
そりゃ初心者混乱して当然だと思う。

129デフォルトの名無しさん:04/05/30 05:01
普通のプログラムで書く世界から、ある種メタ方向に
世界観を拡張させる必要があるからではないか。
class Pointer< class T >{
public
 T getValue();
 void setValue( T value );
 Pointer& operator[]( int index );
 Pointer& operator+( int index );
 ・・・
};
>>119
今更ですまんが、>>117 はレーザーポインタかも試練。
MagicPoint課も試練

   いまさらおせーんだよ!!
\_____  ________
          ∨        

         ∧_∧     _ _     .'  ,..  ∧_∧
        ( ´Д` )_ - ― = ̄  ̄`:, .∴ '    (    )
         ヽ-'' ̄    __――=', ・,‘r⌒>  _/ /
        /  ,,-―  ̄ ̄   ̄"'" .  ’ | y'⌒  ⌒i
       /   ノ\\            . |  /  ノ |
        /    /   \\            , ー'  /´ヾ_ノ
       レ  ノ     ヽ_つ        / ,  ノ
      /  /               ./ / /
      /  /|              / / ,'
      ( ( 、            /  /|  |   ←>>131
      |  |、 \          !、_/ /   〉
      .| / \ ⌒l            |_/
      | |   ) /
     ノ  )   し'
    (_/            -==≡≡≡=
134デフォルトの名無しさん:04/05/30 20:49
>>100

>int *ptr1[n]; これはどうやって結合するんですか?

ptr1から演算子の結合順位に従って英語表記にしてけばいいんでないの?

ptr1 is an array of pointer to int.
を日本語にして
ptr1は、intへのポインタ型の配列。
英語圏の人間は理解しやすいと思われ。
ポインタが分かりにくいというより
ポインタの使い方が良く分からない
と言う人のほうが多いんでない?
* には、いったい何種類の使い方があるんだ?
Cは何でもかんでも * を使うから、初心者が混乱する。
>初心者が混乱する。

本当にそうだろうか?
本当に初心者はポインタで混乱し、躓き、挫折してるのだろうか?
俺には、Cで挫折するヤツはそれ以外の部分で躓いてるようにしか見えない。

似非上級者どもが初心者に対して一生懸命「ポインタはヤバい、
、難しい、理解しづらい」と吹聴しているのはいかがなものか。
そんなこと言う奴はたいてい、Cで挫折したヤツであり、しかも
そいつらはポインタ以前の問題で挫折しているように見受けられる。
たとえばプログラムが使うメモリの領域で、スタックとヒープの概念さえ
理解できていないといったことだ。
そいつらが全てをポインタのせいにして「Cはポインタが複雑だから習得は難しい」
などと叫び、必死に初心者の邪魔をする。そうでないと自分達の無能ぶりが
救われないからだ。
138137:04/05/30 22:31
以前ウチの会社に未経験で入ったMさんという女の子。
ウチの会社は6割がVB、3割がJava、1割がその他(Cなど)なのだが、
珍しくCを習得することになった。
そのことが決まってから3日間の間に、先輩達10人くらいに
「Cはポインタが難しい。初心者にはとても理解できない」
(↑おまえが低脳だからだ)
「Cはメモリを直接いじるから下手なことするとOSまで壊すから怖い」
(↑今のWindowsでできるもんならやってみろよ)
などという虚言妄言を繰り返し繰り返し言われたようだ。
なんかな、こういう馬鹿どもがいけないんじゃないのかね。
>>136
オレが講師をする時には、*の使われ方一覧を用意するようにしている。
140デフォルトの名無しさん:04/05/30 22:50
かけざん
ぽいんた
ポインタの中身

あと何ありましたっけ
141 :04/05/30 22:55
糞スレ
>>134
同じ物をPascalで書けば
ptr1: array[0..n-1] of ^Integer;
Cの表記がポインタを不必要に分かりにくくしている。
ポインタはインスタンスを指そうとするもので、
インスタンスは内容物。
メモリだと、自分のために確保された安全な領域や長さnの要素。
自分のために確保されていない場所はデンジャー。ハッハッハ〜。

読み出すだけなら、どこでも安全なんだけどねぇ。
とりあえず、これは保留。
144デフォルトの名無しさん:04/05/31 10:25
> 読み出すだけなら、どこでも安全なんだけどねぇ。

そうでもない。
「あれこれ難しく考える前に、体で憶えろ」か?最善の方法は
ポインタというのは参照(リファレンス)という抽象概念を、
アドレスという実体で実装したものだと思うのだが、
参照だけでも難しいのかな?

まぁ、抽象概念というのは当たり前すぎて難しかったりする物ではあるけれど…
例:プログラム・関数・変数など

抽象概念を身につけるには、比喩や具体例を積み重ねつつ、
そこにある関係を丁寧に対応付けて、パターン認識力を育てていくのが王道で、
定義とか説明とかにこだわりすぎるとかえってハマるような気がする。
>>146
>参照だけでも難しいのかな?
如何にも難しそうに語るような連中が初学者を混乱させているだけでしょう。
>>126
>参照と非参照
dereferenceの日本語訳って,非参照だったっけ?

こんな訳だと,単語から意味わかんねぇよなぁ。
>>145じゃないが,「体で覚える」になる原因じゃないか,これ。
>>148
そんな訳は聞いたことが無い。「逆参照」じゃないか。
しかし「参照解決」のほうがいいと思う。
変数を先に変な風に教えるとまずいんじゃないの。
ポインタがないと、どう不便か、と考えてみるとかさ。
悲惨賞
アドレスの入れ物じゃないの?ぽいんたって
>>153
だから「入れ物」なのはポインタ変数だと何度言ったら気が済むのだ!
155デフォルトの名無しさん:04/06/03 12:37
なぁ、ポインタっていつ使うんだ?
漏れは、func(char *) としか使わないぞ。
オレは関数のアドレスを配列に入れて
テーブルジャンプする時ぐらいしか使わないな。
俺は英国紳士のように優雅に狩りをするとき
くらいしか使わないな。
二分木
>155
おれも一緒だなぁ。

Cの本のポインタの説明にあるような
↓こんな直接変数のアドレスを見ることなんてしないしね。
配列と似た感じでしか使ってないよ。

int main(void){
int a;
int *p;

a = 3;
p = &a;
printf("%p %p\n", &a, p);
return 0;
}
ポインタを使わないプログラムなんてありえないでしょ?
なにいってんの?
Template T* とかつかわない??
162デフォルトの名無しさん:04/06/04 01:59
ポインタ使わないってことは、ヒープ使わないってこと?
Cの世界ってそれがノーマルなのですか… orz

Javaで5年PG→いまCやってて、ほとんどヒープに確保してるのですが…
なんで、アドレスさすのが
ヒープ領域のみになるんだか・・・

プログラム領域かもしれないし
スタック領域かもしれないし・・・
>>162
ヒープ使うのがふつーですね。
組み込み等、環境の制限が厳しい場合は
避ける事もありますが。

>163
えーっと…誰かそんな事書いてました?
>>160
頑張れば、ポインタ一切使わずに書くことも出来るでしょう。
あんまり見たいコードではないでしょうけど。

 ・関数ポインタなんか使わない  → すべてswitch〜case
 ・ヒープなんか割り当てない     → すべて固定長の配列
 ・引数にもポインタなんかない   → グローバル変数
 ・構造体にもポインタなんかない → リストなどという
                       複雑なデータは扱わない
>>163
「ポインタを使わない→ヒープを使わない」は認識としておかしくないぞ
「ヒープを使わない→ポインタを使わない」ならおかしいが

>>162
ようやく「Javaは使えない」の意味がわかってきた
スタックですむことならなるべくスタックを使うのが「C」の「ノーマル」
ヒープに確保するのはその理由があるときのみ
確保時の変数のスコープとオブジェクトの寿命が異なるとかな
デフォルトがヒープなのは危険だよ
free()ちゃんと呼べてる?
Javaはすでに死んでいる言語だ
168デフォルトの名無しさん:04/06/04 11:12
引数にもポインタはよく使うよな。
構造体にポインタはほとんどない。
リストも滅多に使わないし。

Javaは文字列を扱うとき(自分のツール)にたまに使ってたよ。
mov DX,[AX]
mov DX,AX

この差
文字列操作関数を作れば、いやでもポインタが必要になる。
文字列操作をサポートしてない言語に限るね。
172デフォルトの名無しさん:04/06/05 01:24
そういや、大昔勉強したての頃
ポインタ使わずにゲーム作った事あったなぁ・・・X68でw

その後、アセンブリ言語を勉強して
初めてアドレス空間のことを把握できて

Cに戻ってもポインタの仕組みや動きをやっと理解できた記憶も。

しかし今思うと、よくゲームつくれたなぁと逆に思ったり。
コード無くしたから今更確認できないけどw
>>170
内部的にどの言語もポインタを使っているので、
ポインタは必要だしみんなポインタを使っている。
けど、ポインタの存在をしらなくてもプログラムが組める。
ポインタの存在を意識しなくても
ポインタを使っている。
それでいいじゃないか。
ということで、ポインタの説明は必要ない。
まあ半導体の知識みたいなもんだな。
誰もが使っているが、通常のプログラミングに知識は必要ない。
あればベターって感じだよね。
ポインタの勉強とSQLの勉強、どっちかやるならSQLの勉強せろ、って感じだ。
ポインタの概念は初心者でも1時間あれば理解できるだろ
要するに「アドレスみたいなもの」だよ

問題はあの腐りきった表記法なんだよ
複雑なやつになるともう訳ワカラン
セグメント割り当てから勉強しないと完全理解は不可能
そうか俺はアセンブラから入ったからポインタ苦にならなかったのか...
「メモリマップ」ということばで何か図が思い浮かぶやつは、大丈夫。
いまどきのプログラミングじゃ、セグメントの意識はほとんど必要ないべ。
組み込み系では、まだあるかも知れないが。
MSXでは、いらんかった。
R3000でも、いらんかったが、MMUが面倒だった。
関数ポインタはいい、初めて見て驚き、理解できて快感。
それがオブジェクト指向言語で必要なくなった。
パチスロを打ったことのない香具師にリプレイはずしの概念や意味を教えるのと同じ。
打たなければ理解不能。
>>187
何が必要なくなったの?
190仕様書無しさん:04/06/06 12:19
おれはCのポインタを理解するのに1ヶ月もかかったのだが
配列num[i]をポインタnum_pで表現する場合、Cの式上において
下記のことがきちんと整理できていればポインタなんて
難しくなかったんだよね。たったこれだけのことが初心者には
大きく混乱を招いてしまう。

num_p + i = num + i = &num[i] /* 配列のアドレス */
*(num_p + i) = num[i] /* 配列の中身 */
191190:04/06/06 12:23
つけ忘れ

*(num_p + i) = *(num + i) = num[i] /* 配列の中身 */
>>189
関数ポインタ
ポインタを単にメモリ上の「アドレス」というからわかりにくくなるのではないか。
「メモリ上の一点」を指しているだけみたいで。
同じアドレスを指してても型によって扱いが異なるわけだから
「メモリ上の塊」を指しているということをもっと強調すべきだろう。
char *a_p = "hello";
char **aa_p;
char ***aaa_p;
.
.

aa_p = &a_p;
aaa_p = &aa_p;
.
.

printf("%s\n", *aa_p);
printf("%s\n", **aaa_p);
.
.

一般の開発でダブルポインタ以上使うのはどこまで許されるもんですか?
少なくとも俺の所では「ダブルポインタ」なるものは全く許されない。
>>194
さあ?。規約でその種の記述は見たこと無いし。
規約策定者が精通しているのなら「その種の規約は無い方が良い」と判断して、制約しない
規約策定者が精通していないのなら「どこで制約すべきなのかわからない」ので、制約しない
なのカモネ
char **
これが許されないのなら文字列の配列が作れないじゃーないか
>>193
メモリ上の一点じゃなくて、
メモリ空間を区画割りして、それぞれにつけた番地。
199デフォルトの名無しさん:04/06/06 21:05
int main(int argc, char **argv)だったかな?
昔に、使った覚えが…
>>199ならしょっちゅう使ってます
>>198
区画割してないよ。
それはallocの話で、ポインタはいくらでもその区画の途中を指すことができる。
区画割っていうのが、8ビットごとにまとめて1バイトっていうことなら、そのとおりだけど
202198じゃないけど:04/06/06 21:50
>>201
そのポインタの指す型ごとのバイト数単位での区画割りじゃないのかな
>>202
増減の幅の話ってこと?
そしたら、区画割ではないよね。意味のある区切りを表す保証はまったくないんだから。
204198じゃないけど:04/06/06 22:30
>>203
ん?ポインタ演算ではそのポインタの指す型ごとの演算がされることが
保証されているじゃない?そういうことではなくてですか。
オブジェクト指向言語でも関数ポインタは使うよ〜
206198:04/06/06 22:41
最小単位のbyte区画という意味なのだが。
それ以外の型は、複数区画をまとめたものに過ぎないという解釈で。
207203じゃないけど:04/06/06 22:42
>>204
それは型として保障されているだけであって、メモリ内部のデータ自体には関わらないって話じゃないの?
別に int 型の領域を char として計算してもかまわないんだし
208207:04/06/06 22:42
ごめんあげてしまった
209198:04/06/06 22:43
たしかにそれはポインタの説明としては不十分か。
アドレスの説明だ。

まぁ、アドレスが理解できればポインタはすぐ分かるだろうということで。
結局さ、「ポインタ」って言葉が何を指しているか曖昧なのがそもそもの原因だよね?
211デフォルトの名無しさん:04/06/07 00:25
あれだ、URLとHTMLファイルの関係と同じだ
ダブルポインタを新人・初心者にうまく説明できる人、又はした人います?
213まとめ:04/06/07 02:27
アドレス
・メモリ上の物理的な位置を示す。
・最小単位(1Byte)で区切られた区画に割り当てられた数値(番地)。

ポインタ
・メモリ上の論理的な位置を示す。
・任意の型(のサイズ)で区切った区画を識別するもの。
・いわばメモリの目盛り。(型=メモリを測るためのものさし)

こんなんでどうでしょ。
…いや、「メモリの目盛り」なんてさぶいギャグを言いたかったわけではないよ。
>>213
>最小単位(1Byte)
とは限りません。
>>214
かならず1byteになる、という意味ではないんちがう?
厳密な話を始めると、
a = b;
これすら面倒なワナ
>>213 では無いが追加してみる
間違ってたらフォローよろ

ポインタ変数
・メモリの目盛り、つまりポインタを格納する変数

ポインタ型
・ポインタ参照先のデータ型を定義する型

参照
・ポインタがさしている先のメモリ内容を使用する行為


相対アドレスと絶対アドレスの定義も必要かな?
>>213 ではアドレスが絶対、ポインタが相対みたいになっているけど、
実際には、ポインタにどちらが使われるのかは記述時には判んないような気もする

あと >>213 のポインタの説明は、微妙に間違っているような気がする
位置情報には、メモリ内部の型は含まれないはず
実行時に型が決まるってことはないの?
>>218
xxx *p;
っていう変数があるときに
++p;
での実際のアドレスの増幅が実行時にかわることはない。
ポインタがアドレスを指すのって実装依存だよな
メモリそのものの存在も実装いぞんであり
……とかいってまぜっかえしてみたりする

初心者の中にも
・メタファのほうが理解しやすい人
・実装に即したほうが理解しやすい人
の2種類がいるよね
どちらをターゲットにするかで説明の仕方を変える必要があると思う
> ・メタファのほうが理解しやすい人

実際に理解できないから、メタファで理解した気になる人・・・。
metaphorでは理解できんだろ。simileは理解の助けになるし、
  ・(抽象的)仕様が理解できる人
  ・実装に即さないと理解できない人
はいるとおもうが。
実装に則すまで理解しないときがすまない人ですが。
金融系アプリかいてたときにMSの今猿にそこまでCOMの細部まで聞いてくる人はいませんと嫌がられた。
なんどなくだけど、ポインタが分からない人は、それ以前に変数というものが
分かってないんだと思う。
変数の名前とか型とかLVALUEとかRVALUEとかさ。

Cは記法上はRVALUEとLVALUEの区別がない。
変数の名前と型とLVALUEとRVALUEを明確に理解している人にとって
ポインタの理解は(記法の面倒さとかは別として)、別に何でもないことの
はず。
まあC++や、MS-DOSのミディアムモデルとかになるとまた別の話ですがね。

ようするに、ポインタを教える以前に教えるべきことを
教えていないだけなんじゃないかと
基本的な使い方なら丁寧に教えてやれば真性でなければ誰でも理解できる。
ただ、ポインタへのポインタとか構造体へのポインタとか少し難しくなると
ついて来れなくなるやつが多いように思う。
>212
なぜダブルポインタ?普通にシングルポインタが理解できた人なら
ダブルもトリプルもすぐ理解できるはずだよ。
ダブルポインタ変数はシングルポインタ変数のアドレスを格納する変数。
トリプルポインタ変数はダブルポインタ変数のアドレスを格納する変数。
以下略。
////////////////////////////////////////////
char *single = NULL;
char **double;
char ***triple;

double = &single;
triple = &double;
////////////////////////////////////////////
やはり、暗黙のうちに配列を指してる場合とそうでない場合があるから
混乱する人が多いんじゃないだろうか
char*
は普通は暗黙にchar配列へのアクセスに使うし、おまけにNUL文字で終端されている
ことが通常は期待されるが、言語の構文だの記法だのには
それは一切あらわれないし、チェックする機構もない
ただのcharを指してるかchar[]を指してるかは「プログラマのみが知る」
セマンティクス上の問題だ
例えば配列を指しているならば
□--------------->□□□□□
のようなメモリイメージを思い浮かべるんだろう
そうでなければ
□--------------->□
だな

で、どっちなのかは宣言だけからは分からないわけだ
その辺がすでに分かりにくくて、その上で多次元の配列とかポインタ配列とか
関数ポインタだとかがごっちゃになって
どういうメモリイメージを思い浮かべたらいいか分からない
そういうのが初心者のありがちな展開ではないのかな
>>225
激しく同意

>>227
>普通にシングルポインタが理解できた人なら
>ダブルもトリプルもすぐ理解できるはずだよ。
同意
ダブル・トリプルポインタが上手く説明できないのは、
ポインタの時点で既に説明が上手く出来ていない罠。
ダブルとかトリプル何に使うの?
配列などで結果的に扱ったことはあったけれど。
>>231
つかっとるやないか・・・
233前スレ755:04/06/08 02:58
イやもっと積極的にさ。アセンブラなんかだと、アクセステーブル入れ替えとかのテクで使うことはあったんだけど、c++ではほとんど使わなかったのよ。
>>231
ダブルぐらいならmain()の引数として毎度おめにかかってるだろ

配列的使い方以外でありがちなのは
関数で「ポインタを(戻り値ではなく)引数経由で返す」場合かな
これだけで一段間接参照が増えるから少なくともダブルにはなる
あ、C++なら確かに参照だの使えるから機会は減るかもなあ
236231:04/06/08 11:32
あ、ポインタの参照わたしは使ってたね
イやもっと、こちらの予想だにしないトリッキーなコードを期待しているんだけれど
トリッキーなコードを求めるでない。
普通が一番じゃよ
ポインタとは、君の人差し指で何かを指したときの機能を分解すればわからないかな〜。

たとえばこういう話。
自分は指を相手の頭にさす。
そして言う。
「俺はそれをさした。」
ここで、それについて考えてみる。
それは、頭であり、番地であったり、場所であったりする。

こんなのどうでしょ。
3行目ぐらいでわけわかんなくなった
これで初心者の人も理解できましたよね?
つまりポインタは指ですね。
243デフォルトの名無しさん:04/06/09 11:36
int* hoge;
hoge = &foo;

*hoge → foo(保持している値)
hoge → foo(アドレス)
&hoge → (気にするな)

ポインタって、こんな感じでいいの?
気にしなくてもいいけどさぁ、hoge(アドレス)にしとけば?
かしこくみえるよ。
>>243
fooは左辺にかくとfooのアドレス(LVALUEをこう書いちゃうのは単純化かもしれんが)
右辺に(式の中に)かくとfooの値

hogeも左辺にかくとhogeのアドレス
右辺に書くとhogeの値=fooのアドレス

*hogeは左辺にかくとhogeの保持してる値=fooのアドレス
右辺に書くとfooの値

&hogeは式だからかならず右辺値で
hogeのアドレス
という訳でポインタが分からない奴は
変数とか式とか
もっと基本的なことから勉強しなおそう
247デフォルトの名無しさん:04/06/09 17:30
これでいい?

// GCC version 3.2 にて動作確認
#include <stdio.h>
int main(void) {
int* hoge;
int foo = 1;
int* bar;

hoge = &foo;
printf("%d\n", *hoge); // fooの値が表示される。

*hoge = 2;
printf("%d\n", foo); // fooの値が変わるぞい

bar = hoge;
*bar = 3;
printf("%d\n", foo); // fooの値が変わる

return 0;
}
>>247
せっかくgccもってるなら、cc -Sで出るasmのコードを見たほうが
あからさまにてっとり速い気がするけど
ごめん、アセンブラ読めないの

私の環境はMinGWなのね。
cc ないの
>>239 みたいな本質から外れたアホみたいなたとえ話する困った馬鹿がよくいるよなw
251デフォルトの名無しさん:04/06/09 20:39
だれか、>>247 にポインタを教えてやれよ。
○○市長が住民票の写しを発行するのである。
×月□日の時点では、○田 △夫が○○市長なのである。
だから×月□日発行の住民票の写しは、○田 △夫が発行するのである。
'○○市長' てのが変数名だとすれば、こいつはポインタの役割をする変数なのである。

※私を煽る人は、煽ってることが分かりやすいように、
 文末に「ゲロッピーピュフプー」と書いて下さい
ゲロッピーピュフプー
(笑点風に)
「紙をくれ」って言ってる人に
1枚とって渡してあげるのが「値渡し」
「紙なら隣りの用具庫にあるよ」って言って出て行くのが「ポインタ渡し」
そうすると、課長の役割はなんですか?

ゲロッピーピュフプー
「理解してもらわなくてもいいから、どんな感じかを伝えたい」ならともかく
解らせるつもりなら、他の何かに喩えたって無駄。
理解するのは個々人の努力
強制的に理解させようなんて思っても無駄
>>254
「参照渡し」じゃないのか?
259デフォルトの名無しさん:04/06/10 17:26
宝物が値
宝地図がポインタ
宝地図の地図がポインタのポインタ
変な説明いらんよ
ポインタはポインタだ
>>258
参照はこうじゃないか?
相手「紙なら隣りの用具庫にあるよ」
自分「そうか。ならXX(部下)、紙取ってきてくれ」
地図とか指はさぁ、増やしたり減らしたりできんじゃん。
つまり参照の説明にはなってるけど、ポインタの説明にはなってないってことだな。
264258:04/06/11 13:39
>>261
参照渡し:4020件
ポインタ渡し:553件
ちなみにそれはエージェント指向(?)
>>262
基本的な概念は同じ。
アドレスを指すという意味ではもう少し別の例えが必要だけど、
全く知らない初心者に教えるなら地図でも十分かと。
266俺は文系だが:04/06/11 15:25
でもやはし、アセンブラの足し算見たいの理解させればポインタ理解するんでない?
それで分からないと...
参照を理解させれば十分だ、という考えが、参照さえできればアドレス演算ができるポインタは不要ということにつながるわけだな。
だからさぁ、全く知らない初心者に説明しようというときに
「地図」だの「指」だの「頭」だの、いきなりコンピュータと無関係な
たとえ話するからダメなんだよ。
http://mikata.curiocube.com/hello/ch03_memory1.html
こんな感じでいいだろ?
              ∩
             | |
             | |
             | |
             | |
       ∧_∧  | |    / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
      ( ´Д`)//  < いいでぇーす。
      /     /    \_____________
     / /|    /
  __| | .|    | __
  \   ̄ ̄ ̄ ̄ ̄   \
  ||\            \
  ||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄
  ||  || ̄ ̄ ̄ ̄ ̄ ̄ ̄||
     .||              ||
270デフォルトの名無しさん:04/06/11 23:35
問2:
 ポインタを使うことでスマートに実装できるという簡易な実例を列挙せよ。

/* こういうときポインタ使うよね、って例をだせということですわ */
>270
・swap
・List
・コールバック関数
>>270
dump
>>270
仮想関数
274デフォルトの名無しさん:04/06/12 01:37
読み始めたばかりだが、「ポインタそのものに格納できる値は4byte」とか言っている>
>12にまだだれも突っ込みを入れていない?

といいつつも、漏れのポインタの認識もこんなだが。

[ポインタとは]
ポインタとは*演算子を使うことで特定のオブジェクトを間接参照することが出来る変数である。

まず、ポインタは以下の手順を用いて間接参照したいオブジェクトを指す手順が必要である。

手順1. 間接参照したいオブジェクトの型に *をつけて宣言する。
手順2. 間接参照したいオブジェクトのアドレスを代入する。

以上の手順を踏むと、ポインタ変数に*演算子を使って2で指定したポインタ変数を
間接参照できるようになる。

また、ポインタの値を変化させることによって間接参照するオブジェクトを
変えることができる。例えば、ポインタの値に++とすると一つ後ろのオブジェクト、
--とすると一つ前のオブジェクトというように。これはポインタ演算と呼ばれている。

ところがこのポインタ演算はメモリ破壊等の原因となりやすい。
例えば、++しすぎてあてずっぽのところを指してしまったりとか。
このためJava言語はポインタ演算のようなことが出来ない仕組みになっている。
考えてみたらポインタ演算なんか使ったことないな
通信などでメモリ直接いじるとき除く
そ、そうか?
多くのポインタ演算は配列演算子で書き換えることも出来るけど
結局Cでは内部的にはポインタ演算なので(危険度まで含めて)一緒でしょ
それに

c = *p++; // fetch and incr
*dst++ = *src++;// copy

みたいなのが簡潔に書けるのはやはり便利だけど
ほんとにつかわないの?
C++ばかしでポインタはnewしたオブジェクトにしか使わないしそれもvectorとかに突っ込んでるし...やっぱつかわね
>276
そういうのは、配列の書き方でした方が分かりやすいしなぁ。
(デバック時も含めて)

線形リストみたいなのだと、本質的にポインタを使うわけだが
線形リストに使うポインタでは、ポインタ演算を使う意味ないし。

この大きく分けて2つの使い方があるってのが、
ポインタの複雑さなんだろうな。
>>270
配列の途中から途中までを関数に渡して処理させる場合。例えば

int a[10];
sort(&a[5], 5);

とか。
>>279
な、なんかキワどいコードだね・・・。
まぁ、簡潔に見せるために、省略してるんだろうけど。
結局、ポインタは goto とかと同じで、
あれば便利、なくても問題ないなら別にいい
ってレベルの様な気がする
>>281
昔のC言語の教科書のレベルでも、
文字列操作とか、FILE* とか、ポインタは使うのですが。
要は
ポインタは難しいね、
って言われるようなポインタの利用法は
使い道自体が難しいってことかもな。
直感的にわかりづらくなるのは間違いないし。
でも少なくともポインタわからないて言う人にはプログラム書いてほしくない
285281:04/06/12 19:39
>>282
でもポインタ使っていることを意識させない言語もあるでしょ
仮に言語レベルで隠すことが出来ればそっちのほうが初心には分かり易いんじゃないかって話

>>284 の言うとおり、分かっていた方が断然良いがな
ポインタというか
所有の概念やaliasing、deep/shallow copyみたいなのが
初心者を挫折しやすいんじゃないだろうか
よくはしらないが

どのみち他の言語でも学ばなければならないことだ
Cのポインタの違いはより機械の実装に近いというだけだろう
>>286
逆にポインタを知らないから、浅い/深いコピーとかの違いが分からなくなるんじゃないか?
記述の難しさと、ポインタを意識する/意識しない部分の接合性が上手くいっていないのが、
原因の様な気がする

C は前者、Java は後者 (Java にはポインタなんて用語はねぇがな)
というかそもそもポインタの何がわからんのか
初心者に小一時間問い詰めないと空振りっぽい。
何がわかんないのかわかんない
290デフォルトの名無しさん:04/06/12 23:53
思うに
「変数は入れ物」の世界から
「値にアドレスでアクセスする」の世界への
対応が出来てねーんじゃねーかと。
Windowsのショートカットみたいなもの
Tronの仮身みたいなもの
Javaはしらんが、C++ならデバッグでメモリウィンドウ見せれば一発だろ
C++ Win32なんだけど、
「thisはC++で定義されているオブジェクト自身へのポインタ」
なんて表記だと煙に巻かれた気がする。
実際
CPaintDC dc(this);
とかはもうイディオムで覚えてるし、これとreturn *this;を除いて、
突然、メンバの呼び出しで使われると困惑するよ。
基本的には変数ポインタと変わらないはずなんだけど、
俺がクラスを分かってないのか

あ、当然、職業プログラマじゃなく勉強中ね。
そういえば俺ッちもポインタってつまづいた。
非常にインチキな入門書を買ってしまいましてね。
ポインタの説明が数ページしかないの。
「変数箱の荷札」のようなそれはそれは恐ろしい説明であった。
使い道も使用法も意味不明だったし。
マイバイブルとか言っちゃって、
わかんないから何度も何度もよみかえしちゃって、
C言語はむつかしいね〜とか脳みそに植えつけられる結果となった。
296デフォルトの名無しさん:04/06/13 01:12
297デフォルトの名無しさん:04/06/13 01:47
ポインタそのものの説明は難しくないんじゃないか?

ポインタの概念的な説明だけされても、
これが一体何の役に立つのかがわからんから、
初心者は難しく感じるんじゃないかと思う。

ゆえに、ポインタを使わんと解決できない問題を与えるのがいいかと。
ポインタとアドレスの関係は
住所録と住所の関係なり
そんなもんで悩むな
Cを習うのなら基本的なコンピュータのしくみ(概念的な)は勉強しとけってことですな。メモリとアドレスがわかってればポインタを難しいとは思わないはず。プログラミングする上での技巧的な問題はあるけど、それは良質のサンプルソースを提示すりゃ済む問題です。
そういったことを気にせず手軽に使いたいならもっと高級な言語使えばいいことだし。
昔は選択肢がなかったのかもしれないけど、今はCPUも早いし、メモリも大量に積めるし、コンパイラも優秀だし、高級言語でまったく問題ないはず。
>299
>そういったことを気にせず手軽に使いたいならもっと高級な言語使えばいいことだし。

だからこそ、VBがここまで普及してる罠。
>>299
>それは良質のサンプルソースを提示すりゃ済む問題です。

ちょっと分けてもらえませんか?
漏れはポインタが難しいとは思わなかったな。
PCを入手する前に、本で大体覚えたし。
でも本のおかげで、ミスると暴走するというイメージが植え付けられて、
最初は使うのが怖かったな。

苦手意識の何割かは、ポインタの難しさそのものではなく「怖さ」なんじゃないかと思われ。
ポインタが難しいとは思わんが
ポインタを難しいと思っている人には
ポインタを使ったコーディングを(仕事で)
させるのはまずいだろうな
ま、そのへんはCはアセンブラをわかりにくくしたようなもんだししょうがなかんべ
配列が理解できれば、あと一歩だと思うんだが。
306デフォルトの名無しさん:04/06/14 14:25
あと解説書とかにありがちなんだが、サンプルで完全に完結してない処理を記述するのは
どうかと思う。

学生のころポインタの説明でいきなり定義したポインタに値設定するような記述があったり
して非常に混乱した記憶が。

説明に不必要でも扱ってよい領域をポインタに設定して書き込みを行うという一連の動作に問題ないサンプルソースにするべきだと思ったがどうよ?
日本語お上手ですね
308デフォルトの名無しさん:04/06/14 14:34
>>307
韓国から出稼ぎにきてる方ですか?
はい、そうです
>>306
そこで「つくわか@void」ですよ。
>>305
配列とポインタを同列で考えると危険じゃなかんべ?
配列をポインタで表現することはできるが
ポインタを配列で表現することは・・・
313デフォルトの名無しさん:04/06/15 22:07
 ポインタ:地図
これさえあればどこへでもいけるはず……、なんだけど駄目な奴が扱うととんでもないことに。

 参照:カーナビ
上のがよくわかっていない奴にはこっちの方がまだ安心できる(かも)。が、(当たり前だが)完璧に信用できるわけではない。

 ポインタでも参照でもない変数等:駅〜家などよく通る道
言わずもがな。
だから、ポインタと参照の違いを言うなら、ポインタでのアドレス演算が例えれてないとダメなんだよ。
しかもなんだ?完璧に信用できるわけではないって。

紙の地図は更新されないけど、カーナビの地図なら目的地が変われば更新できるしくみがある、という点はその例えでいいけど。
>>313
よけいわからんなるわそれ
>>313
> ポインタでも参照でもない変数等:駅〜家などよく通る道
>言わずもがな。

全然わからん。せめてなにか言ってくれ
[数字の場合]
int a = 5;
int *aP;       int型のアドレスを入れたい時はポインタもint
aP = &a;       を付けると先頭アドレス
printf("%d", *aP);  *を付けると値

[文字の場合]
char a[] = "Hello";
char *aP;       char型のアドレスを入れたい時はポインタもchar
aP = a;        変数名だけで先頭アドレス
printf("%s", *aP);  *を付けると値

ポインタは変数の値を間接参照(アドレスを指定)する時に使う。
変数名, *, & 等ごちゃごちゃ出てくるからややこしくなっているだけ
318デフォルトの名無しさん:04/06/16 10:50
ポインタとは配列のインデックス番号のことです。
319デフォルトの名無しさん:04/06/16 10:54
変数へのポインタの場合は、
変数を要素数が1つの配列と考えてください。
320デフォルトの名無しさん:04/06/16 10:56
文字列は文字の配列と考えてください。
321デフォルトの名無しさん:04/06/16 10:59
ポインタとは配列のインデックス番号ですが、
通常の配列のインデックス番号が0からはじまるのに対して、
ポインタの場合はメモリ全体を大きな一つの配列とみなしたときの
インデックス番号なので注意してください。
「コンピュータというのは CPU があってメモリがあって CPU にはメモリの位置を示すレジスタがあるのだ」
などという基礎的な観点を礎に「アドレス」という語を使うべきなのか。
それとも「高級言語というのはアーキテクチャを隠蔽してもなお存立できうるべきなのだ」
などという観点から「アドレス」という語を避けるべきなのか。

俺は勉強する順番は基礎からの方がいいと思うんだが、
そんなものを全部飛び越えていきなり C++ やら Java やらやってる即席プログラマもいるわけで、
そういう連中に説明するには後者の方がいいんだろうかなぁ。
禿同。基礎からやれ。まずはCPUの仕組みから。
禿同。基礎からやれ。まずは半導体の仕組みから。
禿同。SQLなんて使うのは5年くらい経験つんでからにしろ。
禿同基礎からやらんと話にならん。







そうおもって、量子力学にまで興味を持ってしまってわけかわらなくなってる今日この頃orz...
廃人になりかけてる気がする...
とまあ、低レベルを基礎だと勘違いしてみるわけだな。
>326
俺も量子力学は良く分からんが
少なくとも難易度では
易:ポインタ<<<<<|越えられない壁|<<<<<<|越えられない壁|<<<<<<量子力学:難
である事は確か
329デフォルトの名無しさん:04/06/16 18:05
数学の「形式主義」的な立場からすれば、
そこに "矛盾" が生じない限り、
コンピュータの基礎から理解する
必要性は全く生じない筈なんだがな・・・
たとえばデータベースのフロントエンド作る場合、低レベルのことを知っておく必要はほとんどない。
たとえばSEをやる場合、プログラミングの技法を知っておく必要はほとんどない。
たとえばカレーライスを作る場合、ニュートリノのことを知っておく必要はほとんど無い。
例えばスパゲティを食べるとき、赤方偏移のことを知っておく必要はほとんどない。
たとえば顧客をやる場合、要求が実現可能かどうか知っておく必要はほとんどない。
たとえばシステムを構築する場合、それが実際に役に立つかどうかを知っておく必要はほとんどない。
ポインタ無くてどうやって動的確保するのよ。
ああ、コンテナがあった!
だからポインタなんて覚えなくていいよ。
ポインタと動的確保は関係ない罠。
>>337
関係無いってどういう意味でいってるの?
少なくともコーディングレベルでは大いに関係あるわけだし。
ポインタ、つまり計算可能なアドレスがなくても、動的確保はできる。
ほとんどの処理系が動的確保したメモリ領域のアドレスを管理するけど、アドレスと無関係なIDを振ってもいいわけだし。
Win32のGlobalAllocとかみたいに直接のアドレスじゃないこともある。
それに動的確保した領域のアドレスについて、演算ができる必要はないし。
それは一部の特殊な例ではないのですか?
ほんとにそういうことが一般的な開発者だったらスマソ
>>317
をい、間違っているぞ。

> printf("%s", *aP);  *を付けると値
>>340
特殊かどうかは知らんけど、Win32は多く使われているよね。
俺が言いたいのは、本質的には関係がない、ということ。
実装上関係がある処理系が多いというだけでね。
>>341
たしかに・・・。
間違っていました m(__)m
ポインタなんて低レベルな参照と言えば誰でもすぐに納得できる。
>>344
参照って何ですか?
>>345
参照はC++にもJavaにもVBにもあるんだが、一体君はどの言語が使えるんだ?
まさかCだけか?
>>344
ポインタに悩んでいるような香具師が既にJavaやC++をやっていて
参照を知っているとはとうてい思えないのだが・・・。
>>347
VBが抜けているぞw

C++はともかくJavaやVBで参照を知らずにプログラミングすることは出来ない。
JavaやVBを知っているということは参照を知っていると言うこと。

君はポインタに悩む奴は、JavaやC++やVBをやっていないと言いたいのか?
逆にいえばJavaやC++やVBをやっている人間はポインタを知っていると
そういうことだね。
VBってなんだっけ?ヴァーベキュー?
>>348
JavaやVBなら、参照しらなくてもプログラムできるよ。
351347:04/06/17 00:05
>>348

> VBが抜けているぞw
VBなんてただ漏れが知らなかったから書かなかっただけだよ。
つーか参照がある言語なんて他にもあるだろ。

> 君はポインタに悩む奴は、JavaやC++やVBをやっていないと言いたいのか?
違う。「参照を理解している」≠「やっている」。

漏れが言いたいのはポインタを説明をするのに参照を持ち出すのは
適切ではないということだけだ。

> 逆にいえばJavaやC++やVBをやっている人間はポインタを知っていると
> そういうことだね。
んなことは言ってないよ。

ポインタについて悩む香具師≠参照を理解している香具師

参照の概念がある言語をやったことのある香具師=ポインタを理解している香具師
とはならないと思うのだが。
参照の概念だけでポインタ演算がない言語でも(JavaなりVBなり)
ディープコピーとシャローコピーの違いがわかっている人は
ポインタも理解していると言えると思う。
>>352
そうでもない。ウチの会社のサブレト厨は
オブジェクトのコピーメソッドは用意してるけど
ポインタについて全く理解してない。手順として知ってるだけ。
Javaにはポインタは無いとかいまだに言ってるし。
zyabaってポインタあるの?


Unko unko = new Unko();
Unko refUnko = unko;

どれがポインタになるの
>>354
考えるな、感じろ
>>354
わかっていて聞くあたりいやらしいな

マジレスすると
その中にはなくて
NullPointerExceptionの
5文字目から11文字目の中に隠れている。
>>353
アドレス演算可能なポインタはない。
ポインタとは
  (1) メモリ上の位置を一意に特定できる。
  (2) 「何も指していない」状態を持つこともできる。
  (3) 「何を指しているか判らない」状態を持つこともあって、非常に困る。
を満たさねばならず、従って「Java にはポインタはない」
359263:04/06/17 11:44
unsigned char c = 100;
unsigned long* p;
p = (unsigned long*) &c;

このとき,*p が 100 になることを期待したいんだが,
ならない.
なんでか,おしえて
>>359
アドレス&cの前後に0以外の数値が格納されているから。
>>358
指し示す型のサイズによる演算が可能、という大切なものが抜けている。
>>359
あっちこっちで聞くな、ぼけぇ。
>>361
ようするに配列のインデックスに使っている変数は
増やしたり減らしたりできるってことだろ?
変数なんだから別に当たり前。
>>358
> ポインタとは
>   (1) メモリ上の位置を一意に特定できる。
>   (2) 「何も指していない」状態を持つこともできる。
>   (3) 「何を指しているか判らない」状態を持つこともあって、非常に困る。
> を満たさねばならず、従って「Java にはポインタはない」
Javaに無いのは(3)だけだな。
>>363
値を増やしたり減らしたりできない変数をもつ言語も多いですよ。
(4)任意の値を設定可能
(5)指し示す型のサイズによる増減が可能
>>364
Cの場合は0番地を指すことになるから、(2)を満たさないということは、アレはポインターじゃないのかね?
368デフォルトの名無しさん:04/06/17 14:13
変数を箱にたとえた時点で初心者はパニクるみたいよ。
よく考えたら、(3)も、Cの場合は何を指しているかわからないということはなくて、必ず何かを指していて、そこに意味があるかないかだけだから、やっぱりCにもポインタはないということか。
なんかすごい結論になっちゃったなw
大きなウソをつくためには、どこかに小さなもっともらしいウソを織り交ぜればよい、というのはホントだな。
372デフォルトの名無しさん:04/06/17 14:35
>>369
何を指しているのか分からないというのは、どんな型を指しているのか分からないということだろ。
要するにCではvoid *
ということはint* は「何を指しているか判らない」状態にはならないから、ポインタではない、ってことですね?
>>367
Cにおけるぬるぽいんたは、0番地を指しているわけではない。

>>369
どこかを指しているが、何を指しているかはわからない。
ということだ。アドレスの範囲外である場合もある。
>>374
そういうのは、「何を指しているのか判らない」状態というのかね?
じゃあ、「何を指しているのか判る」状態というのもあるのかね?
本質からはずれるいっぽうだなw
本質から外れた定義というのは、たのしいね。

とりあえず、Cのアレは、それ自身では有効なアドレスを指しているか無効なアドレスを指しているかわからないから、「何を指してるか判らない」状態はもたないね。
ということで、Cのアレは、>>358の定義によれば、やっぱりポインタではないと。
何を指しているかわからない状態のポインタを操作して、ある特定のものを指す。
この時点で、ポインタが指しているものを特定することができる。
わけわか。
補足きぼんぬ。
int a = random();
みたいなことができることから「int型は、どんな数値をもつか判らない状態をもつ」とはいわんだろ。
ポインタは、どこかを必ず指すんだよ。
ポインタが指している場所に意味があるかどうかは、ポインタの機能ではない。
>>380
int a;
の方が適切だな。
>>358 は、
(3) というデメリットをあえて持ち出すことで、
Java はポインタのない欠陥言語だ、という体裁の定義を作りつつ、
その実 C を揶揄しているという、ウィットに富んだレスをしたかったのだと思うが、
しかし実際は「C ではポインタ変数に何でも代入できる」という、
言ってみれば単なる言語仕様のあやというべき程度のことであり、
それがゆえにレスの意図がみなつかめず、事態は紛糾してしまったと僕は分析する、
それはそうと、(void*)0が無効なポインタであるというのは、言語の定義?処理系の実装?
385デフォルトの名無しさん:04/06/17 15:42
>>384
「どこも指していない」というのは言語の定義。
>>383
> (3) というデメリットをあえて持ち出すことで、
> Java はポインタのない欠陥言語だ、という体裁の定義を作りつつ、
いや(3)というデメリットを持ち出したことで、
ポインタにはデメリットがある。
ポインタは無い方が良いと暗に示したのだろう。
>>322
どっちが先でもいいと思う(むしろ言語をある程度触ってからのほうがよい気はする)が、まとまった時間の取れるときにコンピュータの基礎はやっておいた方がよい気はする。
基礎と言っても電磁気学レベルまで降りる必要はないけど、CPUアーキテクチャマニュアルを読める程度にはなっておいたほうがよい希ガス
電磁気はいらんけど、電気回路・電子回路はやっておいた方がよい奇カズ
電子計算機の基礎とソフトウェアの基礎は別なんだけどね。
>>384
C言語の規格で0は無効なポインタとは決められているはず
NULLは常に0(あるいは0Lだったり(void*)0だったり)で1や-1はだめだったはず
Cを始める前に少しだけアセンブラでレジスタを使うことを教えておけばポインタなんて簡単。
逆にそれを教えないと根本的な理解は難しいと思う。
ハンドルとイテレータの概念だけ知ってれば機械語レベルでの挙動なんぞ知らんでも
ポインタは理解できると思うが。
>>390
無効なポインタを整数にキャストしたら0になるだけで、
ビット表現が0かどうかは保証してない。
>>393
ビット表現が0でなくてもCのソースコード上では0であることが保証されている。
http://www.catnet.ne.jp/kouno/c_faq/c5.html#5
0でmemsetできない以上、ソースコード上は0なんて断言するのは誤解のもと。
ポインタが有効かどうか、誰がどうやって判断するのよ。
無効なポインタをキャストしたら0になるなんて、どうやって実現するのよ。
ぬるぽの話してんの?
>>397
ガッ
>>396
Cの中の人ががんばる
>>399
本気で言ってるの?
こういうマシンでC動かそうとしたら、コンパイラががんばるしかないんじゃない?
http://www.catnet.ne.jp/kouno/c_faq/c5.html#17
>>391
レジスタ教えるのだって楽じゃないよ。CPUとは何であるから始めないと。
>>402
ポインタを理解している人って組んでて自然にニーモニックがこんな感じになるのかな〜って出てきたりしない?
404デフォルトの名無しさん:04/06/18 01:39
「コンパイラが頑張る」とか言ってる人は是非「バカの壁」を読んでみてください。オススメです。
>>404
んなことバカに言われてもなぁー
>>405
バカな人の典型的なレスですね(笑)
とりあえず本を読んでくださいね。
407デフォルトの名無しさん:04/06/18 09:43
>>404
どのような点で?
>無効なポインタをキャストしたら0になるなんて、どうやって実現するのよ。
例え有効でも、違う型からポインタへのキャストは全部無効にしちゃえばいい
409デフォルトの名無しさん:04/06/18 10:02
ここは、「最高に頭悪そうな発言をしてください」スレですか?
>>406
買って送ってくれ。
そしたら読んでみようかと考えないでもない。
別に送ってくれなくても、ここに全部書き込んでくれればいいよ。
>>403
メモリマップのようなものは思い浮かべるが、
ニーモニックは思い浮かべない。
>>403
アセンブラもわかるけど、CやらC++で組んでてニモニックが出てくることはない。
自然に出てきたら邪魔以外の何者でもないし、
出てこさせなきゃ組めないような愚か者でもない。
ようするに高級言語に慣れてないだけ?
Cのコード書いてて自然と頭がニモニクってくるヤツって
激しく仕事遅そうだなw
おそらく業種が違うからでしょ。
片やWinなどでのシステム開発、片や組み込み関連の業種の人でしょ。
WindowsアプリでVC++とかだったら、ニモニック想像したところで、実際とはまったく違うコードになってそうだしな。
組み込みやっててもポインタ周りでニモニック出て来ることはないけどなぁ。
楽に理解したいなら、やっぱアセンブラから始めるのが良いかと。

いまどきのOSは物理メモリなんぞは隠蔽してるから、枝葉の質問は遠回りになるだけだしな。
それを楽というかどうかだな。
>416
インタープリンタな人でつね。
アセンブラといっても複雑になった今のCPUを使うのは時間が無駄。
できるだけシンプルかつポインタやメモリを理解するのに、
必要最小限のものを選んだ方が良い。

ということでアセンブラはCASLがいいよ。
基本情報技術者試験を受けておけばいい。
CASLもいいけどZ80もシンプルでいいよ。
425353:04/06/19 00:04
>>420
アセンブラ*から*はきついと思う
軽くCやってからアセンブラに入りまた戻ってくるほうが
学習した事柄が補完しあっていいんじゃないかな
426425:04/06/19 00:05
ごめん別スレの名前残したままだった
353じゃないです
>>424
つまり、MSXエミュレータでゲームを作れ、と。
>>425
そんなカリキュラムがあったらイイかも。
Cのインラインアセンブラで。
int main(int argc, char **argv)
{
asm("...");
...
}

カコイイ
>>425
うちの大学のカリキュラムはそんな感じです。
C言語は自分でやれとか言われますが...
>>425
俺はたまたま仕事上でその道を歩んだから幸運だった。

PICマイコンのセットなんかいいと思うよ。
Windowsでイジれちゃうし。
RISC系か68000あたりが良いと思うが。ルール面倒なんでマクロアセンブラでw

同じ処理をアセンブラとCで書いてみればすぐわかる希ガス
>>432
>PICマイコンのセットなんかいいと思うよ。

それは、およそ考えうる限りの中でも最悪の選択だと思うが・・・
試しに PIC 上のイメージで "ローカル変数" の概念を説明してみれ。
>434
>432はポインタを学ぶには、アセンブラが良いと言ってるだけであって
他の事には、触れてないと思うのだが。

アセンブラでクラスがどのように配置されるのかとか俺にはさぱーり分からん。
ま、言語の向き不向きって事で
ダブルポインタがよくわかりません・・・

---------------------------------------------
void func(char *, char **);
main()
{
char *namber[] = {"one", "two", "three"};
char *string = "hoge";
printf("%s:%s\n", string, *number);
func(string, *number);
}

void func(char *string, char **namber)
{
printf("%s:%s\n",string, *number);
}
---------------------------------------------
上記をコンパイルするとfunc関数の第2パラメータのところで
エラーがでます。*numberのアスタリスクをはずして
func(string, number);
とすれば問題なくコンパイルが通り正しい実行結果も得られるのですが
なぜ*をつけては駄目なのでしょうか?printfの場合は逆につけないと
上手く動作しません・・・
437デフォルトの名無しさん:04/06/22 01:18
>436
デバッガーでnumberの値、*numberの値を見てから再度質問にこい。
>>436
ダブルポインタがが分からないんじゃなくて
型と配列を理解していないだけでしょ
int配列で考えてみたら?
ダブルポインタは出てこんよ
439デフォルトの名無しさん:04/06/22 03:02
説明:ポインタとはメモリのアドレスのことです。
俺:へー。

これで理解出来てしまったから俺にはうまい説明は出来ない。
>>439
それだけで理解できたってのは適正があったんだな
って、普通この程度で理解出来て当たり前かも.....

漏れなんか、1時間先輩に説明してもらって分からず
コーヒーカップとコーヒーの説明でようやく理解したorz
それは、「理解した気になってもらって開放してもらった」という表現が適切である。
こういうよく分からない状態から急に理解してすっきりした後の状態って
いったい脳の中で何が起こってるんだろう。
この変化がすべての人間に共通の変化の仕方をするのであれば
ポインタ薬だかポインタ音楽を処方すると自動的に理解するようにはできないだろうか。
もし可能になれば学校なんていらなくなるね。
義務教育と新入社員研修全部で3日で終わるよ。
>>442
人口の多い中国人にすべて奪われて終わりです。
つーか、ポインタなんて学校で習うなよ。社員研修で教えるなよ。
本一冊読んで、適当に練習すりゃ、使えるようになるでしょ?

俺はBorland C++のマニュアルの言語仕様を読んでC言語を習得したよ。
独学は勘違いしてても気が付かなかったりするよね
446444:04/06/22 17:51
適切な使い方だけ教えればいい。
適切な使い方なんぞ独学で充分。
必要なのは*不適切な使い方*を教え禁止することだろ。
ま、教育を社員の独学に頼る企業は、人を育てる気がない、ということになるわけですが。
両手くらいの数の言語を使い分けるわけだから、いちいち教えてらんないよ。
わからないところだけ聞く相手がいて、コードレビューすれば、教育としては十分でしょ。
つーか、常に新しいことを学び続けるのがプログラマなんだから、
人を育てる = 学ぶ時間を業務時間内に確保する
だけでよいと思うよ。
>449
両手もの数って、、、
そもそもそんなに言語あるのか?
10や20はつかうでそ。
#1024とか言うなよ。
1024くらい余裕であるだろ
HSPとかツクールも含めていいならそんくらいはあるな。
HSPは言語仕様があるからまだしも、ツクールってあったか?w
>>450
単純にJavaでサイト作ったとしても
Java・SQL・HTML・JavaScript・EL・JSTL
くらい使う
そこにVBとかPHPとかPerlみたいな使えて当たり前のものとか、C/C++/Delphiとか含めれば、軽く10は越える。
http://directory.google.com/Top/Computers/Programming/Languages/
重複分やプログラミング言語じゃねだろうっての外しても両手両足は越えるな。
組み込みマクロなんかも数に入れるか?
Z80 8086 68000 6502 6809 R3000
オレが使えるアセンブラでも6個か・・・。
言語の数でどうのこうのいうのは、プログラムがまだわかってない証拠だな。
>>455
言語を混在して用いるのはその相で最適なものを用いるからだが
ほんというと相/層ごとに開発単位を分けたほうが
開発効率は上がるしバグも少なくなるんだよね
外設にひっぱられた縦割開発のところが多いけど
そうすると個々の開発者に万能を要求するわけだが
実際にはそうではないから(とくに新人は)個々の弱いところに
バグが出てシステムにむらができる
ソースコードひとつとっても全然違う構造になったりする
>>459
規模にもよるし、プロセスの問題は、ある組織で開発効率や品質があがったからといって、それがほかの組織にも適用できるとは限らないし、ここではそういう話をしてるわけじゃない。
ぽっぽっぽ♪
ぬるぽっぽ♪
>>461
ガッガッガッ
ガガガッガッ
やっぱよくわからんが使ってるってやついるのかな?

およそポインタ。
>>463
ほとんどそうじゃない?
動けばいいし。
しかし構造体のネストはポインタ理解してても吐血するほど迷う
???
関係ないじゃん。
しかし巡回サラリーマン問題を遺伝的アルゴリズムで妥当な解を求めるのは、ポインタ理解してても吐血するほど迷う。
しかし右足から風呂に入るのか左足から風呂に入るのかはポインタを理解してても吐血するほど迷う
しかし壊れたMDデッキのかわりにまたMDを買うかMP3プレイヤを買ってMD環境にグッバイするかはポインタを理解してても吐血するほど迷う
何でテンプレ化してるんだw
俺は、ポインタ理解してるから、何も迷わないぜ。

>>465 がんがんネスト汁!
>>467 実際にサラリーマンを巡回汁!
>>468 右足からの方が折れ好みだ!
>>469 あえてカセットテープに汁!
しかし、C++Builder6Personalと妻みぐい2を一緒に買ったほうがいいのかどうかは、ポインタ理解してても射精するほど迷う
>>472
いまはクラナドと買うのがいいよ
>>473
ポインタ理解してても?
>>474
そう。ポインタ理解してても。
>>475
おっけー。
このスレの300あたりからずっと悩んでたんだけど、解決した。
>>464
それはおまえだけだ。オレは理解してるよ。およそポインタ。
>>477
そういうオマエは、風呂に入るとき右足から?左足から?
悩まない?
>>478
俺は頭から入るね。
>>479
ああ、俺も。さすがポインタ理解してる奴は話せるな。
>>480
ポインタ理解してないので、ついていけない・・・
>>480
ポインタ理解していても、ついていきたくない・・・


ところでさ、
  int *p;
ってした場合、「int」型の変数「*p」っても読めるんだよな
じゃなんで C の開発者は
  int *p = &a;
なんて初期化式を考えたんだろか?
>>482
読めるけど、実際はそうではないから。
「int」型を扱える「*p」とは読んでいいだろうけど。
スレ違いかもしれんが・・・。

Javaのオブジェクトは標準でポインタで扱ってるよなぁ、
C++使ってる俺には、標準でポインタにする意味がわからん。
標準でvirtualだからかも知れんが。
>>484
標準で実体を扱う意味の方がもっとわからん。
newした場合はdeleteが必要だからかもしれんが。
>>485
>標準で実体を扱う意味の方がもっとわからん。

 返り値(無論関数の)にしたとき
>>486と同じ理由があるので面倒。
実体を関数のローカル変数とした場合は、やっぱスタックに積む?
その場合、ヒープにとるより高速だったり?
 ポインタ(メモリマップド)で汎用レジスタっていじれる?
ちなみに、インテル系CPUの・・・。
BCCだからインラインアセンブラ使えないポ。
いじれません
BCCはインラインアセンブラ使えるでしょ。コンパイラくらい買いなよ。

汎用レジスタには番地がないからポインタではない。
しかし、擬似レジスタ変数で読み書きできるよ。_EAXとか。
>>491
Tenx!!

>>490
>>491
メモリマップド対応のレジスタはインテル系では無いんですか?
参考までに・・・。
汎用レジスタがメモリアドレスにマップされているCPUってあるの?
それって単に汎用レジスタが無いCPU?
メモリマップトi/oは知ってるがレジスタは知らんかった・・
495492:04/07/06 18:42
>>494
 ナルホド、周辺I/Oレジスタはレジスタとは別もんですたか・・・。
そろそろ、ポインタと無縁になりそうなのでこの辺にしときまつ。
>>493,494
TMS9900でぐぐれ
**********************************************************************a
498デフォルトの名無しさん:04/07/07 14:22
void a();という関数があったとすれば、上のやつに関数呼び出しの()をつけたものでも呼び出せるはず。
POINTERの実際

int a[1][1];
int *b;

a = "hoge";
b=a[1];

printf("%s",b[0]);

とすると

  hoge
>>482

int a = 123;

とかと構文を統一したかったから。
>>499
エラーだろ
ポインタ→アドレスを格納する変数
ポインタ以外→値を格納する変数

どう使うかは、使う側の問題。
実体指してない(有効なアドレスを設定していない(ポインタの)変数)状態で、
使わなければ桶

それだけ。
所詮変数でしかない。
>>502
ポインタ変数→値を格納する変数
ポインタ以外の変数→値を格納する変数
>>499がなにを言いたいのか分からないので
誰か通訳してくださると大変便利
int型の変数:数値を格納する変数
ポインタ変数:ポインタの値を格納する変数
>>502
ポインタが変数でしかないかどうかは実装によるよな
ポインタはその言語でのポインタの定義を満たす「なにか」であればいいだけで
アドレス値を実態とする32(or64or16or8)bit変数である必要もない
ヌルポインタの実態が0でなくてもよいのといっしょで
ポインタを格納する変数は、所詮変数だが、ポインタは値の種類のことであって、間違っても変数ではない。
>>506
C/C++以外で、ポインタがある言語教えてください。
Pascal
PascalとC/C++のポインタの違いを教えてください。
お好みの宿題スレへどうぞ。
>>511
つまり、知らない、と。
>>510
表記の違い
逆参照演算子 *p が p^ になったりとか
>>508
ActiveBasic
VisualBasicもないとは言えない
>>513
機能的には違いないのかな?足し算引き算できるかどうかとか。
int *a;
があるとして、a[n]というのが*(a + n)と等価になるか、とか。
>>514
Javaの参照みたいな、「ポインタと同じような役割の、違う名前のしくみ」は除くよ。
>>516
VBには密かに変数/文字列変数/オブジェクト変数のアドレスを取得するVarPtr/StrPtr/ObjPtrって関数と、
関数のアドレスを取得するAddressOf演算子がある。逆参照演算子/関数はないけど。

ABはもっとしっかりしていてポインタ型として〜Ptrが存在し、VarPtr/StrPtrでアドレスを得られる。
Get〜系の関数で値を読み込めて、Set〜系の関数で値を書き込める。(〜には型名が当てはめる)
あるいは配列添え字の[]も使えるし、構造体ポインタなら->が使える。
(ただし、あいかわらず関数ポインタから関数を呼び出すことはできない)
>>517
VBのは、アドレスが取得できるというだけで、ポインタがあるとはいえないね。
519デフォルトの名無しさん:04/08/06 22:39
>>517
関数ポインタは条件さえ良ければEnum〜系列挙関数やCreateProcessなんかに渡してWindowsが呼び出させることができる。
520デフォルトの名無しさん:04/08/07 02:36
>>519
日本語勉強してください。
521デフォルトの名無しさん:04/11/13 08:31:15
かんたんじゃん
522デフォルトの名無しさん:05/01/25 22:30:30
523デフォルトの名無しさん:05/02/01 20:42:06 ID:Ibde1uYg BE:56172285-
ホッシュ(`・ω・´)ホッシュ
524デフォルトの名無しさん:05/02/01 20:43:09
早く削除依頼だせよ
525デフォルトの名無しさん:05/02/01 20:57:44
ぽいんたの
 教えてわかる
  むつかしさ
                 〜芭蕉〜

う〜ん、スレタイにもっとセンスを求む。
526デフォルトの名無しさん:05/02/01 21:07:57
VBってのはNETになってからクラスやらポインタやらが使えるようになって
C++と機能としては殆ど変わらなくなったと聞いたがマジっか?
527デフォルトの名無しさん:05/02/02 06:17:58
ポインタ理解度診断

・二つのポインタを受け取り、一つのポインタを返す関数へのポインタの配列の宣言を書け。
・次に前述の関数で、受け取る二つのポインタと返すポインタを、
先の関数へのポインタとして受け取る宣言を書け。
(つまり、関数自身が受け渡されたり返されたりする、関数へのポインタの配列)
・さらに、対象とする関数をクラス内のメンバ関数(プライベート)とし、
この関数へのポインタの配列の宣言の例(クラス内メンバ)を示せ。

これが出来ない奴はポインタがわかっていない奴。
(typedef,defineは使用禁止、無駄なスペースやカッコを入れてもいけない)
528デフォルトの名無しさん:05/02/02 10:05:39
char *(*func[])(char *, char *);

char *(*(*func[]))(char *(*(*func1[]))(char *, char *), char *(*(*func2[]))(char *, char *));

char *(*Klass::memb(*(*[]))[])(char *(*(*func1[]))(char *, char *), char *(*(*func2[]))(char *, char *));

529デフォルトの名無しさん:05/02/02 16:26:58
>>528
それだと、返り値が関数へのポインタになってないのでは?
530デフォルトの名無しさん:05/02/02 19:22:31
問題文の日本語がおかしいと思う
531デフォルトの名無しさん:05/02/02 21:02:04
>>1は20文字以内に説明しろって言ってんだろ。
まあ無理だな
532デフォルトの名無しさん:05/02/02 23:12:44
ポインタよりも、printfの%の後に何付けるかの方が
よっぽど気になる。  わたしだけ?
533デフォルトの名無しさん:05/02/03 00:19:51
漏れはポインタ以前に日本語が駄目なことが判明した。
>>527の意図がまったく理解できない。
> ・次に前述の関数で、受け取る二つのポインタと返すポインタを、
> 先の関数へのポインタとして受け取る宣言を書け。
> (つまり、関数自身が受け渡されたり返されたりする、関数へのポインタの配列)

前述の関数(二つのポインタを受け取り、一つのポインタを返す関数)における「受け取る二つのポインタと返すポインタ」
を、
「先の関数(「前述の関数」と同じ?)へのポインタ」として受け取る
宣言を書け。

?????「先の関数へのポインタとして受け取る」?「前述の関数で受け取る二つのポインタと返すポインタ」を?

つまり、
 関数自身が受け渡されたり返されたりする関数
  へのポインタ
   の配列

「つまり」????ということは前半と後半の記述は「同じことを説明している」わけか????
俺の脳内パーサが異常な量のエラーを吐いて落ちたので続行不能。

534デフォルトの名無しさん:05/02/03 00:23:46
なぜ異種言語でもリンクできるのかとか、仮想アドレスとはとか、
マシン語ハードコーディング以降の高級言語を使う人でもヒントになることは多いと思うのですが...
535533:05/02/03 00:36:06
あ、ようやく意味がわかってきた。
つまり、
「引数を二つ取り、値を返す関数を定義せよ。引数と返値の型は、先の関数へのポインタとする」
と言いたかったのか。
>>527はまず日本語を理解しろ。頭がもげるかと思った。
536デフォルトの名無しさん:05/02/03 00:57:10
>>527は、こういうことなのかな?

関数A :
 戻り値 : char*
 引数 : char*, char*

関数B :
 戻り値 : 関数Aと同タイプの関数へのポインタ
 引数 : 関数Aと同タイプの関数へのポインタ

問題 1)
 関数Aと同じタイプの関数へのポインタの配列を宣言(要素数N)。

問題 2)
 関数Bと同じタイプの関数へのポインタの配列を宣言(要素数N)。

問題 3)
 > さらに、対象とする関数をクラス内のメンバ関数(プライベート)とし、
 「対象とする関数」が関数Aなのか関数Bなのか分かりません。
537デフォルトの名無しさん:05/02/03 02:14:28
>>536
typedef禁止が条件だから問題(2)と(3)は「文法的に記述出来ない」が正解だな
538デフォルトの名無しさん:05/02/03 14:56:00
539デフォルトの名無しさん:05/02/03 15:21:06
>>536
こんなか?

#include <stdio.h>
char* funcA_1(char *str1, char *str2 ) {
return str1;
}

char* funcA_2(char *str1, char *str2 ) {
return str2;
}

char* (*( funcB_1( char*(*funcIn)(char*,char*) ) ))(char*,char*) {
if ( funcIn == funcA_1 ) return funcA_2;
else return funcIn;
}

char* (*( funcB_2( char*(*funcIn)(char*,char*) ) ))(char*,char*) {
return funcIn;
}

int main() {
char*(*arrayA[])(char*,char*) = { funcA_1, funcA_2 };
char*(*(*arrayB[])(char*(*)(char*,char*)))(char*,char*) = { funcB_1, funcB_2 };
printf( "%s\n", arrayA[0]("test", "string") );
printf( "%s\n", arrayA[1]("test", "string") );
printf( "%s\n", arrayB[0](funcA_2)("test", "string") );
printf( "%s\n", arrayB[1](funcA_2)("test", "string") );
return 0;
}
540デフォルトの名無しさん:05/02/04 23:52:40
>>537>>539のどっちが正しいんだよ。
541デフォルトの名無しさん:05/02/05 02:15:16
>>539 は問題と全然関係ない関数定義だろ?
542デフォルトの名無しさん:05/02/05 02:24:24
みんなポインター好きだなーw
やっぱCは永遠なのか?
543フナ太郎:05/02/05 03:28:09
>>542
苦労して覚えたから誇りたいだけだよ。
544デフォルトの名無しさん:05/02/05 03:52:24
>>543 ポインタは覚えるもんじゃなくて感じるもんだと思うが
545デフォルトの名無しさん:05/02/05 04:42:55
どこが感じるの?
546デフォルトの名無しさん:05/02/05 17:53:14
マジレスすると、変数の型をしっかり理解していれば、ポインターなんてたいして難しくない。
547デフォルトの名無しさん:05/02/05 18:11:21
ポインターわかんない人ってデリゲートとかもわかんないんだろうなぁ
548デフォルトの名無しさん:05/02/05 19:24:54
char s[] = ""と
char *s = ""
の違い教えるのにめちゃ苦労したぞ。
549デフォルトの名無しさん:05/02/05 19:32:31
そうか?
どのようにコンパイルされるか見せれば簡単ジャン
550最凶VB厨房:05/02/06 15:05:13
配列(まんま値)と
配列(まんま値)の先頭アドレスが入ったポインタ
って違いでええのか?
551デフォルトの名無しさん:05/02/09 14:03:26
>>550
初期化される奴とそのまま使われる奴
下は文字列を変更しちゃいけないことになってる
552デフォルトの名無しさん:05/03/09 09:42:41
>>551
下の形式って個別のメモリに書き込もうとしたらアクセス違反が出るんだけど、
char s[1]型としての変数に""を代入したってもんと、""つー文字列が入ったアドレスが入ったポインタとの違いでOK?


char *number[] = {"one", "two", "three"};

このような形のnumberを使って個別のcharを書き換えるには(number[0][1]='p'とか)以下のようにしないと無理?

char num1[] = "one", num2[]="two", num3[]="three";
char *number[] = {num1, num2, num3};

それともうまく宣言する方法があったりするんでしょうか。
553551:05/03/14 15:00:07
>>552
一行にまとめたければこうするとか

char number[][8] = {"one", "two", "three"};

8 は、中に入る文字列の長さの最大値よりも大きくすべし
でも、これだとかなりの領域が無駄になるので注意
554デフォルトの名無しさん:2005/05/08(日) 11:53:15
>552
>このような形のnumberを使って個別のcharを書き換えるには(number[0][1]='p'とか)以下のようにしないと無理?

定義先の、"one" が置かれて居るのが定数領域に置かれているから
書き換えは出来ないんじゃなかったけな?
555デフォルトの名無しさん:2005/05/08(日) 11:59:53
>char s[] = ""と
>char *s = ""

上のは、sって配列はメモリ上のRAM領域(OSが管理している)に取られる。
s[0]はRAM領域に確保されてるから書き換えは可能。

下のは、""がROM領域に置かれている。
で、sは、その""のアドレスが入っている。
そのアドレスは、ROM領域だからs[0]='p'みたいに書き換えは出来ない。
556デフォルトの名無しさん:2005/05/08(日) 12:05:29
文字列の文字の書き換えってそれ長さは変わらないことが前提?
そうでないとオーバフロでバグの元になりかね
557デフォルトの名無しさん:2005/05/08(日) 12:46:57
情報工学が工学の劣等生である理由の一つは、
概念と用語がきちんと整理できていないことにあると思う。

「ポインタ」という言葉一つとっても、曖昧に使われていて
はっきりとした定義がない。
そのために初学者は不要の混乱をする。こんなもの本来中学生でも理解できる程度の
ものでしかないのに。

だいたいK&R程度の内容の本がありがたがられる学問っていったいなんだよ。
558デフォルトの名無しさん:2005/05/08(日) 13:57:06
>>557
いいこといったな
おまえ、Wiki立てろ。
ウィキペディアみたいに用語を定義していこうぜ。
559デフォルトの名無しさん:2005/05/08(日) 14:00:50
K&R って初級者が読む入門書でしょ
560デフォルトの名無しさん:2005/05/08(日) 14:10:59
>556
変わらないのは、前提じゃないが
長さが変わる可能性があるなら
配列の長さは、多めに確保しないといけない。

もしくは、本当の意味での可変文字列を扱うなら
mallocを使うかってバッファを超えそうになれば、
再取得するか。
561デフォルトの名無しさん:2005/05/08(日) 14:42:52
>>559
上級者が行き詰ったときにも読む
562デフォルトの名無しさん:2005/05/08(日) 14:43:55
何か勉強するために読み返すってことは無いな
悩んだりしたときに素数を数えるような気持ちで読む
563デフォルトの名無しさん:2005/05/08(日) 17:42:25
悩むことの解決に役立つ本だろうか?実践あるのみと思う
564デフォルトの名無しさん:2005/05/08(日) 18:50:13
*は解ったけど**がいまいち理解できん。
ポインタのポインタ?
int a=3;
int *p=&a;
int **pp=*&p;
は一緒?コンパイルエラー??
(int *)p=&a;と
int *p=&a;は一緒?
(int *)* pp;とint **pp;は一緒?

迷子
565デフォルトの名無しさん:2005/05/08(日) 19:04:44
>>564
悩む前にコンパイラに通せよ
566デフォルトの名無しさん:2005/05/08(日) 22:30:35
>>564
int **pp = &p;だ。

int *はint型へのポインタ。
int **はint *型へのポインタ。
int *型の変数も「変数」なんだからアドレスが存在する。
アドレスが存在する以上それを格納するポインタ型も存在する。それがint **になる。

さらにtypedef使ってこうも書ける。
HOGE a;
HOGE *p = &a;
もしtypedef int HOGE;でもtypedef int *HOGE;でもこのコード片はコンパイルできる。
(実際にはaを初期化していないのがまずいけど)
567デフォルトの名無しさん:2005/06/30(木) 21:18:56
ああああ!![]って[ ]のことかっ!!
568デフォルトの名無しさん:2005/06/30(木) 21:27:28
GR1がpでいいのですか?
569デフォルトの名無しさん
ポインタは変数のアドレス。
但し、ただのアドレスと違うところは
インクリメントやディクリメントに対して
変数のサイズ分ずつ増減するところ。

これで充分なのでは?