指定された数以下の範囲にある素数を取り出すプログラム・・・よっしゃ、次、C言語で行ってみよーー!!

・・・と思ったんですけどね。のっけから詰まる。

1. とりあえず、配列に指定された数までの数値を格納しておく
2. 小さい方から順に、倍数を消去して行く(2を素数として確保した後、2の倍数を元の配列から削除。次は3を素数として確保の後、3の倍数を・・・以下同様)
3.

という処理をするのだが・・・問題は、1。pythonだと、空の配列に2から順に整数を放り込むだけで済んだが、Cの場合、予め「必要分」を確保する必要がある。

まあ、十分に大きな量を確保しておけばいいといえばいいけど、何かこう、大変メモリを無駄にするため、許されない気がするんである・・・後、入力受け付けの時、確保分を超えないようにする工夫がいる。入力を却下するか、強制的に切り詰めるか。まあ、これは、そんなに難しくない。

う、う、う・・・できれば、入力された数値に応じて、確保量を変えたいよね。

mallocか。mallocなのか。きれいに忘れた。仕方が無いので、先生のブログを見に行った。一回は理解したはずの内容である。

・・・

・・・・・・

えーと、何が起こってるのかな~~

きれいに忘れていた。どこまで遡ればよろしいのか。ポインタだ、ポインタが出たぞーーう🔥 🐉

ポインタの中身はアドレス。うむ、それは知っている。そこまでは理解している。ええと、だから・・・ええとぉぉぉぉぉ・・・(一旦理解した後、すぐにちゃんと復習しないからこうなる)

おぉう、さすがなんである~~!いざとなったら泣きつくかも(←はためーわく)

今頑張って解読している・・・多分、なんとか生きていける、はず。とりあえず書いた。確保だ、確保ーーっっ。ちゃんと確保失敗した時のも書いた。えらい(いや、書くの当たり前だから、それ)

int* nums=(int*)malloc(max * sizeof(int));

なんでこんなにintだらけやねーん!!と思ったが、mallocもキャストがいるということをですね・・・後、int型の箱が欲しいなら、intのサイズをかけないといけないとか・・・ちみっとずつ思い出して来たことです。

後は、最後は解放してあげましょうね、と。とりあえず忘れるといけないから、先に書いておこう・・・

だがしかし、時間切れなんである・・・また今度(絶対また忘れる)。


maxなる変数の値とintのバイト数(4)をかけた大きさの領域をmallocで獲得してポインタ値をnumsへ格納すると。
ここでmaxが0や府の整数ではなくmallocへ渡す数値がシステム的に獲得可能である必要がありますだ。
読みやすいコーディング視点だと変数名が適当でない気がします。
あと、キャストしないとコンパイラがぶつぶつ言うのは仕様です。

ありがとーーです。じり、じり、と思い出して来たことです。変数名は、自分の勝手な法則があるので、ほかの人が見ると「なんじゃこりゃ」に・・・orz。

n:使い捨てのカウンター
num:整数(単体)
nums:整数を収める配列

ほかの人と組むことはないとしても、ほかの人に見てもらうなら、ちゃんと「一般的な作法」に沿った変数名にすべきですよねん・・・悩ましい・・・

maxは、素数チェックをする最大の数ですな。何のmaxか分からない。危険(分かっているなら書け)。

いや、それよりですよ・・・numsから2の倍数を削除、3の倍数を削除・・・とやるのだけれど、これってひょっとしてnumsの末尾から削除した方が処理は軽くなるです??後ろからの方が移動させるものが少ない・・・ですよねえ・・・?


AIに聞きました
---
素数判定のロジックは以下の手順で実装できます:

最初に、判定対象となる整数が1以下の場合は素数ではないと判定します。
次に、2からその数の平方根までの整数で順番に割り、割り切れるかどうかをチェックします。割り切れる場合はその数は素数ではありません。
上記の手順で2から平方根までのどの数でも割り切れなければ、その数は素数です。
この方法に基づいて、C言語での素数判定関数を作成することができます。

フォロー


C参考ソース
---
<stdio.h>
<math.h>

// 素数判定関数
int isPrime(int n) {
if (n <= 1) return 0; // 1以下は素数ではない
if (n == 2) return 1; // 2は素数

// 2からnの平方根までの数で割り切れるかチェック
int limit = sqrt(n);
for (int i = 2; i <= limit; ++i) {
if (n % i == 0) {
return 0; // 割り切れる場合は素数ではない
}
}
return 1; // 割り切れない場合は素数
}

int main() {
int num = 17; // 素数かどうかを判定したい数
if (isPrime(num)) {
printf("%d は素数です。\n", num);
} else {
printf("%d は素数ではありません。\n", num);
}
return 0;
}


完全数(Perfect Number)を求めるための基本的なロジックは以下の通りです:

整数n が完全数であるかどうかを判定するには、
n の約数の和がn 自身に等しいかを確認します。
n の約数の和を計算するには、nを除く
n 自身以外の正の約数を見つけ、その合計を取ります。
具体的には、1 から
n/2 までの数で
n を割り切れるかどうかを調べ、割り切れた場合はその数は
n の約数です。


サンプル
<stdio.h>

// 完全数判定関数
int isPerfect(int n) {
int sum = 0;
for (int i = 1; i <= n/2; ++i) {
if (n % i == 0) {
sum += i;
}
}
return (sum == n);
}

// メイン関数
int main() {
int num = 28; // 完全数かどうかを判定したい数
if (isPerfect(num)) {
printf("%d は完全数です。\n", num);
} else {
printf("%d は完全数ではありません。\n", num);
}
return 0;
}

ありがとうございます。平方根まででいいのか・・・ :ablobcat_wakaran:

分かる、ような、分からん、ような。ちょっとこれはこれで考えてみないと~。落ち着いて考えれば分かる・・・ような気がする。たぶん?

・・・ってああそうか、普段紙に書いて約数書き出す時、確かに「平方根」のところで分けてら。36の時、(1,36) (2,13) ・・・と両端から攻めて行って、(6,6)で終了する。つまり平方根までたどり着いたら、後はかけ算の裏返しになるから、いらないんだ・・・

大分計算を減らせますにゃ。

しかし・・・C言語やっぱり難しい・・・

ログインして会話に参加
Fedibird

様々な目的に使える、日本の汎用マストドンサーバーです。安定した利用環境と、多数の独自機能を提供しています。