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

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

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

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

Q&A

解決済

4回答

1135閲覧

C言語のポインタ、これで実行できない理由を教えてください。

yassuda

総合スコア15

C

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

0グッド

0クリップ

投稿2017/07/23 04:53

授業とは違うプログラムを作ったのですが、これでうまく実行できない理由がわかりません。

###問題
三⾓形の底辺の⻑さを格納するint型変数を指すポインタxpと、⾼さを格納するint型変数を指すポインタhpと、⾯積を格納す
るためのfloat型変数を指すポインタapを仮引数として受け取ると、三⾓形の⾯積を計算してapが指すfloat型変数に格納する
calc_area関数を作成せよ。さらに、適切にmain関数を設け、三⾓形の底辺の⻑さと⾼さを整数値で標準⼊⼒すると、三⾓形
の⾯積を⼩数点以下2桁まで標準出⼒するプログラムを作成せよ。

###回答のプログラム

C

1#include<stdio.h> 2 3void calc_area(int *xp, int *hp, float *ap); 4 5int main(void) { 6 int x, h; 7 float area; 8 9 printf("x = "); scanf("%d", &x); 10 printf("h = "); scanf("%d", &h); 11 12 calc_area(&x, &h, &area); 13 14 printf("Area = %.2f\n", area); 15 16 return 0; 17} 18 19void calc_area(int *xp, int *hp, float *ap) { 20 *ap = *xp * *hp * 0.5; 21}

###自分の回答

c

1#include<stdio.h> 2 3void calc_area(int *xp, int *hp, float *ap); 4 5int main(void) { 6 int *x, *h; 7 float *area; 8 9 printf("x = "); scanf("%d", x); 10 printf("h = "); scanf("%d", h); 11 12 calc_area(x, h, area); 13 14 printf("Area = %.2f\n", *area); 15 16 return 0; 17} 18 19void calc_area(int *xp, int *hp, float *ap) { 20 *ap = *xp * *hp * 0.5; 21}

アドレスとしてxを定義するとxの変数のアドレスを準備したことにはならないということですか?

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

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

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

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

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

guest

回答4

0

ベストアンサー

xがどこを指しているかが問題です。

正回答では、格納する場所を作り、それを指すポインタをscanfに渡しました。

c

1int x;//格納する場所 2int* x_p = &x;//格納する場所を指すポインタ 3scanf("%d", x_p);

ここで上例でx_pのみの状態が誤回答の状態です。どこを指しているか不明なポインタを渡しています。

追記

ポインタはあらかじめ格納する場所を用意しておく必要があるということですか?

じゃないと何を指し示すのか(point)わからないじゃないですか。

ちなみにどこを指しているかわからない or NULL pointerはdereferenceしてはいけません。dereferenceとは具体的に言うと、operator *(単項演算子), operator []の呼び出しです。

c

1int x; 2int* p1 = &x; 3int* p2; 4int* p3 = NULL; 5int* p4 = malloc(sizof(int)); 6*p1;//OK 7//*p2;//NG: Undefined Behavior: C11, 6.5.3.2p4 8//*p3;//NG: Undefined Behavior: C11, 6.5.3.2p4 9*p4;//OK 10free(p4);

ref:

投稿2017/07/23 05:15

編集2017/07/23 06:54
yumetodo

総合スコア5850

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

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

yassuda

2017/07/23 05:20

int *x; これだけでは、格納する場所がxでそのポインタを表す。 というふうにはならないということですか? つまり、ポインタはあらかじめ格納する場所を用意しておく必要があるということですか?
yumetodo

2017/07/23 05:26

>格納する場所がxで ちがいますね。その場合xはポインタを格納する場所です
yassuda

2017/07/23 06:18

ポインタに関する理解が深まりました。 ありがとうございました。
yumetodo

2017/07/23 06:19

>ポインタはあらかじめ格納する場所を用意しておく必要がある ちがいます。ポインタをdereferenceする前に有効なポインタ(NULLポインタとかどこ指しているかわからんぽいんたではない)にしましょう、というお話。
guest

0

解決済みのようですが一言

ポインタ変数は定義しただけでは有効領域を指し示しません。(つまりそれだけでは意味をなさない)常に有効領域を指し示すかまたは明示的にNULLを代入しておくことをお勧めします。(暗黙的にNULLが代入されるとは限りません)


int* p = NULL;//(定義時に初期化)

free(p);
p = NULL;//メモリ開放関数を使ったらNULL埋め

投稿2017/08/15 14:43

HogeAnimalLover

総合スコア4830

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

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

0

変数は、ロッカーみたいなものです。

プログラムくんが起動したとき、OSちゃんは、「このロッカーの10番までは好きに使って。中身は捨ててもいいよ。」って言ってくれました。プログラムくんは、友達のアイオーくんから荷物を受けとるために、「1番のロッカーの中に入ってる指示書に従って」とアイオーくんに伝えましたが、メモを入れるのを忘れていました。

アイオーくんが1番のロッカーの中を覗くと、OSちゃんが捨て忘れた「20番のロッカーに入れる」ってメモが入っていました。アイオーくんが20番のロッカーを開けようとしたら、OSちゃんが「えっち、もう知らない!」って怒ってしまいました。プログラムくんにも口を利いてくれません。

ポインタってのは、上に書いたメモみたいなものです。慣れれば大変便利なものです(1つのロッカーに入りきらないときに、どこのロッカーに入れたかのメモがあれば思い出せる)。けど、プログラムが起動したときは色々入っていたりすることがあって、中身を捨てずに残っていたメモを見てロッカーを開けようとすると、怒られてしまうのです。

プログラムさんとしては、メモを捨てて「(自分が使える)2番、3番のロッカーに入れる」という内容の新しいメモを入れないといけなかったのです。

これが、上手く動かなかった理由です。

投稿2017/07/23 06:34

majiponi

総合スコア1720

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

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

yumetodo

2017/07/23 06:52

その説明よく見かけるけど、ポインタへのポインタ型の説明とかconstとかどう説明する気なんだろうといつも思う。
majiponi

2017/07/23 07:07

質問にわかば*ガール…じゃなかった、若葉マークがあったので、文系の入門者向けの説明をしましたよとだけ。CPUの機能とかアセンブラとか説明しても、初心者バイバイになると思うと…ねorz
guest

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; }

投稿2017/07/23 06:15

A.Ichi

総合スコア4070

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

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

yumetodo

2017/07/23 06:17

>ポインターは実体が無いので それまたおかしな話。ポインタにも実体があるのでポインタをさすポインタ型があるんですががが
A.Ichi

2017/07/23 06:24

その通りです。値を持たない?アドレスを指していない?とか表現能力の欠如でした。 ポインターなので定義されただけでは、型と領域は持っていますが、アドレス情報が無いので使う前に、値が入っているアドレスを指してあげる必要が有ります。
yumetodo

2017/07/23 06:30

>使う前 というよりdereferenceする前ですね。「使う」だとなんのことかわかりにくいので。
A.Ichi

2017/07/23 06:33

日常そんな会話しかして居ないのですみません。dereferenceですね。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問