掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26567

関数の返却型について
投稿者---あきき(2006/04/07 00:15:48)


ユーザー関数を作成する時の事なんですが、仮引数がポインタである限り,そのユーザー関数の返却型は、void型でいいんでしょうか。それ以外でも関数の返却型が、void型になれるケース、または、できないケースについて教えていただきたいのですが、
例えば、main()関数からsub1()関数からsub2()関数を呼び出すと言った様に階層レベルが深くなる時の上位関数との引数の関係(もちろん、引数はアドレス渡しを念頭にしています)についてが分からないのです。

次のようにした時は大丈夫でした。仮引数:(intへのポインタの配列,配列の要素)
#include<stdio.h>

void Ins(int *p, int n);

int main(void)
{
    int array[5]={1,2,3,4,5};
    int i, n;

    printf("0〜4の数字を入れてください:");
    scanf("%d%*c",&n);
    Ins(array, n);
    
    for(i=0; i<5;i++) {
        printf("%d ", array[i]);
    }
    puts("");

    return 0;
}
void Ins(int p[], int n)
{
    p[n] = n*2;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:関数の返却型について 26568 RiSK 2006/04/07 00:45:53
<子記事> Re:関数の返却型について 26572 shu 2006/04/07 13:39:49


No.26568

Re:関数の返却型について
投稿者---RiSK(2006/04/07 00:45:53)


>ユーザー関数を作成する時の事なんですが、仮引数がポインタである限り,そのユーザー関数の返却型は、void型でいいんでしょうか。

「限る」必要はありません。

>それ以外でも関数の返却型が、void型になれるケース、または、できないケースについて教えていただきたいのですが、

いつでも void にして良いです。返却値を用いないのであれば void で良いでしょう。

>例えば、main()関数からsub1()関数からsub2()関数を呼び出すと言った様に階層レベルが深くなる時の上位関数との引数の関係(もちろん、引数はアドレス渡しを念頭にしています)についてが分からないのです。

「階層の深さ」や「ポインタを値渡しにすること」と
関数の型(void など)の間には何の関連もありません。


この投稿にコメントする

削除パスワード

No.26569

Re:関数の返却型について
投稿者---あきき(2006/04/07 07:19:55)


>>例えば、main()関数からsub1()関数からsub2()関数を呼び出すと言った様に階層レベルが深くなる時の上位関数との引数の関係(もちろん、引数はアドレス渡しを念頭にしています)についてが分からないのです。
>
>「階層の深さ」や「ポインタを値渡しにすること」と
>関数の型(void など)の間には何の関連もありません。

質問内容に一部誤解を招く箇所がありましたので訂正します。

仮引数がポインタである限り、そのユーザー関数の返却型は、void型でいいんでしょうか。
                  ↓
仮引数がポインタであれば、そのメモリー上の値を参照・書き換えができるので、
返却値を用いないのであれば、関数の返却型がvoidであっても十分ではないでしょうか。

>>例えば、main()関数からsub1()関数からsub2()関数を呼び出すと言った様に階層レベルが深くなる時の上位関数との引数の関係(もちろん、引数はアドレス渡しを念頭にしています)についてが分からないのです。
>
>「階層の深さ」や「ポインタを値渡しにすること」と
>関数の型(void など)の間には何の関連もありません。

(注1) この事なんですが、main()関数で、staticを除く(構造体)変数を宣言・定義していて、sub1()関数・sub2()関数がその(構造体)変数のアドレスを仮引数にしているとします。この時、sub2()関数内で、
その変数の書き換えがなされた時、main()関数やsub1()関数に反映されるという意味なんでしょうか。

勿論、sub1()関数のみで宣言・定義された変数のアドレスを引数として、sub2()関数の仮引数にした時は、
sub2()の返却型は、いくらvoid以外であっても、sub1()関数に反映されても、main()関数には反映されないように感じます。

というより、関数を呼び出す時、引数をアドレス渡しをする時は階層の深さというのは存在せず、その変数(アドレス)を共有する関数内の変数の値は変更されるのではないのかと感じます。(注1)



この投稿にコメントする

削除パスワード

No.26570

Re:関数の返却型について
投稿者---DD.(2006/04/07 09:20:46)


>仮引数がポインタであれば、そのメモリー上の値を参照・書き換えができるので、
>返却値を用いないのであれば、関数の返却型がvoidであっても十分ではないでしょうか。
返す値が必要ないのであれば、void で問題ないかと思います。

>(注1) この事なんですが、main()関数で、staticを除く(構造体)変数を宣言・定義していて、sub1()関数・sub2()関数がその(構造体)変数のアドレスを仮引数にしているとします。この時、sub2()関数内で、
>その変数の書き換えがなされた時、main()関数やsub1()関数に反映されるという意味なんでしょうか。
ポインタを渡しているのであれば、変更内容は反映されます。


>勿論、sub1()関数のみで宣言・定義された変数のアドレスを引数として、sub2()関数の仮引数にした時は、
>sub2()の返却型は、いくらvoid以外であっても、sub1()関数に反映されても、main()関数には反映されないように感じます。
sub1()内で宣言された変数は sub1()を出るとき(main()に戻る時に)破棄されます。なので、main()に反映されないと言うよりも、main()内にはsub1()内で宣言された変数は存在しないと言うことになるかと。

>というより、関数を呼び出す時、引数をアドレス渡しをする時は階層の深さというのは存在せず、その変数(アドレス)を共有する関数内の変数の値は変更されるのではないのかと感じます。(注1)
ごめんなさい。意味がよくわからんとです。


この投稿にコメントする

削除パスワード

No.26571

Re:関数の返却型について
投稿者---Craft(2006/04/07 10:48:42)


>(注1) この事なんですが、main()関数で、staticを除く(構造体)変数を宣言・定義していて、sub1()関数・sub2()関数がその(構造体)変数のアドレスを仮引数にしているとします。この時、sub2()関数内で、
>その変数の書き換えがなされた時、main()関数やsub1()関数に反映されるという意味なんでしょうか。
>
>勿論、sub1()関数のみで宣言・定義された変数のアドレスを引数として、sub2()関数の仮引数にした時は、
>sub2()の返却型は、いくらvoid以外であっても、sub1()関数に反映されても、main()関数には反映されないように感じます。
>
>というより、関数を呼び出す時、引数をアドレス渡しをする時は階層の深さというのは存在せず、その変数(アドレス)を共有する関数内の変数の値は変更されるのではないのかと感じます。(注1)

staticだろうとautoだろうと、アドレス渡しして呼び出された関数内で
値を書き換えれば、アドレスが正しく引き継がれる作りになっていれば、
どれだけ上位で宣言してようと書き換わります。

一度結果をみたあと、
main内のstruct st_test st; のところを、
static にかえて試してみてください。

#include <stdio.h>
#include <string.h>
#include <memory.h>

struct st_test {
    int num;
    char text[100];
};

void func1(struct st_test *);
void func2(struct st_test *);

int main( void )
{
    struct st_test st1;
    
    /* 構造体メンバの初期化 */
    st1.num = 50;
    strcpy(st1.text,"INIT");

    printf("構造体の初期状態\n" );
    printf("st.num = %d\n", st1.num );
    printf("st.text = %s\n", st1.text );

    /* 構造体st_testの中身を全て書き換えるfunc1の呼出 */
    func1( &st1 );

    printf("構造体の更新結果\n" );
    printf("st.num = %d\n", st1.num );
    printf("st.text = %s\n", st1.text );
    
    return 0;
}

void func1(struct st_test *lpst)
{
    /* メンバnumに100を設定 */
    lpst->num = 100;

    /* st_testのメンバtextの値を書き換えるfunc2の呼出 */
    func2(lpst);
}

void func2(struct st_test *lpst )
{
    /* メンバtextに"ABC"を設定 */
    strcpy( lpst->text, "ABC" );
}




この投稿にコメントする

削除パスワード

No.26572

Re:関数の返却型について
投稿者---shu(2006/04/07 13:39:49)


関数の型(関数の返却型)と引き数は、それぞれ独立したものです。
関数の型に、引き数が影響するのは、関数内でそのようにプログラムした場合です。


この投稿にコメントする

削除パスワード

No.26573

解決:(関数の返却型について)
投稿者---あきき(2006/04/08 21:58:27)


>関数の型(関数の返却型)と引き数は、それぞれ独立したものです。
>関数の型に、引き数が影響するのは、関数内でそのようにプログラムした場合です。

関数のプロトタイプが、void foo(type *,...)の場合の
メモリー(変数)の参照・書き換えのイメージがつかめてきました。
皆さん、ありがとうございます。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