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

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

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

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

Q&A

解決済

5回答

3633閲覧

cのべき乗の関数(初心者)

ele

総合スコア7

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

0グッド

0クリップ

投稿2015/11/22 01:15

###前提・実現したいこと
初心者です。書籍で、Cのべき乗の関数を作っています。

###発生している問題・エラーメッセージ
以下が分かりません。
①int y=1がxのp乗になること:式の意味が分かりません。
②最初はpに0が代入されるから(p-->0)のpは-1になるのでは?
③④の式の意味も分かりません。
分からないことが多いので、丁寧に教えて頂けると助かります。

###ソースコード
#include<stdio.h>

int powint(int x,int p) /* 関数の定義 /
{
int y=1; /
正の整数xのp乗を求める関数 */①

while(p-->0) /* pの値を次次に減らし 0になるまで繰り返す */② { y*=x; /* このループはp回繰り返される */③ } return y; /* yをこの関数とする */④

}

int main(void)
{
int i,j;

for(i=0;i<=10;i++) { j=powint(2,i); printf("%d\t%d\n",i,j) } return 0;

}

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

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

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

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

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

guest

回答5

0

powint(int x,int p)は、掛け算だけをつかって階乗計算をしています。

1: int y=1;
2: while(p-->0)
{
3: y*=x;
}
4: return y;

x =2, p = 0 の場合に行を追ってみます。
1 行目の実行後 y = 1, p = 0
2 行目の実行後 while の条件文 (p > 0) は false, p は -1
p-->0 は、 p > 0 が評価条件となり、そのあとで p は -1 します。
4 行目の実行後 y = 1 を return

x =2, p = 1 の場合に行を追ってみます。
1 行目の実行後 y = 1, p = 1
2 行目の実行後 while の条件文 (p > 0) は true, p は 0
3 行目の実行後 y = 2
2 行目の実行後 while の条件文 (p > 0) は false, p は -1
4 行目の実行後 y = 2 を return

x =2, p = 2 の場合に行を追ってみます。
1 行目の実行後 y = 1, p = 2
2 行目の実行後 while の条件文 (p > 0) は true, p は 1
3 行目の実行後 y = 2
2 行目の実行後 while の条件文 (p > 0) は true, p は 0
3 行目の実行後 y = 4
2 行目の実行後 while の条件文 (p > 0) は false, p は -1
4 行目の実行後 y = 4 を return

