C言語のポインタ、これで実行できない理由を教えてください。
解決済
回答 4
投稿
- 評価
- クリップ 0
- VIEW 916
授業とは違うプログラムを作ったのですが、これでうまく実行できない理由がわかりません。
問題
三⾓形の底辺の⻑さを格納するint型変数を指すポインタxpと、⾼さを格納するint型変数を指すポインタhpと、⾯積を格納す
るためのfloat型変数を指すポインタapを仮引数として受け取ると、三⾓形の⾯積を計算してapが指すfloat型変数に格納する
calc_area関数を作成せよ。さらに、適切にmain関数を設け、三⾓形の底辺の⻑さと⾼さを整数値で標準⼊⼒すると、三⾓形
の⾯積を⼩数点以下2桁まで標準出⼒するプログラムを作成せよ。
回答のプログラム
#include<stdio.h>
void calc_area(int *xp, int *hp, float *ap);
int main(void) {
int x, h;
float area;
printf("x = "); scanf("%d", &x);
printf("h = "); scanf("%d", &h);
calc_area(&x, &h, &area);
printf("Area = %.2f\n", area);
return 0;
}
void calc_area(int *xp, int *hp, float *ap) {
*ap = *xp * *hp * 0.5;
}
自分の回答
#include<stdio.h>
void calc_area(int *xp, int *hp, float *ap);
int main(void) {
int *x, *h;
float *area;
printf("x = "); scanf("%d", x);
printf("h = "); scanf("%d", h);
calc_area(x, h, area);
printf("Area = %.2f\n", *area);
return 0;
}
void calc_area(int *xp, int *hp, float *ap) {
*ap = *xp * *hp * 0.5;
}
アドレスとしてxを定義するとxの変数のアドレスを準備したことにはならないということですか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
x
がどこを指しているかが問題です。
正回答では、格納する場所を作り、それを指すポインタをscanf
に渡しました。
int x;//格納する場所
int* x_p = &x;//格納する場所を指すポインタ
scanf("%d", x_p);
ここで上例でx_p
のみの状態が誤回答の状態です。どこを指しているか不明なポインタを渡しています。
追記
ポインタはあらかじめ格納する場所を用意しておく必要があるということですか?
じゃないと何を指し示すのか(point)わからないじゃないですか。
ちなみにどこを指しているかわからない or NULL pointerはdereferenceしてはいけません。dereferenceとは具体的に言うと、operator *
(単項演算子), operator []
の呼び出しです。
int x;
int* p1 = &x;
int* p2;
int* p3 = NULL;
int* p4 = malloc(sizof(int));
*p1;//OK
//*p2;//NG: Undefined Behavior: C11, 6.5.3.2p4
//*p3;//NG: Undefined Behavior: C11, 6.5.3.2p4
*p4;//OK
free(p4);
ref:
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
ポインターは実体が無いので、実体のアドレスを代入してあげます。
#include<stdio.h>
void calc_area(int *xp, int *hp, float *ap);
int main(void) {
int *x, *h;
float *area;
int ix, ih;
float farea;
x=&ix;
h=&ih;
area=&farea;
printf("x = "); scanf("%d", x);
printf("h = "); scanf("%d", h);
calc_area(x, h, area);
printf("Area = %.2f\n", *area);
printf("Area = %.2f\n", farea);
return 0;
}
void calc_area(int *xp, int *hp, float *ap) {
*ap = *xp * *hp * 0.5;
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
変数は、ロッカーみたいなものです。
プログラムくんが起動したとき、OSちゃんは、「このロッカーの10番までは好きに使って。中身は捨ててもいいよ。」って言ってくれました。プログラムくんは、友達のアイオーくんから荷物を受けとるために、「1番のロッカーの中に入ってる指示書に従って」とアイオーくんに伝えましたが、メモを入れるのを忘れていました。
アイオーくんが1番のロッカーの中を覗くと、OSちゃんが捨て忘れた「20番のロッカーに入れる」ってメモが入っていました。アイオーくんが20番のロッカーを開けようとしたら、OSちゃんが「えっち、もう知らない!」って怒ってしまいました。プログラムくんにも口を利いてくれません。
ポインタってのは、上に書いたメモみたいなものです。慣れれば大変便利なものです(1つのロッカーに入りきらないときに、どこのロッカーに入れたかのメモがあれば思い出せる)。けど、プログラムが起動したときは色々入っていたりすることがあって、中身を捨てずに残っていたメモを見てロッカーを開けようとすると、怒られてしまうのです。
プログラムさんとしては、メモを捨てて「(自分が使える)2番、3番のロッカーに入れる」という内容の新しいメモを入れないといけなかったのです。
これが、上手く動かなかった理由です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
解決済みのようですが一言
ポインタ変数は定義しただけでは有効領域を指し示しません。(つまりそれだけでは意味をなさない)常に有効領域を指し示すかまたは明示的にNULLを代入しておくことをお勧めします。(暗黙的にNULLが代入されるとは限りません)
例
int* p = NULL;//(定義時に初期化)
free(p);
p = NULL;//メモリ開放関数を使ったらNULL埋め
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/07/23 14:20
これだけでは、格納する場所がxでそのポインタを表す。
というふうにはならないということですか?
つまり、ポインタはあらかじめ格納する場所を用意しておく必要があるということですか?
2017/07/23 14:26
ちがいますね。その場合xはポインタを格納する場所です
2017/07/23 15:18
ありがとうございました。
2017/07/23 15:19
ちがいます。ポインタをdereferenceする前に有効なポインタ(NULLポインタとかどこ指しているかわからんぽいんたではない)にしましょう、というお話。