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

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

ただいまの
回答率

90.61%

  • C

    3573questions

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

  • ポインタ

    102questions

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

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

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 758

ababab

score 51

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をしていることは予想できるのですが、なぜこうなるのかがわかりませんでした。
よろしくお願いいたします。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+10

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/23 19: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]
    このあたりでおかしいと思い始めました...
    間違いがあればご指摘をお願いしたいです。
    よろしくお願いいたします。

    キャンセル

  • 2015/07/23 19:43 編集

    最初のところ
    私の表の変数の表現が悪かったかもしれませんが、ポインタ変数のpはアドレスの格納をしますので、bの値 34 が入ってしまっているのはおかしいですね

    *p = b ということは、pが指し示しているアドレスの先にbの値が入る、ということなので・・・どこに入るのが正解か考えてみましょう

    キャンセル

  • 2015/07/23 22:03

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

    キャンセル

  • 2015/07/23 22:16

    正解です!

    キャンセル

+4

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

まず,プログラムを書き換えます.
#include <stdio.h>

int main(){
    int a = 12;
    int b = 34;
    int c;
    int *p;

    //STEP 1
    p = &a;
    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);

    //STEP2
    c = *p;
    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);

    //STEP3
    *p = b;
    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);

    //STEP4
    p = &c;
    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);

    //STEP5
    b = *p;
    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);

    //STEP6
    *p = a-b;
    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);

    printf("%d\n",c);
}

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

STEP:1
a=12
b=34
c=0
p=12
*a=c
*b=22
*c=0
*p=c
----------

STEP:2
a=12
b=34
c=12
p=12
*a=c
*b=22
*c=c
*p=c
----------

STEP:3
a=34
b=34
c=12
p=34
*a=22
*b=22
*c=c
*p=22
----------

STEP:4
a=34
b=34
c=12
p=12
*a=22
*b=22
*c=c
*p=c
----------

STEP:5
a=34
b=12
c=12
p=12
*a=22
*b=c
*c=c
*p=c
----------

STEP:6
a=34
b=12
c=22
p=22
*a=22
*b=c
*c=16
*p=16
----------

22

となります.

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

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
後は見ての通りの計算!

という形ですね…流れは

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1


こういう事じゃないでしょうか?違うかな? (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 20:03

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

    キャンセル

0

なぜこうなるのかがわかりませんでした。
正解は分かっているが、解く過程が分からないわけですよね?

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

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


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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3573questions

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

  • ポインタ

    102questions

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