• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ポインタを使ったプログラム)

ポインタを使ったプログラムの解説

sankaku197の回答

  • ベストアンサー
回答No.9

おっとすみません、No.2氏の回答は見落としてました。 >そうすると、やはりfunc内は >(略) >という記述になるような気がします。 その通りですね(汗)、私のコードだと不正解です。 折角コードを書いて下さったのにすみません、忘れて下さい。 ちなみにコードの内容は問題ないと思います。(細かい所をいえば「void func」は「int func」じゃないとエラーになりますが、ケアレスミスだと思いますので) というわけで、改めて回答をしたいと思います。 kmtryさんが質問で書かれたコードについて、とりあえずヒントを一つ。 int *m1,*m2,*m3; m1 = m2 = m3 = &m; ↓ int m1,m2,m3; for(int i = 0; i < 50; i++){  m1 = m2 = m3 = i;  //略 } 以下はTIPSです。 少しでも理解の助けになれば幸いです。 >m1 * m2 * m3 != 0の部分は、私のようにわざわざ*m1 * *m2 * *m3 != 0と書く必要はないのですね。 m1,m2,m3をどう宣言したかに注目すれば良いです。 「int m1,m2,m3;」なら前者、「int *m1,*m2,*m3;」なら後者の書き方になります。 例えば「int m1,*m2,m3;」だったら「m1*(*m2)*m3」です。 ついでにここら辺の関係をまとめてみました。 変数には値とアドレス(メモリ上の場所)の二つの数字があります。 int a; int *b = &a; aは普通の変数宣言で、bはポインタでaのアドレスを代入しました。 この変数a,bと、値,アドレスの対応表は以下のようになります。 a   //aの値 &a   //aのアドレス b   //aのアドレス *b   //aの値 &(*b) //aのアドレス &b   //bのアドレス bの値はありません。(当たり前ですが) TIPSその2 複数の値を返したい場合があります。 例えばこんな感じです。 int func(int a){  return a+a;  return a*a; } 見て分かる通りこれだと上手く動きません。 「returnで返せる値は一つだけ」なんです。ここが重要です。 とするとreturn以外の方法を使うしかないわけで、つまりその方法がアドレス渡しというわけです。 なにしろ引数ですから、応用すればいくらでも代入する変数を増やせます。 というわけでこんな感じですね。 void func(int a, int* b, int* c){  *b = a+a;  *c = a*a; } 教科書だと「参照渡し(アドレス渡し)だと関数の外にある変数の値を変える事ができる」という説明はしてくれるんですが、「そもそも関数は一つしか値が返せないからそういうテクニックが必要になるのだ」という事はあんまり教えてくれない気がします。 なのですみません冗長に感じたかもしれませんが、書いてしまいました。

kmtry
質問者

お礼

ありがとうございます。 やはり基礎がわかっていないまま問題に取り組もうとしていたようです。皆さんのご説明で少しずつですがポインタというものが理解できてきました。 いただいたヒントを参考にしながら時間をかけて考えてみることにします。

関連するQ&A

  • 教えてポインタ

    例えば、以下のようなソース。 関数の中で、引数のポインタに値を入れてmainに戻す。 とても簡単なものです。 void func(int *N) {  *N=0; } main {  int  *N=1;  func(N);  printf("%d",*N) } 疑問は、ここからです。 (1)void func(int  *N) (2)void func(int*  N) (3)void func(int*  &N) 上記は、何が違いますか? なお、当方のVS2010で同じソースを作ると、 (1)の場合、エラーになります。(func関数の*N=0のところでダウン) (2)だと、OKになります。 (3)は、なに?

  • ポインタお手上げです。

    #include <stdio.h> main() { void original(int[], int *[], int *[], int *[]) ; int i, origin[10]; int m2[10],m3[10],m5[10]; for(i = 0; i < 10; i++){ scanf("%d", &origin[i]); } original(origin, &m2[], &m3[], &m5[]); printf("2の倍数:"); for(i = 0; i < 10; i++){ printf("%2d ,", m2[i]); } printf("\n"); printf("3の倍数:"); for(i = 0; i < 10; i++){ printf("%2d ,", m3[i]); } printf("\n"); printf("5の倍数:"); for(i = 0; i < 10; i++){ printf("%2d ,", m5[i]); } printf("\n"); return 0; } void original(int origin[], int *multiple_2[], int *multiple_3[], int *multiple_5[]) { int i, m2 = 0, m3 = 0, m5 = 0; for(i = 0; i < 10; i++){ if(origin[i] % 2 == 0){ *multiple_2[m2] = origin[i]; m2++; } if(origin[i] % 3 == 0){ *multiple_3[m3] = origin[i]; m3++; } if(origin[i] % 5 == 0){ *multiple_5[m5] = origin[i]; m5++; } } } 上のプログラムをコンパイルし実行するとセグメントエラーがでてしまいます。どこがわるいんでしょうか・・・。上のプログラムは、外部入力から10個の数字をoriginに格納しそれをそれぞれ2の倍数、3の倍数、5の倍数をあらわすポインタにそれぞれを格納していき、最後にそれを表示するプログラムなんですが・・・。いまいち配列を持ったポインタを使い、なおかつ引数として使うやり方がうまくわからないからこんなエラーが出るような気もします・・・。どなたか初心者でもわかるようなアドバイスお願いします!

  • 関数ポインタについて

    C言語の関数ポインタの問題で以下のような問題で、実際に解いて、プログラムを動かしてみてみました。 正常に動作したのですが、この回答では満点はもらえませんでした。 このほかに良い解答例などありましたら、教えていただけないでしょうか。 どうかよろしくお願い致します。 [問題]次の※1・※2を埋めなさい(「func1」,「func2」は解答に含まれないように書くこと)。 #include <stdio.h> void func1() { printf("func1\n"); } void func2() { printf("func2\n"); } void func(int no) { void (*func[2])(void) = {func1, func2}; /* ※1 (*func[no])() */; } int main() { /* ※2 func(1) */; return 0; } 実行結果:func2

  • 【C言語】別関数でポインタの値を変えたのに変わらない。

    【C言語】別関数でポインタの値を変えたのに変わらない。 メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。 以下がそのプログラムになります。 そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。 なぜ出来なくなってしまったのでしょうか。 2つのプログラムの違いは、 >  *pp = &dummy; が >  p = *pp;      // ダブルポインタをシングルポインタにした >  p = &dummy; に変わっただけです。 【参考】http://www.kouno.jp/home/c_faq/c4.html#8 -----------------正しいプログラム---------------- // 以下プログラムは、正しく動作する // 実行結果は、 //   p = 5 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   *pp = &dummy; } ---------------------------------------------- -----------------間違いプログラム---------------- // 以下プログラムは、正しく動作しない // 実行結果は、 //   p = 0 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   int *p;   p = *pp;      // ダブルポインタをシングルポインタにした   p = &dummy; } ----------------------------------------

  • Javaでポインタ的なことはできるか?

    JavaでC言語のようにポインタを使おうとしたらJavaには ポインタが表面上はサポートされていないことを知りました。 関数を呼び出した際に、呼び出し元の変数に影響を与えるようなプログラムは Javaで作れるのでしょうか? 例えば、以下のプログラムはCで関数を呼び出した際に呼び出し元の 変数の中身を関数内で書き換えてしまうプログラムです。 こういうことをJavaでするにはどう書けばよいのでしょうか? もしこういうことができないのであれば、Javaにはポインタに代わるやりかたがあるのでしょうか? 実行結果: 1 10 #include <stdio.h> void func( int *n ){   *n = 10; } int main(){   int n = 1;   printf("%d ", n );   func( &n );   printf("%d ", n ); }

    • ベストアンサー
    • Java
  • ポインタの代入の省略について

    下記のプログラムにおいて、 Base* const sensor(mSensors[0]);は Base* const sensor = mSensors[0]; と同意だということなのですが、 C++のこのようなポインタの代入の記述法(?)について 書かれた参考書をもっておらず、最初かなりとまどいました。 このような記述法に名前(XX法)はついているのでしょうか? またこのような表記法について説明がなされている参考書または Webページがあればご教示いただけないでしょうか? よろしくお願いします。 #include <stdio.h> class Base { protected: public: Base(int n); void func(); }; Base::Base(int n) { printf("hello, world\n"); } void Base::func() { printf("func is called\n"); } int main(void) { Base* mSensors[2]; mSensors[0] = new Base(5);       Base* const sensor(mSensors[0]); sensor->func(); return 0; }

  • プログラムがわかりません

    C言語の本を読んでいるんですが、詰まってしまいました。プログラム自体は単純なのですが #include<stdio.h> void hello(void) { fprintf(stderr,"hello!\n"); } void func(void) { void *buf[10]; static int i; for(i=0;i<10;i++) { buf[i] = hello; } } int main(void) { int buf[100]; func(); return 0; } のスタックオーバーフローのプログラムです。 1. 要素100のint型配列を宣言 2. 関数funcの呼び出し 3. void *buf[10]; まずここでがわかりません。なぜポインタが   でてきたのか?またbufの要素数は100では? 4. buf[i] = hello; のループ    これもわかりません。配列に関数を代入しているのでしょうか?     5.  fprintf(stderr,"hello!\n"); これもまたわかりません。    fprintfの最初の引数は出力先ですが、なぜ標準エラー出力なの   でしょうか? 時間のあるかた解説お願いします。

  • C言語の基本的な質問ですが、関数へのポインタの宣言

    関数へのポインタの質問です。 下のように、関数へのポインタを使ったプログラムを書きました。 (関数へのポインタを理解するためのものなので、実用的な意味はありません。(*^_^*) また、このプログラムはコンパイルもリンクも実行も問題なく出来ます。) #include <stdio.h> int add_func(int,int); (*func_p0) (int,int); int main(void) { int (*func_p1) (int,int); int (*func_p2) ( ); int hoge0,hoge1,hoge2; func_p0=add_func; hoge0=func_p0(3,5); printf("0 : 3+5は%d\n",hoge0); func_p1=add_func; hoge1=func_p1(3,5); printf("1 : 3+5は%d\n",hoge1); func_p2=add_func; hoge2=func_p2(3,5); printf("2 : 3+5は%d\n",hoge2); return(0); } int add_func(int x, int y) { return(x+y); } func_p0のように戻り値の型を書かない場合と、func_p1やfunc_p2のように戻り値の型を書くのとでは何が違うのでしょうか。 func_p0は外部変数ですが、自動変数にする(main関数の中で同様に宣言。)とコンパイルエラーになります。 それはなぜですか。 func_p1のように引数の型が書いてあるのと、func_p2のように引数の型が書いていないのでは何が違うのでしょうか。 int (*func_p2) ( );というのは、int (*func_p2) (void);とは違うんですよね?

  • gcc: incompatible pointer type

    以下のCソースでコンパイルすると、warning: passing arg 1 of `func_b' from incompatible pointer type となります。 void (*p_func)() は、引数を省略しているので int として扱われるということでしょうか? #include <stdio.h> #include <stdlib.h> void func_a( unsigned char x ){ printf( "x=%d\n", x ) ; } void func_b( void (*p_func)() ){ p_func( 1 ) ; } int main(){ func_b( func_a ) ; return 0 ; }

  • プログラムに詳しい方教えてください!

    #include<stdio.h> void fxl(int x,int y); int main(void) { int a,b,m,n; printf("整数aの値を入力\n"); scanf("%d",&b); printf("整数bの値を入力\n"); scanf("%d",&b); m=a; n=b; fxl(m,n); printf("a=%dとb=%dを加算した値は%d\n",ab,m); printf("a=%dからb=%dを減算した値は%d\n",ab,n); return 0; } void fxl(int x,int y) { int j,k; j=x; k=y; x=j+k; y=j-k; } このプログラムを作ってみたのはいいのですが、参照渡しを使って正常に足し算、引き算をするにはどうすればよいのでしょうか。