トップページ⇒tech
90コメント32KB

リファレンスとポインタの違い

■ このスレッドは過去ログ倉庫に格納されています
0001Rubyist!NGNG
Subject: [ruby-list:27218] C 言語ポインタ完全制覇
Mate: Thu, 18 Jan 2005 07:12:58 +0900
--------------------------------------------------------------------------------また、迷教科書の登場なのでしょうか?

リファレンス(参照)とポインタ(アドレス値)の違いって常識だと思っ
てたんだけど。

http://member.nifty.ne.jp/maebashi/seiha/hosoku001.html

Ruby >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> COBOL
0002デフォルトの名無しさんNGNG
>>1
ポインタをアドレスとして実装するかどうかも処理系の実装に依存する。
そういう意味では、参照とポインタを等価と考えても間違いではない。
0003デフォルトの名無しさんNGNG
>>2
とはいえ、参照をポインタとして実装するかどうかも処理系依存。
0004デフォルトの名無しさんNGNG
参照かポインタかは、言語の「用語の定義」による。
それが、「参照と呼ぶべきか、ポインタと呼ぶべきか」の議論は
フレームになるだけで、あまり意味が無い。

それより、ある言語の場合変数が、値を保持しているのか、値を
保持している領域を指しているのか、について知ることや、
どう実装されているかについて知ることが重要。
0005デフォルトの名無しさんNGNG
なんでルビ中のネタにマジレスが返ってんだ?
0006 NGNG
関数ポインタやポインタ操作、ポインタ型変換が出来なければポインタとは
普通は言わない。
Javaなどでどうしても参照をポインタとしたいのなら。
「全ての参照はポインタ集合の部分集合である」
といっておく。
0007デフォルトの名無しさんNGNG
「Javaはポインタしかない」
は
「Javaはポインタ相当品しかない」
の隠喩だよ。

M氏の主張する内容ではなく、ごり押しな表現に皆、うざさを感じてるのさ。
プログラマって厳密じゃないと嫌な性分だからさ。
0008デフォルトの名無しさんNGNG
おまんこ丸見え!
0009デフォルトの名無しさんNGNG
下ネタかよ!!!!
0010デフォルトの名無しさんNGNG
C++の参照って中身アドレス?
処理系とy/nを書いてもらえればうれしいです。
0011デフォルトの名無しさんNGNG
なぜ1の日付が2005年なのだろう?
0012デフォルトの名無しさんNGNG
日付じゃないよ。
「待て」
0013デフォルトの名無しさんNGNG
しかもDateじゃなくてMateになってるし...
0014デフォルトの名無しさんNGNG
参照は別名の事だから、コンパイラは例えば
そのメソッドが一つのクラス変数についてしか呼ばれていなければ
内部でポインタにする必要もない
インラインに展開される場合は特にそうする必要はない

ポインタについてはそこまでの最適化をするには 一段難しい解釈をやらなければならない
0015 NGNG
■■全ての参照はポインタ集合の部分集合である■■
と声を大にして言う。
0016デフォルトの名無しさんNGNG
Rubyってやっぱり作者がアレな人だったんだね…
0017デフォルトの名無しさんNGNG
ウゼーよ。fjでやれ
0018のんちゃんNGNG
のんちゃん
0019デフォルトの名無しさんNGNG
リファレンスは高水準な概念
ポインタは低水準な概念

ダメかな?
0020デフォルトの名無しさんNGNG
ポインタ:原始的イテレータ
リファレンス:参照

オブジェクトとして、全然違う
0021デフォルトの名無しさんNGNG
ポインタ変数は逆参照演算子を使うことにより
変数としての他に、もうひとつ左辺値を持つ。
0022デフォルトの名無しさんNGNG
C++は参照無しには成り立たないの?
ポインタだけじゃだめなこととかあるのかな。
0023デフォルトの名無しさんNGNG
>>22
サブクラスへの型変換
0024デフォルトの名無しさんNGNG
>22
operator 各種とか。
0025デフォルトの名無しさんNGNG
> 関数ポインタやポインタ操作、ポインタ型変換が出来なければポインタとは
> 普通は言わない。

