先頭へ戻る

関数プロトタイプ 解答ページ | Programming Place Plus C言語編 第10章

Programming Place Plus トップページ -- C言語編 -- 第10章

先頭へ戻る

問題①

問題① 円周の長さを渡すと、その円の半径を返すような関数を、関数プロトタイプも含めて自作してください。 このとき、引数と戻り値の型は double型とします。


円周の長さは「直径×円周率」で求められるので、これを変形すれば、「直径=円周÷円周率」です。 今回求めたいのは半径なので、この結果をさらに半分します。

#include <stdio.h>

double calcRadius(double circumference);

int main(void)
{
    char str[40];
    double circumference;
    double radius;


    puts( "円周の長さを入力してください。" );
    fgets( str, sizeof(str), stdin );
    sscanf( str, "%lf", &circumference );

    radius = calcRadius( circumference );
    printf( "半径: %f\n", radius );

    return 0;
}

/*
    円周の長さから半径を計算する。
    引数
        circumference:  円周の長さ。
    戻り値
        半径の長さ。
*/
double calcRadius(double circumference)
{
    return ( circumference / 3.14 / 2.0 );
}

実行結果:

円周の長さを入力してください。
31.4
半径: 5.000000

問題②

問題② 問題①で作成した関数の戻り値を、int型の変数で受け取ろうとするとどうなりますか。


もともと、戻り値は double型なので、int型で受け取ることは正しいとは言えなさそうです。 実際に試してみると…。

#include <stdio.h>

double calcRadius(double circumference);

int main(void)
{
    char str[40];
    double circumference;
    int radius;


    puts( "円周の長さを入力してください。" );
    fgets( str, sizeof(str), stdin );
    sscanf( str, "%lf", &circumference );

    radius = calcRadius( circumference );
    printf( "半径: %d\n", radius );

    return 0;
}

/*
    円周の長さから半径を計算する。
    引数
        circumference:  円周の長さ。
    戻り値
        半径の長さ。
*/
double calcRadius(double circumference)
{
    return ( circumference / 3.14 * 0.5 );
}

実行結果:

円周の長さを入力してください。
31.4
半径: 5

Visual Studio では、次の警告が出ます。

c:\main.c(16) : warning C4244: '=' : 'double' から 'int' への変換です。データが失われる可能性があります。

clang は、デフォルトでは何も警告されないようですが、コンパイラオプション「-Wfloat-conversion」を使用すると警告されます。

「データが失われる」というのは、double型の方が、int型よりも表現できる範囲が豊富であるため (単純に考えても、double型なら小数点を含んだ数が表現できますが、int型ではできません)、 正しいデータが壊れてしまう可能性があるということです。 計算途中で小数点以下が出てきても、それを整数として扱うときには、 切り捨てられてしまうのでしたが(第4章参照)、それと同様のことが起きています。

これがエラーではなく、警告であることからも分かるように、この動作は致命的なものではありませんが、 意図せずにデータの一部を失わないように注意を払う必要があります。

データの一部を失わないように、double型で返されたデータは double型のまま扱い、 どうしても必要なのであれば、キャスト(第21章参照)を用いて、型を変換します。


参考リンク


------------------------------------------------------------------------

更新履歴

'2018/4/5 VisualStudio 2013 の対応終了。

'2018/4/2 「VisualC++」という表現を「VisualStudio」に統一。

'2018/2/4 全面的に文章を見直し、修正を行った。

'2018/1/5 Xcode 8.3.3 を clang 5.0.0 に置き換え。

'2017/7/30 clang 3.7 (Xcode 7.3) を、Xcode 8.3.3 に置き換え。

'2017/3/25 VisualC++ 2017 に対応。

'2016/10/15 clang の対応バージョンを 3.7 に、Xcode を 7.3 に更新。

'2015/10/12 clang の対応バージョンを 3.4 に更新。

'2015/9/5 VisualC++ 2012 の対応終了。

'2015/8/22 問題②の解説を修正。clang 3.2 の場合の警告について追記。

'2015/8/18 VisualC++ 2010 の対応終了。

'2015/8/15 VisualC++ 2015 に対応。

'2014/2/1 VisualC++ 2013 に対応。

'2014/1/14 VisualC++ 2008 の対応終了。

'2012/9/17 VisualC++2012 での結果を確認。

'2010/5/1 VisualC++2010 での結果を確認。

'2009/2/27 新規作成。



第10章のメインページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
Twitter でツイート Twitter をフォロー LINE で送る
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー