アプリ版:「スタンプのみでお礼する」機能のリリースについて

プログラミングの質問です。

#include <stdio.h>

int x=0,y=0;

void add(int k, int z){
int x=0;
x=x+k;
y=y+k;
z=z+k; }

int main(){
int z=0;
x=x+3;
y=y+3;
z=z+3;
printf("x;%d y;%d z;%d \n",x,y,z);
add(3,z);
printf("x;%d y;%d z;%d\n",x,y,z);
add(3,x);
printf("x;%d y;%d z;%d\n",x,y,z);
add(3,y);
printf("x;%d y;%d z;%d\n",x,y,z);return 0;
}
の内容がよく理解できません。
結果は以下の通りになります。
x;3 y;3 z;3
x;3 y;6 z;3
x;3 y;9 z;3
x;3 y;12 z;3

xが四回とも3になるのは理解できるのですが、zがなぜ四回とも3なのでしょうか?

質問者からの補足コメント

  • zがyと同じように表示されないのかがよくわかりません。

      補足日時:2020/08/19 01:42

A 回答 (4件)

出力されるzはmain内で宣言されています。


そして、add関数内のzは引数で持ってきており、返しているわけでもないので、add関数内でのみ使われているものです。

main内で出力されるzとadd関数内で使われているzは名前は同じですが、実はメモリのアドレスが異なっているのです。
    • good
    • 0
この回答へのお礼

add内のzが仮だということがよく分かりました。ありがとうございました!

お礼日時:2020/08/19 10:39

#include <stdio.h>



int x = 0, y = 0; /* x と y は大域変数 */

void add(int k, int z) { /* ここで z は仮引数 */
 int x = 0; /* ここの x はローカル変数で、大域変数 x はシャドウされる */
 x = x + k;
 printf("\tadd内のローカル変数 x = %d", x); /* ここで add 内のローカル変数 x を見てみる */
 y = y + k; /* 結果、add を呼び出しても影響を受けるのは大域変数 y だけ */
 z = z + k; /* ここは「仮引数 z 」に対しての計算を行うが、仮引数に何が与えられようとも、その本体には全く影響がない */
 printf("\tadd 内の z = %d\n",z); /* ここで、 add 内のローカル変数 z を見てみる */
}

int main(void) {
 int z = 0; /* ここで、z はローカル変数 */
 x = x + 3; /* ここで大域変数 x は 3 になるが、これは add ではシャドウされる */
 y = y + 3; /* ここで大域変数 y は3になる */
 z = z + 3; /* ここでローカル変数 z は 3 になる */
 printf("x: %d y: %d z: %d\n", x, y, z);
 add(3, z);
 printf("x: %d y: %d z: %d\n", x, y, z);
 add(3, z);
 printf("x: %d y: %d z: %d\n", x, y, z);
 add(3, z);
 printf("x: %d y: %d z: %d\n", x, y, z);

 return 0;
}


/* 結果、印字されてるのは大域変数 x 、大域変数 y 、(main内の)ローカル変数 z の3つである。関数 add 内の x と z の定義は add から見ると大域変数の x と z を隠してしまう。これを「シャドウイング」と呼んだりする。
C言語では、関数、定義された変数に於いては、「一番近場での同名の変数を探す」と言う挙動を行う。これを

「レキシカルスコーピング(Lexical Scoping)」

と呼ぶ。関数内で定義されていない変数に付いては「関数の外の世界に探しに行く」と言うのが挙動。
従って、実は「xとzはどうなるでしょう?」ってのは意外にフツーで、わざわざ大外の y を「一生懸命探しに行ってる」 add の挙動こそが可愛らしいのである。まるで、

「ママ、ママはどこ?」

と家から外へママを探しに出かけちゃう幼子の如しじゃないか(謎 *\
    • good
    • 0
この回答へのお礼

とても分かりやすく例えまで解説していただき助かりました。ありがとうございました!

お礼日時:2020/08/19 10:39

分かりやすく変数名を変えてみました。



グローバルな変数→頭にgを付加
add関数内のローカル変数→頭にaを付加
main関数内のローカル変数→頭にmを付加

#include <stdio.h>

int gx=0,gy=0;

void add(int ak, int az){
int ax=0;
gx=gx+ak;
gy=gy+ak;
az=az+ak; }

int main(){
int mz=0;
gx=gx+3;
gy=gy+3;
mz=mz+3;
printf("x;%d y;%d z;%d \n",gx,gy,mz);
add(3,mz);
printf("x;%d y;%d z;%d\n", gx,gy,mz);
add(3,gx);
printf("x;%d y;%d z;%d\n", gx,gy,mz);
add(3,gy);
printf("x;%d y;%d z;%d\n", gx,gy,mz);return 0;
}
    • good
    • 0
この回答へのお礼

困ったときは変数の名前を変えて自分で確かめてみるという作業をこれからしていきたいと思います。ありがとうございました!!

お礼日時:2020/08/19 10:40

変数zはローカル変数だから

    • good
    • 0
この回答へのお礼

ありがとうございました!

お礼日時:2020/08/19 10:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!