ページ 11

ポインタについての質問

Posted: 2015年8月03日(月) 11:41
by 大学生
Cでポインタと関数に関する質問なのですが、このtasihikiという関数はなぜメインの外で書いて上で関数を呼び出し、returnで計算した値をポインタで渡そうとするとエラーが起きるのですか???

コード:

#include <stdio.h>

void tasihiki(int c, int d, int *W, int *S);  //関数の呼び出し

int main(void){
    
    int a, b;
    int wa=0, sa=0;
    
    scanf("%d", &a);
    scanf("%d", &b);
    
    tasihiki(a, b, &wa, &sa);  //関数で計算
    
    printf("-----結果-----\n");
    
    printf("和: %d\n", wa);
    printf("差: %d\n", sa);
    
    return 0;
}


/*関数*/
int tasihiki(int c, int d, int *W, int *S){
    
    *W = c+d;
    *S = c-d;

    return (c, d, *W, *S);  //. . .(1)
}

このプログラムで実行すると(1)に警告が起きます。しかし、関数を上でvoid型で書くと何事も指摘されることなくコンパイルできます。なぜそうなるのか今後関数を上で呼び出したいときにできないと困るので教えていただきたいです。
また関数で使用する void や int についてあまり理解できていません。
以上2点、どなたかご回答よろしくお願いしますm(_ _)m

Re: ポインタについての質問

Posted: 2015年8月03日(月) 11:48
by 大学生
すみません、ミスがありました。関数の呼び出しで void となっていますが、int の間違いです。
それでは引き続きご回答のほうをよろしくお願いします。

Re: ポインタについての質問

Posted: 2015年8月03日(月) 12:56
by yoko
そもそもreturn文の使い方が間違っています。
Cではreturn文では1つしか値を返すことができません。

ポインタで値を関数に渡した場合は
返却値で返す必要はありません。

修正するなら

コード:

/*関数*/
void tasihiki(int c, int d, int *W, int *S){
    
    *W = c+d;
    *S = c-d;
 
    //return (c, d, *W, *S);  //. . .(1) ←削除してよい
} 
となります。

関数で使用する void や int についてあまり理解できていません。
とのことですが、
簡単な話、
return文で返ってくる値の型が何であるかというだけです。
voidは返却値なしを意味します。

例として、intの場合は

コード:

int test(void){ //引数でのvoidは引数なしを示します
    return 1; //1の箇所がint型である
}
ということになります。

メインの外で書いて上で関数を呼び出し
とありますが、
C言語はプログラムの上から順に解析して実行しています。
つまり、呼び出す関数(今回ではmain関数)より先に書かれていない関数(今回ではtasihiki関数)は
実態がないためエラーになります。
そのために関数原型宣言というのを用いてこのプログラムにはこのような関数が書かれていますというのを書いておくことで
エラー回避となります。

コード:

void test(void); //これがないとtestの実態がmainより後ろに書かれてるので、
               //呼出しの時にまだ解析していないtestを呼び出そうとするためにエラーが起こる
int main(void){
    test(); //関数原型宣言があるためにmainの後ろにtestがあることがわかるので、エラーが起きない
    return 0;
}
void test(void){
}
※プログラムは実行テストしていませんので、実行できない可能性があります。

Re: ポインタについての質問

Posted: 2015年8月03日(月) 13:20
by amehirune
オフトピック
因みに、戻り値をポインタにしたい場合はこのように書きます。
以下、テストプログラムです。

コード:

//include省略
void* m_malloc(){
	return malloc(sizeof(int));
}

int main(){
	void *a;
	a = m_malloc();
	printf("%p",a);
}
ですがあまりお勧めは致しません。というか使う機会があるのだろうか…

Re: ポインタについての質問

Posted: 2015年8月03日(月) 13:25
by 大学生
>yokoさん
大変分かりやすい解説ありがとうございました。returnは1つしか値を返せないのですね!
それにvoidは返却値なしということも知れて良かったです。ありがとうございました(^^)

Re: ポインタについての質問

Posted: 2015年8月03日(月) 13:29
by 大学生
>amehiruneさん
ありがとうございます。このような書き方があるのは知らなかったので知れてうれしいです(^^)
自分も実用的なプログラムを組む上で使い道があるかどうか聞かれると分からないのですが、教科書を見ながらやっていて、ふと疑問に思いました。
でも解決して下さりありがとうございました。