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

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

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

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

Q&A

解決済

4回答

7444閲覧

c言語で x^n プログラム

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2016/01/22 08:59

編集2016/01/23 06:17

c

1#include <stdio.h> 2int po(int x, int n){ 3 int i, y = x; 4 for(i = 1; i < n; i++){ 5 y *= x; 6 } 7 return y; 8} 9int main(void){ 10 int x, n; 11 scanf("%d",&x); 12 scanf("%d",&n); 13 printf("%d\n", po(x,n)); 14 return 0; 15}

関数 po をもう少し短く書けそうな気がするのですが、わかりません。
みなさんならどう書きますか?
教えてください。


みなさんありがとうございます。

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

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

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

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

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

guest

回答4

0

まーありがちですが。

c

1int po(int x, int n){ 2 return n > 0 ? x * po(x, n - 1) : 1; 3}

(1/25追記。末尾再帰が効くようにしてスタックオーバーフローを避ける書き方)

c

1int po3(int x, int n, int powered) { 2 return n > 0 ? po3(x, n - 1, x * powered) : powered; 3} 4 5int po(int x, int n) { 6 retrun po3(x, n, 1); 7}

投稿2016/01/22 09:06

編集2016/01/25 00:46
yuba

総合スコア5568

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

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

Chironian

2016/01/22 13:58

すいません。 回答としてはもちろんありですし、確かに短いのですが、落ちるので良い回答ではないと思います。 msvc2015とMinGW 5.2.0で32ビット・ビルドするとpo(1, 0x7fffffff);で落ちちゃいました。もちろん、元のanunsamさんのプログラムは落ちないです。 再帰定義は便利なのですが、再帰呼び出しの深さが深いとスタックオーバーフローするので、あまり深くならないことが分かっている時だけに限定するべきと思います。
raccy

2016/01/22 15:03

GCC 5.3.0なら、-O2で最適化すれば末尾再帰最適化でループにしてくれみたいなので、スタックオーバーフローせずに大丈夫みたいですよ。VCも最適化オプション付ければたぶん大丈夫かなと(未確認)。 末尾再帰最適化は条件が色々あるから、使いどころは注意なんですけどね。
退会済みユーザー

退会済みユーザー

2016/01/23 06:18

ありがとうございます。
yuba

2016/01/25 00:45

ご指摘の通りで、上記のコードは教科書なんかだと「再帰呼び出しを簡単に書けたっぽいけどこれじゃスタックオーバーフローしますよねさてどうしたらいいでしょう」という導入の題材として紹介される書き方です。 ではどうすれば良いかというともちろんこれもご指摘のコメントにもある「末尾再帰」で、それを可能にする書き方を追記しました。
guest

0

短くはなりませんが、「ループ回数を減らす」という観点で、こういうやり方もあるようです。

C

1int po(int x, int n) 2{ 3 int p = x; 4 int v = 1; 5 while(n != 0) 6 { 7 if(n & 1) 8 { 9 v *= p; 10 } 11 n >>= 1; 12 p *= p; 13 } 14 return v; 15}

Wikipediaの冪乗を参考にしました。

投稿2016/01/22 09:46

catsforepaw

総合スコア5938

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

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

catsforepaw

2016/01/22 13:16

興味深い話ですね。ということはC/C++でこのアルゴリズムを使って実装すればさらに爆速ってことでしょうか。 それにしても、Rubyはよく知らないのですがループの外からgotoでループの中に突入するという書き方には違和感が……。
raccy

2016/01/22 15:08

大きさがlongで扱えきれなくなったら多倍長整数(Bignum)に切り替えになるので、そこら辺はどうしても複雑になっちゃうという感じでしょうかね。多倍長整数での計算もアルゴリズムは同じっぽいらしいです。
catsforepaw

2016/01/22 15:51

なるほど、多倍長整数への対応ですか。言語レベルで多倍長整数が扱えるのは便利ですね。
退会済みユーザー

退会済みユーザー

2016/01/23 06:18

ありがとうございます。
guest

0

ベストアンサー

短くするなら再帰だけど、0に対する配慮や、0乗に対する配慮が抜けてるかも

C

1int po(int x, int n){ 2 int i, y = 1; /* 0乗に対する配慮 */ 3 if (x == 0) return 0; /* 0 に対する配慮 */ 4 for(i = 0; i < n; i++){ 5 y *= x; 6 } 7 return y; 8}

投稿2016/01/22 09:31

T.Kanno

総合スコア915

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

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

T.Kanno

2016/01/22 09:36

ごめん、0の0乗は 1だっけ? 0だっけ? 数学的には 未定義エラーにした方が良いのだっけ? あやふやですまんです。
退会済みユーザー

退会済みユーザー

2016/01/23 06:18

ありがとうございます。 0の事を忘れていました。 助かりました!
guest

0

(long long int)pow(x, y)

ループが前提ですか。

投稿2016/01/22 09:07

ipadcaron

総合スコア1693

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

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

退会済みユーザー

退会済みユーザー

2016/01/23 06:18

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問