質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

5回答

1519閲覧

C言語で次のプログラムの出力結果がわかりません

ababab

総合スコア47

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

1グッド

0クリップ

投稿2015/07/23 02:35

int a = 12,b = 34,c,*p;

p = &a;
c = *p;
*p = b;
p = &c;
b = *p;
*p = a-b;
printf("%d",c);

答えが22だったので、34-12をしていることは予想できるのですが、なぜこうなるのかがわかりませんでした。
よろしくお願いいたします。

nnahito👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

コードを眺めて頭で考えてると混乱するので、たとえばこんな感じに変数の格納イメージを書き出してみてはいかがでしょうか?

変数格納イメージ

ひとつひとつ何の値がどこに入るのか、上から順に考えてみればきっと理解できると思います

投稿2015/07/23 03:31

編集2015/07/23 03:33
takito

総合スコア3111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ababab

2015/07/23 10:28

回答ありがとうございます。 表をつくることでどこでわからなくなっているかわかってきました。 少しわかりづらいかもしれませんが、残りの空欄を順に埋めてみたのですが、 a[1000,12] b[2000,34] c[3000,12] *p[4000,34] a[1000,12] b[2000,34] c[3000,12] *p[4000,3000] a[1000,12] b[2000,3000] c[3000,12] *p[4000,0] このあたりでおかしいと思い始めました... 間違いがあればご指摘をお願いしたいです。 よろしくお願いいたします。
takito

2015/07/23 11:10 編集

最初のところ 私の表の変数の表現が悪かったかもしれませんが、ポインタ変数のpはアドレスの格納をしますので、bの値 34 が入ってしまっているのはおかしいですね *p = b ということは、pが指し示しているアドレスの先にbの値が入る、ということなので・・・どこに入るのが正解か考えてみましょう
ababab

2015/07/23 13:03

回答ありがとうございます。 では、*p = bの文では、*pやpに34が入るのではなく、aに34が入るという答えでよろしいでしょうか?
takito

2015/07/23 13:16

正解です!
guest

0

LLman様の仰るとおり書き出してみる,それが確かにお勧めです.
ですが,それだけだと回答にならないので,私の分かる限りで書いてみます(私もポインタは好きですが苦手なので…)

まず,プログラムを書き換えます.

C

1#include <stdio.h> 2 3int main(){ 4 int a = 12; 5 int b = 34; 6 int c; 7 int *p; 8 9 //STEP 1 10 p = &a; 11 printf("STEP:1\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 12 13 //STEP2 14 c = *p; 15 printf("STEP:2\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 16 17 //STEP3 18 *p = b; 19 printf("STEP:3\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 20 21 //STEP4 22 p = &c; 23 printf("STEP:4\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 24 25 //STEP5 26 b = *p; 27 printf("STEP:5\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 28 29 //STEP6 30 *p = a-b; 31 printf("STEP:6\na=%d\nb=%d\nc=%d\np=%d\n*a=%x\n*b=%x\n*c=%x\n*p=%x\n----------\n\n",a,b,c,*p,a,b,c,*p); 32 33 printf("%d\n",c); 34}

なんてことない,ただ表示させるだけの文を追加しました.
その出力結果は

Result

1STEP:1 2a=12 3b=34 4c=0 5p=12 6*a=c 7*b=22 8*c=0 9*p=c 10---------- 11 12STEP:2 13a=12 14b=34 15c=12 16p=12 17*a=c 18*b=22 19*c=c 20*p=c 21---------- 22 23STEP:3 24a=34 25b=34 26c=12 27p=34 28*a=22 29*b=22 30*c=c 31*p=22 32---------- 33 34STEP:4 35a=34 36b=34 37c=12 38p=12 39*a=22 40*b=22 41*c=c 42*p=c 43---------- 44 45STEP:5 46a=34 47b=12 48c=12 49p=12 50*a=22 51*b=c 52*c=c 53*p=c 54---------- 55 56STEP:6 57a=34 58b=12 59c=22 60p=22 61*a=22 62*b=c 63*c=16 64*p=16 65---------- 66 6722

となります.

さて,順を追って見て行きましょう.

STEP1

p = &a; ↓ a=12 b=34 c=0 p=12 *a=c *b=22 *c=0 *p=c

ということで,
pにaのアドレスが入りました.


STEP2

c = *p; ↓ a=12 b=34 c=12 p=12 *a=c *b=22 *c=c *p=c

なので,cにpのアドレス(つまりaのアドレス)が入りました.


STEP3

*p = b; ↓ a=34 b=34 c=12 p=34 *a=22 *b=22 *c=c *p=22

pにb(の値)を入れます.
なので,aにもbのアドレスが入ります.


STEP4

p = &c; ↓ a=34 b=34 c=12 p=12 *a=22 *b=22 *c=c *p=c

今度はpにcのアドレスを入れます.
ここで,aとは孤立します.(STEP3と4で,私はもなぜかはわかりません!文法に詳しい人!ヘルプ!!)


STEP5

b = *p; ↓ a=34 b=12 c=12 p=12 *a=22 *b=c *c=c *p=c

bにpの中身(つまりcの値)を入れます.

STEP6

*p = a-b; ↓ a=34 b=12 c=22 p=22 *a=22 *b=c *c=16 *p=16

後は見ての通りの計算!

という形ですね…流れは

投稿2015/07/23 03:15

編集2015/07/23 03:29
nnahito

総合スコア2004

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こういう事じゃないでしょうか?違うかな? (C言語は25年前に触ったきりなので)

a ポインタ: 値:12
b ポインタ: 値:34
c ポインタ: 値:

1.p = &a;
a ポインタ:p 値:12
b ポインタ: 値:34
c ポインタ: 値:

2.c = *p;
a ポインタ:p 値:12
b ポインタ: 値:34
c ポインタ: 値:12

3.*p = b;
a ポインタ:p 値:34
b ポインタ: 値:34
c ポインタ: 値:12

4.p = &c;
a ポインタ: 値:34
b ポインタ: 値:34
c ポインタ:p 値:12

5.b = *p;
a ポインタ: 値:34
b ポインタ: 値:12
c ポインタ:p 値:12

6.*p = a - b;
a ポインタ: 値:34
b ポインタ: 値:12
c ポインタ:p 値:34-12=22

7.printf("%d",c);
22

投稿2015/07/23 03:12

rik

総合スコア1151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ababab

2015/07/23 11:03

回答ありがとうございます。 たとえばp=&cになった場合、*pを20に変えたらcの値も20に変わる、という解釈でよろしいでしょうか?
guest

0

*p = a-b; これが答え

投稿2015/07/23 03:06

JhonDoe

総合スコア36

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

なぜこうなるのかがわかりませんでした。

正解は分かっているが、解く過程が分からないわけですよね?

一行ごとに a,b,c,p,*pの値を書き出してみるのがおすすめです。
一種の机上デバッグをする感じで、イメージがよくつかめます。

いかにもめんどうそうなので初心者の方には敬遠されがちですが、
ポインタを理解するには遠回りのようで近道だと思います。


追記:print文デバッグで確認するのも良い方法ですが、
自動的に正解が出てしまうので、
その前に間違っていてもいいので自力で書き出しておくと、
自分がどう誤解していたのかが明確になります。

投稿2015/07/23 02:46

編集2015/07/23 03:37
LLman

総合スコア5592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問