こんにちは
現在学校でC言語の初歩を習っているのですが、いきなり挫折しています。
先日学校で
ファイル名…prime
引数   …int
戻り値  …int
内容   …引数に一番近い素数をかえす
といったプログラムをかけと言われたのですが、
書き方が全く分からない上に、たとえ先生に聞いたとしても難しく説明されてよくわかりません。
自分なりに調べてみたのですがそれでもわかりません。
次の授業(明日27日)で発表しなくてはいけないのでできるだけ更に焦っています;
どなたか詳しく教えていただけないでしょうか。

A 回答 (7件)

さらに変更。



int near_prime(int n)
{
int p1 = n + !(n & 1), p2 = n - !(n & 1);

if(n <= 2) return 2;
while(!is_prime(p2)){
if(is_prime(p1)) return p1;
p1 += 2;
p2 -= 2;
}
return p2;
}
    • good
    • 0

 変更


int near_prime(int n)
{
int p1 = n + !(n & 1), p2 = n - !(n & 1);

if(n <= 2) return 2;
while(!is_prime(p1)) p1 += 2;
while(!is_prime(p2)) p2 -= 2;
if(p1 / 2 + p2 / 2 + 1 >= n) return p2;
return p1;
}
    • good
    • 0

#include <stdio.h>



int is_prime(int n)
{
int i;

if(!(n & 1)) return 0;
for(i = 3; i * i <= n; i += 2){
if(!(n % i)) return 0;
}
return 1;
}

int near_prime(int n)
{
int p1 = n, p2 = n;

if(n <= 2) return 2;

while(!is_prime(p1)) ++ p1;
while(!is_prime(p2)) -- p2;
if(p1 / 2 + p2 / 2 + 1 >= n) return p2;
return p1;
}

int main(void)
{
int n;

scanf("%d", &n);
printf("%d %d\n", n, near_prime(n));
return 0;
}
    • good
    • 1

// prime.cpp : コンソール アプリケーションのエントリ ポイントを定義します。


//
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>

// こういう問題の場合
// 問題を分けて考える(分割統治という)が有効です
//
// ある自然数Nが与えられ、
// Nは素数であるか否か判定せよ
// というのは簡単な問題です
// (1とその数以外で割ってみれば良い)
//
// ある数Nに一番近い素数というのが少し難しいです
//
// そこで場合分けをしましょう
// A) Nが素数の場合
// Nそのものが解になります
// B) Nが素数でない場合
// 解の候補は2つあります
// 一つ目はNより小さい数で最大の素数
// これをM1とします
// 他の一つはNより大きくて最小の素数
// これをM2とします
// M1とM2のうち、Nに近いほうが解となります
//
// ここでさらに"近い"ということの意味も考える
// 必要があります
// 近いということは”距離が短い"ということです
// 距離を測るには差を求めれば良いですね
// M1 < N < M2なので
// N - M1 が M2 - Nより小さければM1が近い
// N - M1 が M2 - Nより大きければM2が近い
// ことになります
//
// では,等しい場合はどうなるでしょう
// 問題文からは読み取れません
// 私は数学者でないのでわかりませんが
// もしかしたら、このようなケースはあり得ない
// ことが証明されているのかも知れません
//
// しかし、わかりませんので
// 同じ距離の場合は小さい方(M1)を返すことに
// します

// 与えられた数が素数であるかどうかを調べる関数です
// 素数であれば1、そうでなければ0を戻します
static int IsPrime(int n)
{
int i;

// 1は素数ではありません
// ここでは自然数しか扱わないので0以下の整数が
// 与えられることはあり得ないのですが
// 安全のため1か?ではなく1以下か?で判定します
if (n <= 1)
return 0; // 素数でないので0を返します

// 2は素数です
if (n <= 2)
return 1;

// 3以上の場合です
// 3は素数であるとわかりきっているので
// 計算するまでもないのですが
// 無限にifで分岐するわけにもいきませんから
// ここからは計算することにします

// 全ての自然数は1とその数自身で割り切れることは
// 自明です
// よって2とその数(n - 1)以下で割り切れるものが
// あれば素数といえます

for (i = 2; i < n; ++i)
{
if (n % i == 0)
{
// 2以上n-1以下の自然数iで割り切れました
// 素数ではありません
return 0;
}
}

// 2以上n-1以下の自然数で割り切れるものはありませんでした
// つまり1とnでしか割り切れません
// 素数です
return 1;
}