CとC++しか知らない奴発見。
Pascalでは、その3つともできないが、ポインタと呼ぶぞ。
0026デフォルトの名無しさんNGNG
>25
「リファレンスとポインタ」という文脈では、
そういう解釈にはならない。
0027デフォルトの名無しさんNGNG
> 「リファレンスとポインタ」という文脈では、そういう解釈にはならない。

言い換えると、「論理的には説明はできないから黙れ」ってことだな。(w
002827NGNG
26の男!!!!!!
でてきて私の質問に答えなさーーーーーーーーーい!!!
怖気づいたのね?
中年女の恐ろしさに気づいたの?今頃?賦賦賦賦賦亞爬爬爬爬爬。


0029デフォルトの名無しさんNGNG
クソスレでおおはしゃぎ
0030デフォルトの名無しさんNGNG
>>25 そうなの? Delphiは関数ポインタもメソッドポインタも ポインタ操作も 型キャストも出来るけど

標準パスカルは出来ないのか・・・
0031デフォルトの名無しさんNGNG
リファレンスとポインタってどう違うの?

俺の心の中では ポインタは型に依存する と勝手に決めてる。
int型ポインタをインクリメントすると次のintへ移る っていうアレね。
つーかそれができないとポインタって呼べないような気がするなぁ。

リファレンスはただの参照っしょ?アドレスっつーか。
0032デフォルトの名無しさんNGNG
>31
んじゃ汎用ポインタは?
0033デフォルトの名無しさんNGNG
>>25-27
ある言語でリファレンスと呼ばれるものが、他のある言語でポインタと呼ばれたりすることはよくあるが。
ポインタとリファレンスを同じ土俵で比較するならばC++の話と言うことになるだろ。
0034デフォルトの名無しさんNGNG
>>32
汎用ポインタは汎用のポインタでしょ。
リファレンスと言い換えてもいい。

つーか ポインタ≒リファレンス ってことで決着しようよ。
なんか自分で何いってるか判らんくなってきた。
0035デフォルトの名無しさんNGNG
汎用ポインタ=イテレタでねーの。
イテレタを参照の代用として使うことはできる
(参照という言語仕様があるなら、
そういう使い方は駄目駄目)
逆は不可。
0036デフォルトの名無しさんNGNG
結論:結局よくわかりませんでした
0037デフォルトの名無しさんNGNG
とりあえず、C++限定の話でいいかな?
C++では、例外安全を保証するために、ポインタは使わない方がいいんだよね?
今まではベターCとしてコーディングしてたからソース中に
ポインタが散らばってるけど、全部リファレンスかauto_ptrに
直そうと思うんだけど。
これって、リファクタリングとしての価値があるよね?
0038ZZZZZZZNGNG
ZZZZZZZZZZZZZ
0039デフォルトの名無しさんNGNG
>>Rubyist!
クソスレ立てるのやめてください
0040デフォルトの名無しさんNGNG
   || ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄||
   || ★★荒らしは放置が一番キライ!★★
   ||    〜 荒らしは常に誰かの反応を待っています 〜
   ||
   || ●重複スレには誘導リンクを貼って放置!
   || ウザイと思ったらそのまま放置!
   ||
   || ▲放置された荒らしは煽りや自作自演であなたのレスを誘います!
   || ノセられてレスしたらその時点であなたの負け!
   ||
   || ■反撃は荒らしの滋養にして栄養であり最も喜ぶことです
   || 荒らしにエサを与えないで下さい
   ||
   || ☆枯死するまで孤独に暴れさせておいて
   || ゴミが溜まったら削除が一番です 。   ∧_∧
   ||                       \ (゚ー゚*) キホン。
   ||________________  ⊂⊂ |
      ∧ ∧    ∧ ∧    ∧ ∧    | ̄ ̄ ̄ ̄|
      (  ∧ ∧ (   ∧ ∧ (  ∧ ∧ |      |
    〜(_(  ∧ ∧ __(  ∧ ∧__(   ∧ ∧ ̄ ̄ ̄
      〜(_(  ∧ ∧_(  ∧ ∧_(   ∧ ∧  は〜い、先生。
        〜(_(   ,,)〜(_(   ,,)〜(_(   ,,)
          〜(___ノ  〜(___ノ   〜(___ノ
0041 NGNG
>>37
個人的にはその方向には踏み込まない方が・・・。
エラー処理、範囲チェック、・・・と理想を
目指して突き進んだあげく、簡単な開発でさえ
気苦労の重いものになってしまって生産性が著しく
落ちていることに気づいてしまうことはないか?
0042デフォルトの名無しさんNGNG
>>41
最初はきついかもしれないけど、体で覚えたころには当たり前にできるように
なると思うけど。
スキルの低い人と一緒に開発するときは、さすがに辛いものがあるけどね。
0043デフォルトの名無しさんNGNG
>>41=37
C++使うな。
004437NGNG
>>41
そうかな…? 新しくソースを書くことに関しては、
「ポインタ渡しにするか、リファレンス渡しにするか…」と
いちいち悩まなくてすむ分、生産性は向上しない?
自分規約がひとつ出来て、悩みがひとつ消えた気がするんだけど。
まあ、過去のソースを修正するって部分で生産性が落ちてるかも
しれないけど、これは新しい自分規約を覚えるための練習代わりとして
ちょうどいいと思ってるけどなー。

>>42
前半はほぼ同意。後半はどうなんだろう? 趣味でプログラミング
してるだけだから、共同開発なんてやったことないからわかんないよ〜。

>>43
全然違うよ。っていうか、そもそも>>42=37って言いたかったんじゃないのかな?
まあ、それも違うんだけどね。
それと、私はCとC++ぐらいしか出来ないから。
004541NGNG
わお、意外とC++で堅いコードを書くことに肯定的な人が
多いんだね。この辺の正解はチームプログラマーか個人
プレイヤーかどうか、とか、プロジェクト規模とかで
変わってくるものではあるんだけど。

>>42
いずれにしても、スキルの低い人間と組む場合は、
この辺をしっかりやらないと地獄を見るし、
しっかりやろうとするとやはり教育で地獄を
見るし、何をやっても辛いんだろうけど・・・。

>>43
はいはい、それでは何を使えば良いかご教示お願い致しますよ
JAVAでも使ってればよろしいでしょうか?(w
0046デフォルトの名無しさんNGNG
Del厨ですが、ほとんど参照渡ししてますね。
変更されたくない場合はconst渡しで
0047(´ヘ`;)ハァNGNG
なにこの本こんなドキュが書いてるの?
0048デフォルトの名無しさんNGNG
matz >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 前橋
0049デフォルトの名無しさんNGNG
matzって誰?
0050デフォルトの名無しさんNGNG
教祖様
005148653NGNG
参照をインクリメントしたらどうなるの?
0052デフォルトの名無しさんNGNG
(´-`)。o ○ (「参照をインクリメント」・・・不思議な言葉だ。)
0053デフォルトの名無しさんNGNG
(´-`)。o ○(>>51オリジナルのインクリメントと等価。)
005448653NGNG
(´-`)。o ○(>>52,>>53 ふーん)
0055デフォルトの名無しさんNGNG
参照とポインタの違いを明らかにするメリットがよくわからん。
俺には同じ物(見た目は違うかもしれないけど)に見える。
0056デフォルトの名無しさんNGNG
>>55
参照はあるオブジェクトに到達するための記述。
参照自体が1st class objectになっているものもあるし、
source code上の記述でしかないものもある。
参照の種類は言語によっても異なるし、1つの言語でも複数種類の参照が提供される。
例えば変数名はsource code上の記述でしかない参照の一種。
ポインタは参照を1st class objectとするための実装の一種。
005737NGNG
あれれれ。関数の戻り値が配列を返すときには、
ポインタをリファレンスにするにはどうしたらいいんだろう…?

// ポインタはこう。今までこれでOKだった。
DWORD* GetPallet(void)
{
  static DWORD Pallet[256];
  return Pallet;
}

// リファレンスにしてみた(つもりだ)けど、コンパイルエラー。
DWORD[]& GetPallet(void)
{
  static DWORD Pallet[256];
  return Pallet;
}

// これもコンパイルエラー。
DWORD[] GetPallet(void)
{
  static DWORD Pallet[256];
  return Pallet;
}

// こうやっても無駄だった。
DWORD[256] GetPallet(void)
{
  static DWORD Pallet[256];
  return Pallet;
}

何コレー! このポインタは消せないの〜?
005837NGNG
ちなみに、コンパイルエラーはこの関数のヘッダの方で出る。

DWORD[] GetPallet(void);

こういう風に書いてると、

構文エラー : '['

だってさ。なんで?
0059デフォルトの名無しさんNGNG
配列がオブジェクトではないから。
おとなしくvector使うか、structで包んどけ
0060デフォルトの名無しさんNGNG
前橋 vs matz
戦争勃発!!!
0061デフォルトの名無しさんNGNG
>>37
 typedef DWORD Hoge[256];

 Hoge & GetPallet(void)
 {
   static Hoge Pallet;
   return Hoge;
 }

ってのは?
0062デフォルトの名無しさんNGNG
gccにやらせると配列を返す関数は作れねぇぞゴルァ!
とか怒られます。
C++の仕様では配列を返す関数は作れないんでは?
006362NGNG
いろいろやってたら、配列自体は返せないけど、
参照ならこれでできました。

int (&getp(void))[5]{
  static int p[5]={3,6,9,12,15};
  return p;
}

main(){
  int (&h)[5]=getp();
  printf("%d",h[3]);
}
0064デフォルトの名無しさんNGNG
だって配列は配列宣言した時点で先頭アドレスが
決定されるのだろう?
DWORD[] GetPalette
の時点で返される値が決まってしまうようなもんだから、
関数の意味もない。YO?
0065デフォルトの名無しさんNGNG
あー、なんだ、
単にDWORD[]ってのがおかしいんじゃないか。
普通DWORD 変数[]だもんNA!
0066デフォルトの名無しさんNGNG
まつもとまんs−
006737NGNG
>>59
そうだね。最初に出た意見だけど、結局vectorを使うのがC++での
最上の回答のような気がするよ。structラップの方は、悪いけど
面倒だから却下ね。
(´-`).。oO(「structラップ」って今はじめて使った造語だけど…)
(´-`).。oO(語感が「ストラウストラップ」に似ているね…)

>>61
Effective C++の5項に、配列型にtypedefをするのは控えるように
書いてあるよ。それやるぐらいなら、vectorを使った方がいいんだって。
まあでも「控える理由」は delete と delete[] の混乱ってことなんだから
この場合は関係ないんだけどね。

>>62-63
すごいすごい! けど、これって記述が面倒…。この記述の面倒さを
なくそうとすると、>>61に行き着くだけかなー。

>>64
Effective C++の47項の簡易シングルトンをやりたいんだよ。そりゃもちろん
今はただのDWORD配列だから、初期化タイミングなんて意味はないんだけど。
あとあとクラスにする可能性も考えて、staticメンバ変数は全部この方法で
実装するようにしてるの。だから意味はあるよ。私の自分規約のひとつ。

>>65
でも、引数なら Hoge(DWORD[]); でオッケーだよ。引数はオッケーで
戻り値はダメって、なんか理不尽じゃない?

More Effective C++ が今日届いた。うれちー。
(´-`).。oO(けど…なんでこんなにページレイアウトがダサいの…?)
(´-`).。oO(紙質も安っぽいし…)
(´-`).。oO(Effective C++ と同じ造りにして欲しかったな…)
(´-`).。oO(第一印象サイアク…)
0068デフォルトの名無しさんNGNG
(´-`).。oO(配列と配列へのポインタと配列の先頭要素へのポインタがごっちゃになってるひと、だれですか?)
0069デフォルトの名無しさんNGNG
言語は C に限定して構わないので、
「配列へのポインタ」と「配列の先頭要素へのポインタ」
はどう区別するか教えてください。

char moji[] = "mojimoji";

これなら moji は配列の先頭要素へのポインタで、&moji[0] も
そうですよね。*moji は moji[0] と同じですよね。では配列
へのポインタは &moji ですか?
0070デフォルトの名無しさんNGNG
moji は配列だってば。
0071デフォルトの名無しさんNGNG
>67
>(´-`).。oO(Effective C++ と同じ造りにして欲しかったな…)
そうか?オレはEffective C++の表紙が硬くて嫌いだからMore Effective C++
と同じにしてほしかった。
0072reroreroNGNG
>69
・・わかるぜ、その気持ち。



char moji[]="abc";

---------------------------
| 'a' | 'b' | 'c' | '\0' |
---------------------------

んで、

配列名mojiはたしかに先頭要素を指すよ。

#include <stdio.h>

int main(void)
{
char str[]="moji";
printf("%p\n",str);
printf("%p\n",&str[0]);
printf("%c\n",*str);

return 0;

}

[hh c]$ ./a.out
0x11ffffa10
0x11ffffa10
m <-------先頭要素の文字が出力された
[hh c]$


strと&str[0]は同じアドレス。

strは先頭要素を指すポインタと「みなされる」
のであって、ポインタではない。
配列名が保持するアドレスは固定であって、定数である。
だから、strにアドレスを代入することはできない。
それに対し、ポインタは変数である。



配列へのポインタってのは

int (*a)[3]

などと表す。

これは "int型の要素を3つもった配列"をさすポインタ

である。

007369NGNG
>>70 >>72
いや、あくまで格下げされるだけで、ポインタと見なされるだけ
というのは分かります。

>配列へのポインタってのは
>
>int (*a)[3]

なるほど。これは配列へのポインタですか。関数へのポインタ
と形としては同じですね。私の挙げた例だと、&moji はあくまで
配列の先頭要素を指すポインタへのポインタというのにすぎない
わけですね。(便宜上ポインタと表現してます)

0074デフォルトの名無しさんNGNG
丁寧な言葉使いだ。
0075デフォルトの名無しさんNGNG
ポインタ=アドレス値って自体変じゃないか?
ポインタが表すのは厳密なアドレスじゃないし
表せるアドレス自体物理アドレスじゃなくて仮想アドレスだ
実際のアドレスを使ってんのはCPUのページングユニットだけちゃうん
0076デフォルトの名無しさんNGNG
(´-`).。oO(文法の話と実装の話がごっちゃになってるひと、だれですか?)
007737NGNG
>>71
でも、世間的には Effective C++ の造りの方が上質となってるはずだけど。
私の好みとしても、Effective C++ の方が良いな。
っていうかそれよりも、More Effective C++ のひどい邦訳の方が
はるかに問題だよね。それに比べたら、本の造りなんてどうでも
いい気がするよ。
007837NGNG
みんな〜、pimplイディオムの実装って、auto_ptrでやってるよね?
こういうの、どうかな。pimplイディオム専用のラッピング。

template<class T>
class auto_ref{
public:
  // デフォルトコンストラクタ
  auto_ref(void) : R(*new T) {}
  // 引数つきコンストラクタは、外でnewしたのを渡してもらう
  auto_ref(T* _P) : R(*_P) {}
  ~auto_ref(){delete &R; }
  T& get(void)const {return R; }
private:
  T& R;
};

デフォルトでインスタンスを確保するから、auto_ptrのようにnewする
必要がないのが利点。
メンバ参照演算子(.)のオーバーロードが出来ないから、インスタンスの
アクセスがget()になっちゃってるのがダサイ…というか、欠点。
引数付きコンストラクタを用意しているのは、コンポジションしている
オブジェクト単位でpimlイディオムを使うときに便利だから。

// 先行宣言。A,Bはともに開発中のオブジェクトで、実装はおろか
// インターフェースも定まってないようなクラス。
class A;
class B;
class Hoge{
  Hoge(int,double);
  auto_ref<A> a_;
  auto_ref<B> b_;
}
Hoge::Hoge(int n,double d) :
a_(new A(n)),
b_(new B(d))
{}

…どうかな?
007937NGNG
(´-`).。oO(しまった…)
(´-`).。oO(template<class T> は、 template<class K>にしておけば…)
(´-`).。oO(private: T&R; は、private: K&R; で楽しかったかも…)
0080デフォルトの名無しさんNGNG
Ruby >>>>>>>>>>>>>>>>>>>>>>>>>>>> ポインタ
0081俺 ◆JjsLsZzw NGNG
if(Ruby + 松本 < 俺) puts("True");
else puts("False");

bcc5.5コンパイル結果...
  ↓
警告 W8008 e:\\c\\test.c 16: 条件が常に真(関数 main )
警告 W8066 e:\\c\\test.c 17: 実行されないコード(関数 main )
0082デフォルトの名無しさんNGNG
bcc5.5.1 - 修正項目:
比較演算子の大小判定が逆になっていたバグを修正。
0083デフォルトの名無しさんNGNG
>>78
それだと ヘッダの中で T の実装を参照しているから、
実際に使う時には #include "(T のクラス).h" をしなきゃダメな気がする。
だから実装を隠したいという pimpl のメリットがなくならない?

優秀なコンパイラは気を使ってくれるのかな。
0084John ◆0z.4Is5E NGNG
>表せるアドレス自体物理アドレスじゃなくて仮想アドレスだ
>実際のアドレスを使ってんのはCPUのページングユニットだけちゃうん
そうなのかな?
仮想メモリのアドレス値が実際のアドレスなんじゃない?
主記憶とかキャッシュは、使う確率が高いものを部分的に持ってるだけであって。
だから、ポインタの値は仮想メモリのアドレス値だと思うけど。
0085デフォルトの名無しさんNGNG
とりあえず、お前はここ↓から出るな。
http://pc.2ch.net/test/read.cgi/tech/1013995470/
0086デフォルトの名無しさんNGNG
プログラム議論板が欲しい今日この頃
0087デフォルトの名無しさんNGNG
>>84
仮想メモリのアドレス値が実際の物理アドレス値だったらDATってもんは何の為にあるのか?って話になるよ
>ポインタの値は仮想メモリのアドレス値だと思うけど。
そうかもね つまりポインタじゃ正確な物理アドレスにはさわれない
>主記憶とかキャッシュは、使う確率が高いものを部分的に持ってるだけであって。
仮想メモリ上にあろうがその中の実メモリ領域にリロケートしなきゃどんなプログラムも実行できんでしょ
主記憶以外がおまけだよ
それとポインタはプログラミング言語が用意した都合のいい擬似番地なんだからむやみにアドレス値アドレス値と叫ぶな
誤解を生む
008837NGNG
>>83
クラスの実装を参照してはいるけど、クラスを使用してはいないから、
auto_ptrでのpimplと同じように出来るよ。実際、VC++6.0で試したけど、
#include "(T のクラス).h" は.cpp側に書いてて問題なかったよ。
ただやっぱり、get()でアクセスしなきゃならないのがネックだね…。
これさえなければ、pimplイディオム外しをする時の修正がすごく少なくて
すむんだけど…。
get()じゃなくて、operator->をオーバーロードしちゃえば良いのかもしれないけど、
それだとauto_refっていう看板に偽りアリだし…。pimpl_ptrって名前にした方が
良かったのかな。
って、それじゃ、
「可能な限り、ポインタ排除、参照マンセー」っていう最初の目的が
達成できないし。
むむむ…。
0089デフォルトの名無しさんNGNG
Ruby は取り巻きがキチガイなだけだと思ってたけど、
松本さんもけっこうアレな人なのかもしれないと思った。

sage
0090デフォルトの名無しさんNGNG
シンボリックリファレンスはぜんぜんポインタっぽくない。
■ このスレッドは過去ログ倉庫に格納されています