• ベストアンサー

C++ ポインタ 認識はこれでただしいですか?

int i=3;// iが格納されてるアドレスは001とする そこに3の値 int *pi;// piが格納されているアドレスは//002とする pi=&i;// アドレス002にある値に001が入る printf("%p",pi);//001が表示 printf("%d",*pi);//アドレス001を参照して3を表示 printf("%p",&pi);//002が表示 Q1 このイメージであってますか? Q2 *pi= の右辺は&i,iなどいれられない   代入するときは宣言以外のときは   pi=&i のようにpi= という形にして右辺はアドレスをいれ なければならない。  これであってますか? Q3 char *pc; pc="ABCDE";//ABCDEは文字定数領域に記憶される //文字Aがアドレス(仮)005、Bが006にはいっていたとしたら ↑の式はpc=005;という意味でアドレスを代入している これでいいでしょうか?

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

  • ベストアンサー
  • momenlara
  • ベストアンサー率60% (6/10)
回答No.1

Q1、Q3については問題ないかと思います。 Q2は条件によってなんとも言いがたいですね。 例えば、以下は問題ないパターンです。 int i=3; // アドレスは001 int *pi; // アドレスは002 int j=4; // アドレスは003 pi = &i; *pi = j; printf("%d", *pi); // 4が表示される *pi = (int)&j; printf("%p", *pi); // 003が表示される お気づきのとおりアドレスの実体は整数値ですので、 intにキャストしてあげれば*pi=の右辺にアドレスを指定することも可能です。 ただし、以下のようなパターンはエラーになります。 int i=3; int *pi; *pi = i; // やってはいけない! *pi = &i; // やってはいけない! 違いはポインタ変数piに有効なアドレスが代入されていないという点です。 この場合、メモリのどこか分からない適当なアドレス位置に代入をおこなおうとしているので、エラーになる可能性があります。 もしpiが000を指していると、いわゆるぬるぽになります。

exceln
質問者

お礼

1,3が間違ってないことがわかり安心しました。 2はかゆいところまで教えていただき助かりました 回答ありがとうございました。

その他の回答 (1)

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

>pi = &i; >*pi = j; >printf("%d", *pi); // 4が表示される *pi = j; の文は冗長です。 pi = &i; printf("%d", *pi); // 4が表示される でじゅうぶんです。

exceln
質問者

お礼

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