// m1, m2の内nに近い方を返します
// 等距離の場合は小さい方とします
static int GetNearInt(int m1, int m2, int n)
{
int d1, d2;
// m1, m2, nの並び順に依存すると使いにくい関数と
// なってしまいます
// それを避けるため絶対値で比較します
d1 = abs(m1 - n);
d2 = abs(m2 - n);
if (d1 == d2)
{
// 等距離の場合です
// 小さい方を返します
return m1 < m2 ? m1 : m2;
}
else
{
// 距離が小さい方を返します
// d1がm1とnの距離
// d2がm2とnの距離です
return d1 < d2 ? m1 : m2;
}
}

// 与えられた数未満で最大の素数を返します
static int GetMaxPrime(int upperLimit)
{
int i;
// 上限から減少し、素数を見つけます
// 最小の素数は2なので、2以下を調べる必要はありません
for (i = upperLimit; i >= 3; i--)
{
if (IsPrime(i))
{
// 素数を見つけました
return i;
}
}

// 与えられた範囲で3以上の素数はありません
// 最大の素数は2に決定です
return 2;
}

// 与えられた数より大きくて最小の素数を返します
// 最大の整数まで調べて見つからない場合は-1として
// エラーを知らせます
static int GetMinPrime(int LowerLimit)
{
int i;
// 下限から上昇し、素数を見つけます
// 最大の整数で打ち切ります
for (i = LowerLimit; i < INT_MAX; i++)
{
if (IsPrime(i))
{
// 素数を見つけました
return i;
}
}

// 最大の整数値未満では素数がありませんでした
// 最大の整数が素数ならその値を返します
if (!IsPrime(INT_MAX))
return -1;
else
return INT_MAX;
}


// 引数に一番近い素数をかえす関数です
static int GetNearPrime(int n)
{
int m1, m2;

// nが1なら一番近い素数は2です
if (n <= 1)
return 2;

// nが素数ならそのまま返します
if (IsPrime(n))
return n;

// n未満の最大の素数を求めます
m1 = GetMaxPrime(n);

// nより大きくて最小の素数を求めます
// 求められない可能性もあります
m2 = GetMinPrime(n);

if (m2 < 0)
{
// nより大きい素数は見つかりませんでした
// (計算限界に達したため)
// 仕方ないのでn未満の最大の素数を
// 最も近い素数に決定します
return m1;
}
else
{
// n未満の最大の素数及び
// nより大きい最小の素数の両者が見つかりました
// 距離の近い方が
// 最も近い素数です
return GetNearInt(m1, m2, n);

}
}


// 引数に一番近い素数をかえす
int main(int argc, char* argv[])
{
int n;

// 引数は"プログラム名", "整数"の2個でなければ
// なりません
if (argc < 2)
{
printf("usage : prime [Number]\n");
return -1;// エラーとします
}

// 引数はargv[]で渡されます
// argv[0] : プログラム名(prime)
// argv[1] : 整数(を表す文字列)
// 入力ミスでargv[1]に整数以外が渡される可能性も
// あります

// 文字列を整数に変換します
// いろんな方法がありますが
// scanf()が最も汎用性があります
// atoi()でも実装できます
// ただし、atoi()は変換できない場合は0を戻します
// 0を正しく変換できた場合も同じ0で区別できない
// 弱点があります
// その分速いです
// 今回は0がエラーなのでatoiを採用します
// 0も正しいデータとして扱いたい場合
// atoi()は使えないのでscanf()を用います
n = atoi(argv[1]);
if (n <= 0)
{
printf("usage : prime [Number]\n");
printf("Numberは自然数でなければなりません。\n");
return -1;
}

n = GetNearPrime(n);
printf("最も近い素数は %d です。\n", n);

return n;
}
    • good
    • 0

