ポインタとアドレス

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
はるさめ

ポインタとアドレス

#1

投稿記事 by はるさめ » 1年前

gnの値を100増やしたいです。できたらポインタの勉強も兼ねたいのでこのように書いています。しかし結果は0が返ってきます。なぜでしょうか?

コード:

#include <stdio.h>

void f1(int *gn);
void f2(int gn); 

int main(void)
{
    int gn = 0;
    f1(&gn);
    printf("%d", gn);
	return 0;
}

void f1(int *gn){
    f2(*gn);
}

void f2(int gn){
    gn+=100;
}

はるさめ

Re: ポインタとアドレス

#2

投稿記事 by はるさめ » 1年前

結果は0が返ってくるというのはprintf("%d",gn);で0が出てくるという意味です。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ポインタとアドレス

#3

投稿記事 by みけCAT » 1年前

関数f2の引数gnは関数f1から渡される*gnのコピーなので、
関数f2内で引数gnを書き換えても関数f1における*gnには影響しません。
そして、関数mainのgnや関数f1の*gnを書き換えるコードは存在しないので、
関数main内の変数gnの値は初期化した時の0のままとなります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: ポインタとアドレス

#4

投稿記事 by box » 1年前

別に二段構えにしなくても…。

コード:

#include <stdio.h>

void f1(int *gn);

int main(void)
{
    int gn = 1234;

    f1(&gn);
    printf("%d\n", gn);
    return 0;
}

void f1(int *gn)
{
    *gn += 100;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

はるさめ

Re: ポインタとアドレス

#5

投稿記事 by はるさめ » 1年前

返信ありがとうございます。変数の場合はコピーができるので値は変わらないことが分かりました。
しかし、以下のコードでは引数が配列のため値が変わってしまいます。配列も元の値がコピーされるので
あれば、値は不変なはずです。どうして配列の場合は値が変わってしまうのでしょうか。

コード:

#include <stdio.h>

void f(int array[]);
int main(void)
{
    int array[2] = {};
    f1(array);
    printf("%d %d", array[0], array[1]);
	return 0;
}

void f(int array[]){
    array[0]++;
    array[1]+=2;
}


box
記事: 2002
登録日時: 13年前

Re: ポインタとアドレス

#6

投稿記事 by box » 1年前

関数f()には、main()て定義した配列array[]の先頭要素のアドレスっていう値(ここがちょっとややこしい)を
渡しています。
f()は配列の先頭要素のアドレスを受け取っていますので、f()の中で施した変更が
main()に反映されてます。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: ポインタとアドレス

#7

投稿記事 by box » 1年前

こんなサンプルコードを動かしてみると、
arrayのアドレス値
array[0]のアドレス値
array[1]のアドレス値は
main()とf()とで不変(∵コピー値が渡っている)であり、
また、関数に配列を渡すときはその先頭要素のアドレス値が渡っており、
array[0]とarray[1]が指している先の内容(アドレス値そのものじゃないですよ)が
1増えたり2増えたりして異なっていることに気づくかもしれません。

コード:

#include <stdio.h>

void f(int array[]);

int main(void)
{
    int array[2] = { 123, 456 };

    printf("%d %d\n", array[0], array[1]);
    printf("*** main() before calling f() ***\n");
    printf("value of array is %p\n", array);
    printf("value of &array[0] is %p\n", &array[0]);
    printf("value of &array[1] is %p\n", &array[1]);
    f(array);
    printf("*** main() after calling f() ***\n");
    printf("value of array is %p\n", array);
    printf("value of &array[0] is %p\n", &array[0]);
    printf("value of &array[1] is %p\n", &array[1]);
    printf("%d %d\n", array[0], array[1]);
	return 0;
}

void f(int array[])
{
    printf("+++ f() called by main() +++\n");
    printf("value of array is %p\n", array);
    printf("value of &array[0] is %p\n", &array[0]);
    printf("value of &array[1] is %p\n", &array[1]);
    array[0]++;
    array[1] += 2;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ポインタとアドレス

#8

投稿記事 by みけCAT » 1年前

関数の引数における int array[] は int* array を意味するシンタックスシュガーなので、
配列ではなくポインタの値のコピーが渡ることになります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

“C言語何でも質問掲示板” へ戻る