• ベストアンサー

ポインタ演算

http://wisdom.sakura.ne.jp/ このサイトの講座から引用 *po++; とやると、多くの人の期待に反した結果が得られると思われます このときは、アドレスが指す変数ではなくポインタの値がインクリメントされてアドレスを参照されます とありますが、実際に実行してみると、インクリメントされた後に参照 されます。なぜでしょうか、ご存知の方は回答お願いします。 OSはWindows コンパイラはBorland C++ Compilerです。

  • s5210
  • お礼率82% (38/46)

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.6

>*po++; 演算順位からすると++が先に実行されますが右辺の++なので元のpoの値が使われてポインタ参照しますので、得られる値は*poと同じになるのが正しいです。その後の処理でpoを参照するとインクリメントされているはずです。 実証してみます。cygwinのgccで試しました。 #include <stdio.h> int main() { int data[2] = { 1, 4 }; int *po = data; printf( "*po=%d\n", *po ); printf( "po=%p\n", po ); printf( "*po++=%d\n", *po++ ); printf( "po=%p\n", po ); return 0; } のプログラム実行すると *po=1 po=0x22ccc0 *po++=1 po=0x22ccc4 となりました。 予定通りですので問題ありません。 これ以外の答えになりましたか?

s5210
質問者

補足

同じ結果になります。 結局、http://wisdom.sakura.ne.jp/​ このサイトの講座が間違っていると言うことでしょうか?

その他の回答 (5)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

このサイトにかいてある、 ---------------- *po++ とやると、多くの人の期待に反した結果が得られると思われます このときは、アドレスが指す変数ではなくポインタの値がインクリメントされてアドレスを参照されます --------------------- は、正しくは、・・・・アドレスが指す変数が参照され、その後に、ポインタがインクリメントされます。・・・となります。 従って、それは、まさにあなたが、補足した「すいません、実際は参照された後にインクリメントされる でした。」と全く同じことを言っています。

s5210
質問者

お礼

やはりそうでしたか、回答有り難うございます。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

> *po++; この文は、下記の2つの文と等価です。 *po; // まずpoが指している領域を参照してから po++; // poをインクリメントする(++po; でも同じ)

s5210
質問者

お礼

回答どうもありがとうございました。

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.3

「v は 0 になり、po は &a[0] のまま、a[0] は 1 になり、a[1] は不変。」 でした^^;

  • mikaemi
  • ベストアンサー率50% (33/65)
回答No.2

サイトに書いてあることは  *po++; の意味は、  *(po++); であり、  (*po)++; じゃないですよ、って意味じゃないですかね^^  int a[] = { 0, 10 };  int *po = &a[0]; で、  int v = *po++; すると、v は 0 になり、po は &a[1] になり、a[0] も a[1] も不変。  int v = (*po)++; とすると、v は 0 になり、po は &a[0] のまま、a[1] は 1 になり、a[1] は不変。ということかな^^

s5210
質問者

お礼

回答有り難うございます。参考になりました。

  • _Yu
  • ベストアンサー率0% (0/2)
回答No.1

>実際に実行してみると、インクリメントされた後に参照 されます。 それで合っているはずです。 ポインタが指している値そのものがインクリメントされるわけではない、という事をそのサイトでは言いたいのではないでしょうか。

s5210
質問者

お礼

迅速な回答有り難うございました。

s5210
質問者

補足

すいません、実際は参照された後にインクリメントされる でした。