>たとえ先生に聞いたとしても難しく説明されてよくわかりません。


で、難しく説明されて、あなたはどうしたのでしょうか?
わかったふうな顔をして、そのまま帰ってきたのでしょうか?

わからないなら、わからないと言わないと、先生も立場がないです。
わからないと言ってくれれば、どこからわからないのかを探りながら教えることもできます。

>大まかに言ってしまえば先ほどのすべてに該当します。
ということは、Hellow Worldすらわからないのでしょうか。
その段階では明日までに素数を返す関数を書くのは非常に難しいと思われます。
ただの課題ならまだしも、発表ということは、その場で突っ込みをうける可能性が大でしょう。そうなると、人の回答の丸写しではより大きな恥をかくのが目に見えてます。

もう夕方ですが、もう一度先生に相談することをおすすめします。

これが、あと一週間、いや3日もあるんだったら、こんな掲示板でもなんとかなるかもしれませんが、明日までというのでは無理ですねぇ。
    • good
    • 0

こんにちは。



 下記サイトをご参照下さい。
  http://www.sgnet.co.jp/c/8-1.htm
  C言語の関数の作り方を順を追って書いてあります。
  1.mainで書いて見る。(p1前半)
  2.関数にする。(p1後半)
  3.関数から戻り値を受け取れるようにする。(p3)

では。
    • good
    • 0

答えを丸ごと書いたら「課題」の勉強にはならないので。



>書き方が全く分からない上に、
・関数の定義がわからない
・素数を求める方法がわからない
・それ以前にC言語そのものがわからない
のいずれでしょうか?

>たとえ先生に聞いたとしても難しく説明されてよくわかりません。
というのは質問の仕方に問題があると思います。
「何がどうわからないのか」をきちんと説明できていますか?
この質問文からは上記のいずれとも取れますよ。
質問者さんが「わからない」のはどの部分ですか?

この回答への補足

いろいろと不備があって申し訳ありません。
大まかに言ってしまえば先ほどのすべてに該当します。
まず何をして、次にこれをして、という流れもわからない上に、
仮に完成したプログラムを見せられて、ここでこれがこうなっているからこういった結果になる、という説明もできません。
これが現状なのですが…

補足日時:2009/05/26 16:03
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QJavascriptからJSPファイル(~.jsp)を起動する時、引数

JavascriptからJSPファイル(~.jsp)を起動する時、引数を渡したい。また、jspファイル終了後、jspからのリターン値(もくしは引数)をjavascriptで参照したい。
 ※要するに javasript → jsp 起動
 起動jspファイル終了時、javascript側でjspファイルの処理結果を判定したい。

どうすれば良いですか?

Aベストアンサー

要するに、JAVSCRIPTを使って、サーバーサイドのJSPとAJAX(非同期通信)
するという意味ですかねえ?
 それなら、PHPやCGIの場合とあまりちがわないと思うんですが...
あまりくわしくないですが、
HTML(JAVASCRIPT)側からPOST、GET要求したデーターは、
JSP側は
 「request.getParameter(java.lang.String name)」
で受け取れます。
逆にheader指定は、
<%@ page contentType="text/html; charset=utf-8" %>
で、出力は
<% out.print(hoge); %>とか<%= hoge %>
みたいに、ASPやPHPとかまあ、みんな同じようなもんですね。
ヒアドキュメントもあるのかな。

QC言語において、関数とその役割、また、引数とその役割、仮引数、実引数とは?

C言語初心者です。
そもそもPC使うのも苦手ですがよろしくお願いします。
C言語において、関数とその役割、また、引数とその役割、仮引数、実引数の役割を、実例を用いて簡潔に説明していただけると助かります。お願いします。