関連するQ&A

  • ポインタいついて教えてください

    ポインタがわかりません。 教えてください。 下の二つは、共に「100」を表記すると思いますが、 どこがどのように違うのですか。 また、f1()という関数をつくって、ここで scanfを使って、5つぐらい値を代入させて、 他の関数でこの値を使おうと思っています。 この場合下のどちらを使うのが、よろしいのでしょうか。 よろしくお願いします #include <stdio.h> int main(void) { int *p, q; q = 100; /* q に100を代入 */ p = &q; /* p にq のアドレスを割り当てる */ printf("%d", *p); return 0; } #include <stdio.h> int main(void) { int *p, q; p = &q; /* q のアドレスを得る */ *p = 100; /* ポインタを使ってq に値を代入する */ printf("%d", q); return 0; }

  • ポインタについて

    C言語を勉強しております。 ポインタについてどうしても分からない箇所があり、 質問させて頂きます。 例えば、以下の様なプログラムがあったとします。 #include <stdio.h> int hoge(int *); int main(){ int i; hoge(&i); printf("%d\n",i); exit(0); } int hoge(int *p_pi){ *p_pi = 10; } 上記のプログラムは標準出力に"10"と表示するだけのプログラムですが、 これを #include <stdio.h> int hoge(int *); int main(){ int *pi; hoge(pi); printf("%d\n",*pi); exit(0); } int hoge(int *p_pi){ *p_pi = 10; } と書くとhogeの「*p_pi = 10;」の箇所でセグメンテーションエラーが発生します。 &iで渡した時とpiで渡した時ではどの様な違いがあり、エラーが発生するのでしょうか。 私の認識では、 &iで渡す時はアドレスを渡し、 piで渡す時もアドレスを渡すため、同じ動作になると考えています。 どうかご教示ください。 情報に不足があれば、仰ってください。 よろしくお願いします。

  • ポインタへの代入

    int main() {int *i =0xffffffff; printf("&p...%p",&p); return 0;} としてiにffffffffのアドレスを代入しても別のアドレスが表示されます。なぜでしょうか。

  • C++ ポインタ初級

    C++で、自作関数内でメインの数字をインクリメントします。 自作関数はVOIV型でやりたいんです。 #include <stdio.h> void plus( int * ); main( ){  int a = 1;  int *&p = &a;  plus( p );  printf( "%d" , *p ); } void plus( int *i ){  ( *i )++; } int型の変数を2つ宣言したけど、1つでやる方法はないですか? #include <stdio.h> void plus( int * ); main( ){  int a = 1;  plus( &a ); // aのアドレスを渡して、  printf( "%d" , a ); } void plus( int *i ){ // アドレスの値を  ( i )++; // インクリメントしたつもりだけど } 結果は1のままでした。

  • C言語、配列とポインタとアスタリスクの関係

    ちょっと行き詰まっています。 苦しんで覚えるCで勉強しているのですが、まさに苦しんでいます。 http://9cguide.appspot.com/19-01.html #include <stdio.h> #include <stdlib.h> int main() { int i; int *heap; heap = (int *)malloc(sizeof(int) * 10); if (heap == NULL) exit(0); for (i = 0;i < 10;i++) { heap[i] = i; } printf("%d\n",heap[5]); free(heap); return 0; } int *heap; ここで int ポインタを宣言しています。 heap = (int *)malloc(sizeof(int) * 10); ここでヒープを確保しています。(int *) のキャストも sizeof(int) も理解できました。 for (i = 0;i < 10;i++) { heap[i] = i; } まず1点目の疑問はここです。 変数 heap は「ポインタ変数」です。それでいて配列です。 ポインタ変数は、プログラムの文中で通常の変数として使うときには「*heap」のように先頭にアスタリスクを付けなければならかなったと記憶しています。 アスタリスクなしの「heap」はアドレス格納用の変数ではないでしょうか。 printf("%d\n",heap[5]); そして、その疑問をよそに、この命令が成り立っているようです。 画面上に出される結果は「5」であり、変数「heap」がただの配列として機能しているように見えます。 この printf 次のように書き換えると、エラーが出てコンパイルできませんでした。 書き換え実験1 printf("%p\n",*heap[5]); アスタリスクを付けて、通常の変数として扱い、受ける方も「%d」から「%p」に書き換えてアドレスを表示してみようと思ったのですが、 「「pointer」を付け忘れています。」というエラーが表示されました。 書き換え実験2 printf("%p\n",heap[5]); 受ける方を「%d」からポインタを受ける「%p」にしましたが、変数の方はアスタリスクなしです。 すると、結果はアドレス「00000005」が返ってきました。 (変数にアスタがないのになぜ?) 書き換え実験3 printf("%d\n",*heap[5]); これはもうめちゃくちゃですが、一応やってみました。コンパイルエラーで、 「「pointer」を付け忘れています。」というエラーが表示されました。 つまり、こういうことです。 0:printf("%d\n",heap[5]); //5 1:printf("%p\n",*heap[5]); //エラー 2:printf("%p\n",heap[5]); //00000005 3:printf("%d\n",*heap[5]);//エラー この結果から推測するに、アスタリスクはそもそも付けるとエラーになり、アドレスを表すか、そのアドレスに格納された値を表すかを切り替えるには、単にその変数を受ける「%d」や「%p」を変えるだけ、ということになるのだと思います。 mallocで返ってくるのは、ポインタ変数(の配列)だと思うので、変数のモードを切り替えるためにアスタリスクが必要なのだと思っていましたが、どこかで重大な勘違いをしているようです。 この件について、どなたか教えていただけないでしょうか。

  • ポインタと {   } の関係とは

    戻り値が配列(ポインタ)で返す関数を二つ作りif文で選択できるようにしたら 各要素の値がうまく表示されません。 最初に配列の各要素に自分で値を代入するか、ランダムに値を代入させるか決めて、代入させた配列を最後に表示させたいわけです。 #include <stdio.h> int RegistData(int *); int RandomData(int *, int); void main(){ int mous[6]; int select; printf("自分で表示入力するときは1を、コンピュータに任せるときは0を入力してください。"); scanf(" %d", &select); if(select == 0){  *mous = RandomData(mous); }else if(select == 1){ *mous = RegistData(mous); } for( i = 0 ; i < 6 ; i++) printf("%d ", mous[i]); } printf("\n"); } RandomData(int *mous) { //rand()関数でランダムに各要素に値を代入する処理をします。 return *mous; } RegistData(int *mous) { //自分で要素に値を代入する処理をします。 return *mous; } ちなみに、あらかじめ要素に値を入れておくと正常にうごきます。 int mous[6] = { 10, 15, 12, 23, 33, 42};//動作確認用表示

  • C言語 ポインタ変数について

    ポインタ変数の値とアドレスの表示の仕方がよくわからないため、教えていただけますでしょうか。 --------------------------------------------------------------------- #include <stdio.h> int main() {    char* animal[] = {"dog", "cat", "hamster", "mouse"};    int i;    for(i=0; i<4; i++) {      printf("%p animal[%d] : %s, アドレス : %p\n",      animal+i, i, animal[i], *(animal+i));    }    return 0; } --------------------------------------------------------------------- このプログラムを実行すると 0022FF40 animal[0] : dog, アドレス : 00403000 0022FF44 animal[1] : cat, アドレス : 00403004 0022FF48 animal[2] : hamster, アドレス : 00403008 0022FF4C animal[3] : mouse, アドレス : 00403010 となるのですが、なぜanimal[i]のところに配列の要素(dog, cat,・・・)が表示されるのかがわかりません。 char* animal[] = {"dog", "cat", "hamster", "mouse"};の行では、 animal[0] = "dog" なら animal[0]には"dog"の先頭アドレス(00403000)が代入されているのではないのでしょうか。

  • ポインタについて

    今初めてポインタというものを勉強しております。 よろしくお願いします。 ◎1---------------------------------- #include<stdio.h> int main(void) { int mydt=1234; int *pt; pt=&mydt; printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } --------------------------------------- ◎1のようにmydtのアドレスをポインタptに代入すれば、このプログラムは正常に動きました。 ◎2----------------------------------- #include<stdio.h> int main(void) { int mydt=1234; int *pt=&mydt; printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } ---------------------------------------- ◎2で「int *pt=&mydt;」があまりどういう意味かはわかりませんが、これも正常に動きました。 ◎3------------------------------------ #include<stdio.h> int main(void) { int mydt=1234; int *pt; *pt=&mydt printf("*pt=%d\n",*pt); printf("&mydt=%p\n",&mydt); return 0; } -------------------------------------- ◎3のように◎2と違って「*pt=&mydt」の代入を後から行うと、「'=' : 'int *__w64 ' から 'int' に変換できません。」といったようなエラーが起きてしまいます。 ◎1と◎2の違い、後何故◎3はダメなのかがわかりません。 教えていただけると嬉しいです。 後補足として、配列とポインタについてですが、 ◎4------------------------------ char ss[10]="ABCDE"; char *ssp=ss; --------------------------------- ◎5---------------------------- char ss[10]="ABCDE"; char *ssp; ssp=ss; -------------------------------- ◎4と◎5も同じような事だとは思いますが違いを教えていただけると嬉しいです。 よろしくお願いします。

  • ポインタに関する質問

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

  • ポインタのプログラムについて

    以下のプログラムを実行したとき、表示される値を余白に記述せよ。ただし、配列idataは1000番地から格納されているとする。また、表示結果*8**~*10**の箇所で、正しく計算された値のみ表示させるには、maxはいくらに設定すればよいか。という課題なんですが、実際にプログラムを作ってみてmaxの箇所を4にしてみたところ間違いと言われたので正しいmaxの値を教えて下さい。 #include<stdio.h> int main(void) { int iv,idata[]={2,4,6,8,10,12},*ip,i,max; iv=idata[0]; printf("*1*ivの値=%d\n",iv); ip=&idata[0]; printf("*2*ipの値=%p\n",ip); ip=&idata[1]; printf("*3*ipの値=%p\n",ip); ip=&idata[2]; printf("*4*ipの値=%p\n",ip); iv=*ip; printf("*5*ivの値=%d\n",iv); iv=*ip+3; printf("*6*ivの値=%d\n",iv); iv=*(ip+3); printf("*7*ivの値=%d\n",iv); max=4; *ip=0; for(i=0;i<max;i++){ printf("*8**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+1)=10; for(i=0;i<max;i++){ printf("*9**(ip+%d)=%d\n",i,*(ip+i)); } *(ip+3)=20; for(i=0;i<max;i++){ printf("*10**(ip+%d)=%d\n",i,*(ip+i)); } ip=&idata[0]; printf("*11*ipの値=%p\n",ip); ip=ip+2; printf("*12*ipの値=%p\n",ip); iv=*ip+3; printf("*13*ipの値=%d\n",iv); iv=*(ip+3); printf("*14*ivの値=%d\n",iv); ++ip; printf("*15*ipの値=%p\n",ip); } ヒントは”正しく計算された値のみ”という部分らしいのですが、自分にはまったく分りませんでした。

専門家に質問してみよう