• ベストアンサー

関数とポインタについて

#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関数で受け取りたいのですが、どのようにすればよいのかわかりません。 どなたか教えていただけませんか?

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.6

★最終的に何がしたいのでしょうか? ・『in_file_stu_test』関数で構造体を呼び出し元に返したいようですが、  (1)静的な構造体配列を返したい。  (2)動的な構造体配列を返したい。  どちらでしょうか?  質問・補足を読む限りでは(1)ですが本当にこちらですか?  ※良く分かりませんので2つサンプルを載せておきます。 // サンプル1: int in_file_stu_test1( struct student **save ) {  static struct student test[ CL ][ CL_MAX ];    *save = (struct student *)test;  :  省略  :  return 0; ←適当に } // サンプル2: int in_file_stu_test2( struct student **save ) {  struct student *p;    p = malloc( sizeof(struct student) * CL * CL_MAX );  if ( p == NULL ) return -1;    *save = p;  :  省略  :  return 0; ←適当に } // 呼び出し int main( void ) {  struct student (*test)[ CL_MAX ];    // サンプル1  in_file_stu_test1( &(struct student *)test );  printf( "stu_num = %d\n", test[0][0].stu_num );  printf( "stu_kan_m_name = %s\n", test[0][0].stu_kan_m_name );  printf( "stu_kan_1st_name = %s\n", test[0][0].stu_kan_1st_name );  printf( "stu_fu_m_name = %s\n", test[0][0].stu_fu_m_name );  printf( "stu_fu_1st_name = %s\n", test[0][0].stu_fu_1st_name );    // サンプル2  in_file_stu_test2( &(struct student *)test );  :  省略  :  return 0; } サンプル1…静的な構造体配列を返す方法。 サンプル2…動的な構造体配列を返す方法。 呼び出し元…適切なキャストを行います。

olive0817
質問者

お礼

ありがとうございます! このサンプル1がわかりやすい例でした。 本当に助かりました!

その他の回答 (5)

  • luckymako
  • ベストアンサー率55% (29/52)
回答No.5

静的に確保された領域への参照を渡すだけなら 構造体でもなんらかわらないと思うのですが? 別に領域を確保して値をコピーする必要があるならそれなりに書かないといけないですね... gcc 3.4.4 で通りました↓ #include <stdio.h> typedef struct S{  int a[1][1]; } S; void test(S *p){  static S k;  k.a[0][0] = 10;  *p = k; } int main(){  S i;  test(&i);  printf("%d",i.a[0][0]);  return 0; }

olive0817
質問者

お礼

丁寧な説明ありがとうございます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

えっと.... 例えば int test[3][30]; int x; x = test; というコードがまともに動作すると思う?

olive0817
質問者

補足

ご回答ありがとうございます。 そのコードがまともに動作しないというのは予想ができます。 私がしたいのは サブ関数の中で定義されて値が入れられた構造体を どのように呼び出し元に渡すのかというところです。 構造体ではなく、int型であれば、#1の方の回答でできることはわかりました。 しかし、同じように構造体でしたいのですが、構造体ではできないので 質問をしてます。 無理でしょうか?

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

> 当該のコード全体を見せてください。 こう書いた理由は、お手持ちのコードと同じものを使って、 当方の環境でコンパイルエラーを再現させたかったからです。 今回提示されたコードは、構造体定義部分が欠落していて、不完全です。 当方の環境で、ご自身と同じコンパイルエラーを正確に再現することができません。 趣旨をご理解いただけるでしょうか。

olive0817
質問者

お礼

補足の補足になります。 開発環境は、 Eclipse SDK 3.1 Eclipse CDT 3.0 Eclipse V3.0日本語パック を使用しております。

olive0817
質問者

補足