Aベストアンサー

そんなに一気に理解しようとしても難しいですね。
http://www.kyoto-su.ac.jp/~yamada/ap/parameter_argument.html
を眺めてみてください(仮引数と実引数の意味が書いてある。ただしC言語であんまり仮引数がとか実引数が、という言い方はしないような)。
C言語においては全ての処理のかたまりが「関数」です。関数は何かの処理を行って値を返すことも返さないこともあります。
ここの例でいうとf(int x)は値を返す関数、main()は返さない関数で、ここからプログラムの処理が始まります(そういうルールになっている)。
このページのプログラムはちょっと古い書き方なんで今だと警告が出る可能性があります。

Q【確率統計】99%信頼区間に6個中、5個入ること?

Aが、Bと同等であることを示したいです。

A及びBは正規分布を示し、Bはμ=100、σ=1.0という前提です。

Aを5個測定して、Bの99%信頼区間に入れば、BはAと同等であると言いたいのですが、その場合、危険率は5%となります。

測定結果が信頼区間から外れる確率は5%あるので、判定基準を5個中、5個としてしまうと厳しい判定だと思います。
そこで、6個中、5個が99%信頼区間に入ればAはBと同等と結論付けたいと思いますが、これでは判定が緩すぎると言われる不安があります。

測定のn数はこれ以上増やせません。
6個中、5個でOKとすることについて、どのように理論だてれば良いでしょうか?
また、1個は外れ値が出てもOKとすることを前提として、「6個中、5個が99%信頼区間に入る」の代案がありましたら、ご教示お願いいたします。

Aベストアンサー

> Aを5個測定して、Bの99%信頼区間に入れば、BはAと同等であると言いたいのですが、その場合、危険率は5%となります。

99%信頼区間とありますが、母平均の信頼区間ではないですよね。
多分、Bの分布の99%を覆う区間のことを言っているのだと思いますが、それを信頼区間とは呼ばないでしょう。

さて本題ですが、もしAがBと同じ分布であるなら5個のデータがすべてBの99%区間に入る確率は0.99^5=0.95099なので、確かにほぼ有意水準5%の検定になります。
一方6個中5個以上とすると0.99^5*0.01*6+0.99^6=0.99854なので、有意水準0.146%の検定になります。
データ数が異なるので一概には言えませんが、有意水準を小さくとると検出力は悪くなるので、判定が緩すぎると言われる可能性がありますね。
でしたら、99%区間ではなくもう少し狭めて有意水準を5%となるようにしては如何でしょうか?
0.93715^5*(1-0.93715)*6+0.93715^6=0.95000

しかし、この方法ではAとBが同じ分布であるという検定にはなりませんね。
平均と分散が異なっていてもBの99%区間に入いる確率が99%である分布を考えてみてください。

もし、「A及びBは正規分布を示し、Bはμ=100、σ=1.0という前提」が確かならば、Aのデータから標本平均と標本分散を計算し、μ=100、σ=1.0かどうか検定した方が良いように思います。
このとき、個々の検定の有意水準は2.5%とします。
データ数は多い方が良いので5個よりは6個ですべきです。

あと付け加えると、同等性の検定について調べてみることをお勧めします。
簡単に説明すると、統計的仮説検定は同じであるということが基本的にはできません。
そこで、ある程度以上の違いを十分な検出力で検出できるように検定し、その結果有意でなければ、帰無仮説を支持しようというのが同等性の検定です。

> Aを5個測定して、Bの99%信頼区間に入れば、BはAと同等であると言いたいのですが、その場合、危険率は5%となります。

99%信頼区間とありますが、母平均の信頼区間ではないですよね。
多分、Bの分布の99%を覆う区間のことを言っているのだと思いますが、それを信頼区間とは呼ばないでしょう。

さて本題ですが、もしAがBと同じ分布であるなら5個のデータがすべてBの99%区間に入る確率は0.99^5=0.95099なので、確かにほぼ有意水準5%の検定になります。
一方6個中5個以上とすると0.99^5*0.01*6+0.99^6=0.99854な...続きを読む