関連するQ&A

  • ポインタに関する質問

    int v; int *p=&v ポインタ変数pに変数vのアドレスを代入して、次からは、pからvの値を操作したいのですが、「*p++」としたところ、変数vの値がインクリメントされずに、pに格納されるアドレスその物がインクリメントされてしまいました 「*p+=1」とする事でvの値をインクリメントすることができましたが、 「*p+=1」このように書かれる処理は望ましい物ではないのでしょうか

  • 参照型変数へのポインタに関してです。

    参照型変数へのポインタに関してです。 たとえば int _v[10]; int &v = &_v[0]; int *pv; pv = &v;  // 参照型変数のアドレスをポインタに代入 こうすると、pv[n]と、_v[n]は同値になります。(VC++とG++では確認) これ(この使い方)で同値なのは ・c++の言語仕様 ・コンパイラの実装依存 のどちらでしょうか? WEBを漁ると「参照型変数はエイリアス(別名)」とかかれているページがヒットするので、C++の言語仕様かなと思っています。 #もちろん配列に置き換えずに単純な参照型変数として使った場合の、値の同一性は言語仕様でしょうが。

  • 配列のポインタ配列のポインタから元の配列を参照する方法について

    C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。 short int *motion_data(void) { short int data1[5][7] = { {2377,2174,0,0,0,0,0}, {2377,2377,2784,2648,2648,2648,2377}, {2377,2377,2784,2648,2648,2648,2377}, {2377,2377,2377,2377,2377,0,0}, {2377,2377,2377,2377,2377,0,0}, }; short int data2[5][7] = { {2377,2174,0,0,0,0,0}, {2377,2377,2919,2784,2784,2784,2377}, {2377,2377,2919,2784,2784,2784,2377}, {2377,2377,2377,2377,2377,0,0}, {2377,2377,2377,2377,2377,0,0}, }; short int *po_data[2]; po_data[0] = data1[0]; po_data[1] = data2[0]; return *po_data; }

  • ポインタに含まれる情報は [C言語]

    ポインタに含まれる情報は代入した変数のアドレスですが、アドレス元の変数の大きさは含まれないのでしょうか?ポインタの中の情報を見てみても、参照できる変数が使用しているメモリの先頭アドレスしか入っていません。変数の大きさはどうやって知るのでしょか?回答よろしくお願いします。

  • ポインタに関するトラブル

    pointという座標を表す変数x,y,zつ保持するクラス型があったとして point *a = point型のポインタを返す関数(); という式を作ったんですが、なぜか、 右辺と左辺はどちらのポインタも指すアドレスは確実に同じなのに。 値を参照しようとすると違う結果が出ます。具体的には 右辺から参照した結果が 50(正しい結果) (*a).x を表示した結果 左辺から参照した結果が -9.25596e+061(?) (*point型のポインタを返す関数()).x を表示した結果 という結果で、完全に同じアドレスを保持するポインタなのに 実行した結果が違って混乱しています。まったく原因がわかりません 説明不足で申し訳ありませんが、なにが問題か分かる方がいらっしゃったらお願いしますm(_ _)m

  • 「NULLポインタ」と「演算の結果としてのアドレス0」との比較

    ものすごく基本的な疑問です。。。 「C言語FAQ日本語訳」http://www.kouno.jp/home/c_faq/ ここの「05.ヌルポインター」を見ると以下のような意味の記述があります。 「NULLポインタは他のどんなポインタの値とも区別可能で、有効なポインタと比較しても等しくなる事はない」 「ポインタを書くべき場所に書かれた定数0はコンパイル時にNULLポインタに変換される」 そこで以下のプログラムを Borland C++ 5.5 for Win32 でコンパイル・実行してみたところ、 p1 == p2 とりました。これって変ですよね? p1 は明示的に定数0で初期化しているのでNULLポインタですが、p2 は演算の結果としてアドレス0番地を指しているので、NULLポインタでは無いですよね? これはコンパイラが間違っていると思って良いのでしょうか? #include <stdio.h> int main() { char *p1,*p2; p1 = 0; p2 = (char *)1; p2--; if(p1 == p2){ printf("p1 == p2"); } else{ printf("p1 != p2"); } return 0; }

  • フレームポインタについて

    こんにちは x86の場合、フレームポインタは関数呼び出し直後のスタックポインタの値を保持してると書いてありました スタックは引数、リターンアドレス、ebp保存値、ローカル変数の順番で格納されると認識しています 関数呼び出し直後のスタックポインタの値とは、正確にはどこを指してるのでしょうか よろしくお願いします

  • ポインタ

    long ToLittleEndian(char *a,long bytesize){ long i; char lb; char hb; long lsize; lsize=bytesize/2; for (i=0;i<lsize;i++){ hb=*(a++); lb=*(a--); *(a++)=lb; *(a++)=hb; } return 0; } ポインタのアドレスがはみだすとどうなるのでしょうか? 上記のようなコードの場合、最後の処理でポインタaが1バイト分はみ出してしまいますが、 存在しないアドレスを参照しようとするとエラーになるかと思いますが ポインタを動かすだけだと問題ないのでしょうか? 処理系やコンパイラに依るのでしょうか。 初心者ですがよろしくお願いします。

  • ポインタへの値の代入時の警告の原因

    私は現在、事務職をやっており、プログラミングとは全く別の畑に居ます。 真剣に転職を考えておりC言語を独学にて勉強中なのですが、ポインタの勉強中、どうしても理解できない点がありましたので質問いたしました。 ポインタを理解するために下記1~3のような処理をさせました。 1.文字変数s に 'a' を代入 2.ポインタp を宣言し、変数s のアドレスを代入 3.最終的にpの値を確認する。 #include<stdio.h> int main (void) { char  s; char  *p; s = ' a '; p = & s;        //←ここが9行目です printf (" pは %c です\n " , *p); return 0; } すると、 『 pは a です 』 と、期待通りの表示がされました。 次に、9行目を *p = s と書き換えた所、コンパイル時に 『値が割り当てられていないローカルな変数’p’に対して参照が行われました』 と言う警告が表示されました。 実行してみた所、 『pは a です』 と、結果は期待通りのものが表示されたのですが、この警告がなぜ表示されたのかが分かりません。 参考書を読んでも、このような(*p = sのような)書き方は載ってましたし、私自身、『「ポインタ変数pの値*p」に「変数sの値」を代入した。』と認識している為、間違いでは無いと考えております。 この警告がなされた原因について、どなたかご存知でしたら、宜しくお願いいたします。

  • ポインタについて

    下記プログラムはどういう動きをしているのでしょうか。 「printf("&a\t--> %p\n", &a );」は、なぜ「&a」なのでしょうか。 aはポインタ変数として宣言してあるのだから、アドレスを表す場合、「a」ではないのでしょうか。 「a = &value;」でvalueのアドレスをaに受け渡していると思うのですが、この場合、1つのアドレスを複数の変数が指しているということでしょうか。 aの値を25に書き換えれば、valueの値も25になるのでしょうか。 では逆にvalueの値を30に書き換えれば、aの値も30になるのでしょうか。 #include <stdio.h> int main() { int value = 10; int *a; printf("&value\t--> %p\n", &value); printf("&a\t--> %p\n", &a ); a = &value; printf("*a\t--> %d\n", *a ); *a = 25; printf("value \t--> %d\n", value ); return 0; }