失礼いたしました。構造体定義部分を掲載します。 struct student { int stu_num; //出席番号 char stu_kan_m_name[30]; //漢字苗字 char stu_kan_1st_name[30]; //漢字名前 char stu_fu_m_name[30]; //カタカナ苗字 char stu_fu_1st_name[30]; //カタカナ名前 }; このような定義になっております。 よろしくお願いいたします。

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

> コンパイルエラー"incompatible types in assignment" 当該のコード全体を見せてください。

olive0817
質問者

補足

int main() { printf("test\n"); int i; struct student student_test[3][30]; in_file_stu_test(student_test[0]); printf("%d",student_test[0][0].stu_num); printf("%s",student_test[0][0].stu_kan_m_name); return 0; } int in_file_stu_test(struct student *save) { static struct student test[CL][CL_MAX]; *save = test; test[0][0].stu_num = 1; strcpy(test[0][0].stu_kan_m_name , "宍戸"); strcpy(test[0][0].stu_kan_1st_name , "聡"); strcpy(test[0][0].stu_fu_m_name , "シシド"); strcpy(test[0][0].stu_fu_1st_name , "アキラ"); } イメージとしてはこんな感じです。 実際は、static struct student testは[3][30]の2次元配列になっています。

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

> p = &k; *p = k;

olive0817
質問者

お礼

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

olive0817
質問者

補足

ありがとうございます。 もし、int i やint k が構造体の場合 struct student i、 struct student p、 struct student k、 に書き換わった場合も同じように宣言すると、 コンパイルエラー"incompatible types in assignment" が出てしまうのですが、どのように回避すればよいでしょうか?

関連する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> 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++で、自作関数内でメインの数字をインクリメントします。 自作関数は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のままでした。

  • ポインタ、関数、アドレス・・・

    はじめまして。 今微分方程式を解かせるプログラムを作る上で、関数に配列を渡したいと考えています。(多変数微分方程式なので) そのため、ポインタを学び、何となくそれについて分かってきたつもりなんですが、いざ試しのプログラムで、コンピュータがちゃんと値を返してくれるかを試しているのですが、どーもうまく値を返してくれません。。。 下に僕が作ったプログラムを載せますので、問題点を指摘してもらえたらうれしいです。 このプログラムで、僕として返してもらいたい値は1.1111です。 よろしくお願いします /******ソースプログラム******/ #include<stdio.h> #include<math.h> double f(int *x); void main() { double x[5]; x[0] = 0.0; x[1] = 1.0; x[2] = 2.0; x[3] = 3.0; x[4] = 4.0; printf("%f \n", f(x)); (←ここらへんがおかしいと言われます。。。) } double f(int *x) { int i; double z=0.0; for(i=0 ; i<=4 ; i++) { z += pow(0.1,*(x+i)); } return(z); }

  • C言語 ポインタ 関数

    キーボードから文字列”abcdefg”を入力し、main関数で配列aryに格納する。 main関数から配列aryの先頭アドレスを副関数に引き渡す。 副関数で配列aryの最後尾の要素の内容を';'に変更する。 main関数で配列aryの内容を表示する。 この問題が解けません... #include <stdio.h> int main (void) { char ary[]="abcdef"; int *p; int i,x; p=&ary[0]; func(&i); for (x=0;x<=7;x++){ printf("%s",ary[x]); void func (int i) if(i==\0) i=';' else i++ } return 0 } とりあえずこんな感じなんですけど、出来ませんでした...

  • 関数の引数表記なしについて

    はじめまして。C言語初心者です。 質問させてください。 関数を宣言して引数を表記しないで使用することは可能なのでしょうか? またどのような場合に使用するのでしょうか? 例として以下コードになります。 ----------------------- #include<stdio.h> int test1(int a); void test2(int b); void main(){ int i = 0; int j = 0;       //この部分 i = test1; printf("%d\n", i);        //この部分 j = test2; printf("%p\n", j); } int test1(int a){ return a + 1; } void test2(int b){ printf("test"); } --------------------------- 出力結果を見ると関数のアドレスが帰ってくるように思われますが、詳細が分かりません。 詳しい方がいらしましたら教えてください。 宜しくお願いいたします。

  • C言語のreturnの使い方

    return a, b; のように2つの引数で値を返せることを最近になり 知りました。ところで以下のような使い方は可能でしょうか? test( , )という2つの引数が必要な関数にnum()で return 1,2としてひとつの関数呼び出しで引数2個分に すると言うようなことです。 #include <stdio.h> int test( int i, int j){   printf("%d %d",i,j); } int num(void){   return 1,2; } int main(void){   test( num() ); }

  • 再帰関数でポインタのインクリメントがうまくいかない 

    再帰関数で標準出力に文字列を表示するプログラムを書きました。 #include <stdio.h> void display(char *p); int main(void) { display("おちょめちょめ"); return 0; } void display(char *p) { if(*p){ printf("%c",*p); dis(p++); } } 実行するとbがいっぱい出てきます。?? 一番最後のコードですが、()の中を p=p+1 p+=1 p+1 などにするとちゃんと おちょめちょめ と表示されます。なぜでしょうか。

  • できているとは、思うのですが。ポインタの配列を

    コンパイラではちゃんと動いてます。 1 2 3 0 1 2 3 という具合です。 気になるのは、printarrayの部分が正しいのか、ちょっと悩んでいます 問題としては main関数では0の値を読み込むまで最大99(MAX-1)個の値を配列 xに読み込んでいる。引数のポインタからの値を、値が0になるまで すべて1行に1つづつ画面に出力する関数printarray()を作成し、 プログラムを完成せよ。 引数はアドレスとして受け取る事。(配列としてでなく) フォーマットは、 "%d¥n" とする。(余計な出力はしない事。) (0は出力しない。) main内部を変更してはならない。 以下がソースです。 ご指摘よろしくお願いします。 #include <stdio.h> #define MAX 5 void printarray(int *); int main() { int x[MAX], i; int *p; x[MAX-1] = 0; for (i = 0, p = x; i < MAX-1; ++i, ++p) { scanf("%d", p); if (*p == 0) { break; } } printarray(x); return 0; } void printarray(int *a) { int i,*p; for(i = 0, p = a; i < MAX-1; ++i,++p) { if(*p == 0){ // continue; break; }else{ printf("%d\n", *(a+i)); } } }

  • ポインタ

    #include<stdio.h> int main() { char *p; p="ポインタ"; printf(p); return 0; } なぜ p="ポインタ"; とできるのですか? 普通は  int *i, j; i=&j; *i=100; こんな感じでやるのでは?

専門家に質問してみよう