QC言語の関数の実引数と仮引数の名前について

 C言語で関数を使う場合、実引数と仮引数の名前(変数名)は、変えなければならないのでしょうか、同じでもいいのでしょうか。C言語のルールでは、どうなっているのでしょうか。よろしくお願い致します。

Aベストアンサー

同じでも構いません。

それぞれの変数の有効範囲(スコープ)が異なりますので、問題ありません。

実引数は定義場所により有効範囲は異なりますが、仮引数はその関数の中でのみ有効です。
両方の範囲が重なった場合はその関数内では仮引数の方が有効になります。

QC言語 コンパイラ

C言語のコンパイラを無料でインストールしたいのですが
気に入ったのが見つかりませんでしたぁ
いいコンパイラがあったら教えてください
よろしく御願いします

Aベストアンサー

その前に対象OSやプラットフォームなどの環境を書かないと何とも
いえないと思います。

クロスコンパイラならみなさんのいうようにGCCが一番でしょうし、
Winに限定するならBCCかVC++ Express Editionがいいでしょう。
MS-DOSならLSI C-86試食版なんてのもありますけど。

なんか、上手く動作しないけどWatcom Cなんて手もあるかも。

Cだけでいいのか、C++が使えた方がいいのかによっても異なります。

参考URL:http://ja.wikipedia.org/wiki/C%E8%A8%80%E8%AA%9E

QC言語を学校で習ってるのですが・・・

 はっきり言ってだいぶアホです。
なにかインターネット上で勉強できたりしないものですか?
楽しく、わきあいあいと、わかりやすく・・・。

Aベストアンサー

最近、本屋にはC/C++の書籍が増えてきていますネ。
コンパイラーも無料のものもありますし、環境は十分ですネ?
プログラム言語をマスタするには、簡単なサンプルを数多く入力し、エラーを起こし、バグ取りをして初めてものになります。面白くなると、熱中して、時間も忘れてきます。何時の間にか、朝がきていることも度々です。下に、参考になりそうなサイトの紹介をしておきます。

入門講座
http://www.orchid.co.jp/computer/cschool/cschool.html#C_LECTURE
好きなところから勉強できます。
http://www.bekkoame.ne.jp/~medaka/index.html
フローチャートつきです。
http://www.trpt.cst.nihon-u.ac.jp/programing/C_index.html
C/C++リンク集です。
http://www.cs.kyoto-su.ac.jp/~minaken/Link/Gengo/c.html

日本のITは貴方の肩にかかっています。
頑張れ!若者!!

古希のおじさんより!

最近、本屋にはC/C++の書籍が増えてきていますネ。
コンパイラーも無料のものもありますし、環境は十分ですネ?
プログラム言語をマスタするには、簡単なサンプルを数多く入力し、エラーを起こし、バグ取りをして初めてものになります。面白くなると、熱中して、時間も忘れてきます。何時の間にか、朝がきていることも度々です。下に、参考になりそうなサイトの紹介をしておきます。

入門講座
http://www.orchid.co.jp/computer/cschool/cschool.html#C_LECTURE
好きなところから勉強できます。
http://ww...続きを読む

QC言語のコンパイラについて

私は、高校でC言語を使った授業をしています。
学校のPCではMinGWのコンパイラを使っています。
家のPCでもC言語をしたいのですがコンパイラの入手法がわかりません。
どなたか教えてください。

Aベストアンサー

あなたの自宅のPCがwindowsであるならば、Cygwinを使われたらどうでしょう?
mingwのCコンパイラも存在します。

参考URL:http://cygwin.com/

QC言語プログラムの質問です。 実数をxを読み込み次の計算をするCプログラムを作成し、そのプログラムリ

C言語プログラムの質問です。
実数をxを読み込み次の計算をするCプログラムを作成し、そのプログラムリストを記しなさい。
2sin(x)cos(x) および sin(2x)
次にこのプログラムを用いて、x=0.785を計算しなさい。