while(p-->0
{
...
}
は、 慣れないと理解しにくい表記です。
次のように書き換えると良いかもしれません。

while(p > 0)
{
p--;
...
}

または

for (int i = 1; i < p; i++)
{
...
}

理解できたかを試す課題:
powint() は 階乗演算を使わないで、掛け算だけで階乗を計算しているのです。
powint(int x,int p)の書き方をまねして、次の関数を書くことができますか?
int addint(int x, int p) // x + p を返す。 1 を足すことだけを使って。
int mulint(int x, int p) // x * p を返す。 足し算だけを使って。
int divint(int x, int p) // x / p を返す。 引き算だけを使って。
int modint(int x, int p) // x % p を返す。 引き算だけを使って。

発展問題;
2 ** 8 を計算する場合、2 を 8 回掛け算するよりも計算回数を減らすことができます。
y2 = (2 * 2)
y4 = y2 + y2
y8 = y4 * y4
として 3 回の掛け算で y8 に 2 ** 8 が計算できます。
intpow() をこのようになるべく少ない回数の掛け算ですむように書き換えることができますか?

参考書籍:

投稿2015/11/22 06:40

katoy

総合スコア22324

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

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

ele

2015/11/22 09:13

ご回答ありがとうございます。とても分かりやすかったです。 時間がかかりそうですが、問題を解きたいと思います。
guest

0

①は算法と言うかアルゴリズムの問題です。
xのp乗を計算するとき、たとえば、2の3乗の場合は2×2×2を計算しますよね。
y=1
y=y×2
y=y×2
y=y×2
と計算してyが8になります。

②は演算子と、その優先順位を調べると良いかと思います。
p-->0 は (p--)>0 と同じ意味です。
後置演算子 -- と、比較演算子 > の組み合わせです。

③は代入演算子 *= を調べてみてください。

④はpownt 関数の結果として、計算されたyを戻す事を示しています。
main関数内の j = powint で、jにこの時点のyの値が代入されます。

投稿2015/11/22 03:19

T.Kanno

総合スコア915

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

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

0

①は単なる初期化です。変数yはべき乗の計算結果を格納する変数です。べき乗の計算という処理ということですので、初期値を1としています。

②ですが、後置デクリメント演算子なので、この場合は条件式の評価をした後にデクリメントされます。したがって、最初は引数で渡された値での評価となります。前置演算子、後置演算子は他の式と一緒に使うと評価順が変わりますので、気をつけましょう。

③は計算結果に底数(引数x)を掛けあわせて、その結果を代入しています。

y = y * x

と同じです。

④は計算結果を関数の戻り値として返しています。

投稿2015/11/22 01:41

archiver

総合スコア1557

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

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

0

このコメントがよく分からないのですが、イメージしやすいように書き直すと以下ような感じです。

C

1int powint(int x,int p) /* 関数の定義 */ 2{ 3 int y=1; /* 正の整数xのp乗を求める初期値 */ 4 5 for (int idx=p; idx>0; idx--) /* pが0になるまで繰り返す */ 6 { 7 y = y * x; /* このループはp回繰り返される */ 8 } 9 return y; /* yをこの関数のリターン値とする */ 10}

①:
べき乗は、べき数が0の場合にすべて1となりますから、関数内のループが1周もしない場合の初期値を1にします
②:
P-->0はfor文で書き直すと上記のようになります。
このとき、まず初期値の設定、次に判定が行われ、判定がTRUEの場合にループ内の処理が実施され、その後にカウンタ変数の更新が行われます。
P=0の場合は、判定がTRUEとならないので、ループが1回も実施されず、カウンタ変数の更新も行われません。
③:
上記したような形の数式を、別の書きかたをしたものになります。
④:
関数内での計算結果を、呼び出し元に戻しています。

投稿2015/11/22 01:39

KatsumiTanaka

総合スコア924

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

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

0

ベストアンサー

①int y=1がxのp乗になること:式の意味が分かりません。

y が最終的に答え(xのp乗)になります。
最初にその初期値として1を与えています。
例えば 2の3乗 x=2 p=3 であれば、
最初のループで 12 = 2 (この時 p=2)
2回目ループで 2
2 = 4 (この時 p=1)
3回目ループで 4*2 = 8 (この時 p=0 なのでループは終了)
が計算されます。

②最初はpに0が代入されるから(p-->0)のpは-1になるのでは?

そうです。
よって p=0 の時はこのループは通らず答え y は x がなんであっても
1 になります。
つまりどんな数値も0乗したら答えは 1 ということです。

③④の式の意味も分かりません。

③ は上で説明しました。
④ は最終的な答え y をこの関数 powint の返却値にします。
呼び元の powint(2,i) に y の値が返ります。

投稿2015/11/22 01:36

yoshi777

総合スコア674

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

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

ele

2015/11/22 02:57

ご回答ありがとうございます。 少し分からないことがあるのですが、 mainのiは0からスタートして増えていきますが、powintのpは10からスタートして減っていくということですか?それはなぜですか?
yoshi777

2015/11/22 03:43

p は10からスタートではありません。 p は main の powint(2,i) の i の値が渡ってきますので、for でループするごとに 0 , 1, 2, ... 10 となります。
yoshi777

2015/11/22 03:48

補足です。 powint内での動作ということであれば、p に10が渡ってくればwhileループごとに 10,9,...となります。 powint内で p は変更せず、別の変数を使って for 文で 1 ~ p まで、という処理でも可能です。
ele

2015/11/22 05:15

お手数おかけします。 forのループでiは0,1,2~~10となりますが、pにiを代入するので、whileのループでpは0。1,0。2,1,0。3,2,1,0。となり、何回も同じ値が繰り返されると思うのです。printfには反映されませんが、無駄な処理ではないんですか?
yoshi777

2015/11/22 05:31

たしかに、何回も同じ計算が繰り返されるというのはそうです。 main の処理はforで2の0乗、2の1乗、2の2乗...2の10乗をそれぞれ計算して出力するという処理になっているので、powint関数では、何回も同じ計算が繰り返されます。 ただ、powint関数だけを見れば、呼び出し側がどうなっているかは意識する必要はないのでこのような処理になっていると思います。
ele

2015/11/22 05:43

丁寧な説明ありがとうございます。 疑問点の理解が進みました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問