- ベストアンサー
ポインタいついて教えてください
ポインタがわかりません。 教えてください。 下の二つは、共に「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・C++・C#
- 回答数4
- ありがとう数9
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
無駄なことをやっているように見えますが、これはこのようにする必要があるのでしょうか。 これではポインタを使っている意味が、とくにないでしょう。 int main(void){ int q; q = 100; /* q に100を代入 */ printf("%d", q); return 0; } このようにできない理由は? レポート課題? ただただポインタを使ってみたかった? ちなみに、あえてどちらの場合が有効かについて。 int変数とポインタ変数に必要な容量は、両方とも4バイトです。 よって、コピーにかかる時間はいっしょです。 intでなくdoubleにすれば、ほんの少し変わるかもしれません。 本当にポインタについて勉強したかったら、ポインタについて解説した本がいくつかあるので、1冊買ったらどうでしょう。 もしくは、オンラインヘルプと数ヶ月にらめっこするだけで、結構わかることもありますよ。
その他の回答 (3)
- kokucho81
- ベストアンサー率61% (157/255)
deagleさんへ。 上のソースも下のソースも特に問題ないのでは? 両者のポインタp は実際に使用される前に、 両方とも、&qが代入されていますよ。 ただ、deagleさんのおっしゃるように、C/C++は何を指しているかわからないポインタにも値自体は代入できてしまう上、半々ぐらいの確率で実行が成功したり、プログラムがフリーズしたり、OSごと跳んだりするというすごい仕様になっていますので、その点には注意が必要です。
お礼
kokucho81さん、またレスありがとうございます。 >両者のポインタp は実際に使用される前に、 >両方とも、&qが代入されていますよ。 注意したいと思います。 レスをつけてくださった皆様へ いろいろと試してみて、力をつけたいと思います。 ありがとうございました。
あ。下のソースは駄目です。希にプログラムがハングアップします。 変数というのは値を入れた「箱」であり、ポインタは「その箱がどこにあるか」を書いたメモです。 ところが、宣言したばかりのポインタにはどんな値が入っているか分かりません。 そのポインタ変数に値を入れると、「どんな値か分からない」値がアドレスとして使用され、それが偶然にもシステム領域のど真ん中だった場合、こんな簡単なプログラムがシステムメモリを破壊して場合によってはフリーズします。 上のソースは「ポインタ(メモ)にアドレスを書き込む」という動作をしているので問題ありませんが、下は「どこだかよく分からないアドレスに値を書き込む」という動作なので大変危険です。 ちなみにポインタの概念は、C言語を勉強する人が必ず通り壁ですので、すぐには理解できなくても不思議はありません(^_^; 上記の説明で分からないところがあったら補足してください。
お礼
deagleさん、レスありがとうございます。 とても解りやすかったです。
- kokucho81
- ベストアンサー率61% (157/255)
ポインタの概念そのものに関する勉強中なのですね。 そうですね。両者は同じ行動ですが、次のように全く同様に比較した方が良いでしょうね。 (1) int *p, q; p = &q; q = 100; printf("%d", *p); (2) int *p, q; p = &q; *p = 100; printf("%d", q); まぁ、同じですね。 >scanfを使って、5つぐらい値を代入させて、 とりあえず、例えば、 void foo (int a, int b, int c, int d, int e) { // a,b,c,d,eにscanfで値を代入する } という具合に5つほど、入力された値を変数に代入するということであれば、 void foo(int *a, int *b int *c int *d int *e) { // a,b,c,d,e は格納先を指すポインタ(のはず)である。scanfに&はいらない。 scanf ("%d%d%d%d%d",a,b,c,d,e); } int main(void) { int v1,v2,v3,v4,v5; foo(&v1,&v2,&v3,&v4,&v5); } と「ポインタ」を使用するか void foo(int &a, int &b, int&c, int &d, int &e) { // a,b,c,d,e は参照である。scanfに&が必要。 // scanf ("%d%d%d%d%d",&a,&b,&c,&d,&e); } int main(void) { int v1,v2,v3,v4,v5; foo(v1,v2,v3,v4,v5); } と「参照」(アドレス演算子ではないので注意を!)を使用するか です。 参照を使用したほうが「高速」で、「無駄なメモリも必要ない」ですが、 呼び出し側で「値渡し」との区別がつかない(値を渡すだけか、値が中で変えられてしまうのかは、作った本人以外は使ってみないとわからない)という弱点はあります。 それを補うためには、setValuesOf(...)などというように、値が変更されると言うことが明示的にわかる関数名としておきましょう。
お礼
kokucho81さん、レスありがとうございます。 例まで書いていただきまして、ありがとうございました。 いろいろと試してみます。
関連するQ&A
- ポインタ定義は必要なんですか?
#include <stdio.h> int main( void ) { int x; int *p; p = &x; printf("Address = %p\t\n", p ); return 0; } を #include <stdio.h> int main( void ) { int x; int p;←ここを上とはかえた p = &x; printf("Address = %p\t\n", p ); return 0; } にしたところコンパイル時に p = &x に関して 移植性のないポインタ変換と表記されますが 結果は同じだったのでポインタ定義というのは結局必要なんですか? 移植性のないポインタ変換とはなんなんですか? よければ詳しく教えてください
- ベストアンサー
- C・C++・C#
- ポインタについて
今初めてポインタというものを勉強しております。 よろしくお願いします。 ◎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も同じような事だとは思いますが違いを教えていただけると嬉しいです。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- 関数とポインタについて
#include <stdio.h> void test(int *p); int main() { int i; test(&i); printf("%d",i); return 0; } void test( int *p) { static int k; k = 10; p = &k; } このようなプログラムを作って、void test()のkの値をmain関数で受け取りたいのですが、どのようにすればよいのかわかりません。 どなたか教えていただけませんか?
- ベストアンサー
- C・C++・C#
- C言語のポインタ
あまり意識せずにポインタを使っているせいか,次のプログラムではまってしまいました. #include<stdio.h> #include<stdlib.h> int main(void) { int *p, q; p = (int *)malloc(sizeof(int)); q = (int *)malloc(sizeof(int)); *p = 2; printf("%d\n", *p); return 0; } コンパイルエラーで実行ファイルが出力されません. このプログラムで変数qはなぜポインタじゃないのでしょうか? 次にtypedefでptr_intという型を定義したプログラムは, 上のようなエラーが出力されず,期待とおりの結果になりました. #include<stdio.h> #include<stdlib.h> typedef int* ptr_int; int main(void) { ptr_int p, q; p = (int *)malloc(sizeof(int)); q = (int *)malloc(sizeof(int)); *p = 2; *q = 3; printf("%d\n", *p); printf("%d\n", *q); return 0; } typedefすることでなぜエラーを回避することができるのでしょうか? よろしくおねがいします.
- ベストアンサー
- C・C++・C#
- 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++・C#
- C 関数とポインタ
ポインタと関数がよく分かりません。 (日本語がおかしくてすみません(^_^;)) たとえば↓のようなプログラムで、 #include <stdio.h> void increase(int *i); int main(void) { int x = 3; increase(&x); printf("%d\n", x); return 0; } void increase(int *i) { (*i)++; } 結果は4になりますが、increase(&x)が&xとなっていて、 関数はvoid increase(int *i)でint *iになっているのですが、 これはvoid increase(int *i)はint型の「ポインタ」なので、 increase(&x)も&xと「アドレス」を渡さなければいけないということですか?? そして、void increase(int *i)内では、アドレス&xの指す値をインクリメント、という考えで良いのでしょうか?
- ベストアンサー
- C・C++・C#
- CでいうポインタみたいなことをJAVAでも・・・
Cでいうポインタを使ったプログラム #include <stdio.h> void nibai (int *a , int *b) { *a *= 2; *b *= 2; } int main(void) { int a=3 , b=5; nibai(&a,&b); printf("a=%d b=%d\n",a,b); return 0; } nibai関数はint型のアドレスを貰ってそのアドレスが指す値を書き換えているためmain関数に戻った際に値が変化している。 このようなことをJAVAでやりたいんですけど方法が見当たりません。 グローバルで共有するしか方法はないのでしょうか? CかつJAVAを知っている方限定の質問になってしまいますが よろしくお願いします。
- ベストアンサー
- Java
- ポインタについて
ポインタについてですが、下記のプログラムで、 data = array; で、array[0] のアドレスを代入してますよね? for文で、all+= data[i];では、 どんな計算がおこなわれていますか? dataにarray[0]のアドレスが代入されているので、アドレスの足し算が行われているんですか?(よく解らないのですが。) 教えてください。 #include <stdio.h> int main(void) { int *data; int i, all = 0, array[10] =15,78,98,15,98,85,17,35,42,15; data = array; for (i = 0;i < 10;i++) { all+= data[i]; } printf("%d\n",all/ 10); return 0; }
- ベストアンサー
- C・C++・C#
- ポインタについて(初心者です)
おはようございます。「独習C」を使って独学している者です。わかったような、わからないような、そんな感じでポインタの所まできたのですが、文字列定数とポインタのところで分からないところがあります。 #include <stdio.h> int main(void) { char *p; p = "ひとつ ふたつ みっつ"; printf(p); return 0; } #include <stdio.h> int main(void) { char *p; printf("文字列を入力して下さい:"); gets(p); return 0; } 上のような二つのプログラムが出てきたのですが、下の方はメモリが設定されていないので正しくないと書かれていました。しかし上のプログラムでもメモリは設定されていないように思うのですが違うのでしょうか?メモリを設定するというのは、 char ch; p = &ch; ということだと思うのですが、上のプログラムではこのような文が無くても正常に動きます。この二つのプログラムは何か違いがあるのでしょうか?そもそも根本的に考え方が間違っているのでしょうか?なにぶん初心者な者で見当違いの質問だったら申し訳有りません。よろしくお願いします。
- ベストアンサー
- C・C++・C#
お礼
haporunさん、ごめんなさい。 補足の所に書いてしまいました。 >コピーにかかる時間はいっしょです。 ほとんどいっしょですか。 なんとなく解ってきました。 もっと勉強してきます。 ありがとうございました。
補足
haporunさんレスありがとうございます。 ただただポインタを使ってみたかった? そうなんです。ポインタを理解したいだけです。 はじめに書きましたが、scanfで値を入力させて他の関数でその値を使いたいのですが、 retutnで返せるのは、一つだけらしいので、ポインタを使おうと思いました。 また、グローバル変数にすれば簡単ですが・・・。 もちろん、今やろうとしていることも、 別にmain関数だけでかけますが、ポインタを理解するためにやっています。 これは、独習Cから抜粋しただけです。 レポートではありません。独学なので。 よろしくお願いします。