画像のプログラムを作成し、計算をしたのですが、計算結果が全て0.00000となってしまいます。
どこが間違っているか教えてください!

Aベストアンサー

scanfを以下のように変えてください。
scanf("%lf", &x);

QC言語より後に開発されたプログラミング言語は

C言語を基にして開発されたのでしょうか?

C++,C#はもちろんそうですが、Java、PHP、JavaScriptなどもそうなのでしょうか?と言うのも、C言語の関数とこれらのプログラミング言語の関数がかなり似ているところ(共通しているものも)があるからです。また、Excelの関数とも似ているのですが、これらのプログラミング言語と何か関係があるのでしょうか。

Aベストアンサー

ちょっと面白いものがあります
http://gigazine.net/news/20070126_computer_languages_history/

影響は受けるでしょうが、「C言語を基に」というのはちょっと違うと思います。


ただ、関数名だけに注目した場合は別の理由もあります。

関数名は、その関数の機能を表わすような名前を付けるのが普通です。
その際、英単語がよく使われます。数学関数だと、数学用語がそのまま使われます。
そのため、同様の機能の関数は、同じ英単語/数学用語が元になることが多く、結果、同じ関数名になることが多いです。

例えば、sin関数なら、数学のsinから来たもので、特定プログラミング言語の影響とは考えにくいです。

Q(C,C++言語)関数の引数は自動キャストされる?

プログラミング言語C,C++の数値計算に関する質問です.

整数データ変数同士のみの計算結果は小数点以下は切り捨てられますよね.
もし実数型で計結果を得たいときは,int変数を(double)や(float)でキャストしてあげなければならないことは知っています.

ここで,仮引数リストにdouble型変数が設定されている関数の引数にint型変数を与えた時,関数の呼び出し時にキャストしなくても自動でキャストされるのでしょうか.

以下のサンプルコードを作成し,実行してみた結果を次に示します.

---サンプル---
#include <iostream>

using namespace std;

void printDouble(double val, double val2)
{
cout << "(double)val = " << val / val2 << endl;
}

int main(void)
{
for (int i = 1; i < 5; i++) {
cout << i / (i * 2) << endl;
printDouble(i,i*2);
}
}

-----実行結果----
0
(double)val = 0.5
0
(double)val = 0.5
0
(double)val = 0.5
0
(double)val = 0.5
-------------------------
関数の外での計算は整数に丸められてしまうので
i / ( i * 2 ) 計算結果はゼロに,関数の中では与えられた i はdouble型として扱われるので小数点以下の値も残っているということですよね.

この場合,printDouble関数へ整数を与えるときには
printDouble( (double)i , (double)( i * 2 ) );
といったようにわざわざキャストしなくても自動で仮引数の型でキャストされて関数が呼び出されると理解してもよいのでしょうか.

実行結果から明らかだろ,思われてしまうかもしれませんが,何かの参考書に記述されているのを見たり,人からそう教わったわけではなく,また関数のオーバーロードのこともありますので,質問させて頂きました.よろしくお願いいたします.

プログラミング言語C,C++の数値計算に関する質問です.

整数データ変数同士のみの計算結果は小数点以下は切り捨てられますよね.
もし実数型で計結果を得たいときは,int変数を(double)や(float)でキャストしてあげなければならないことは知っています.

ここで,仮引数リストにdouble型変数が設定されている関数の引数にint型変数を与えた時,関数の呼び出し時にキャストしなくても自動でキャストされるのでしょうか.

以下のサンプルコードを作成し,実行してみた結果を次に示します.

---サンプル---
#incl...続きを読む

Aベストアンサー

関数呼び出し時の引数の割り当ては基本的に「初期化」として処理されます. つまり, 今の例だと関数呼び出しによって
double val = i;
double val2 = i*2;
という初期化がなされることになります. 右辺にキャストは必要でしょうか?


人気Q&Aランキング

おすすめ情報