リンカエラー2001 1120について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: リンカエラー2001 1120について

Re: リンカエラー2001 1120について

#19

by かずま » 4年前

高速化しました。これで、2147483647 も 2100000003 も OK。

コード:

#include <stdio.h>

void factor(int n)
{
	const int M = 46340;
    if (n > 0) {
		int r = (n == 1) ? 1 : 2;
		while (r < M && n % r) r++;
		if (r == M) r = n;
        printf("%d = %d", n, r);
        factor(-n / r);
    }
    else if (n < -1) {
		int r = 2;
        while (r < M && n % r) r++;
		if (r == M) r = -n;
        printf(" x %d", r);
        factor(n / r);
    }
}

int main(void)
{
    int n;
    while (printf(">> "), scanf("%d", &n) == 1)
        factor(n), putchar('\n');
}

Re: リンカエラー2001 1120について

#18

by かずま » 4年前

Math さんが書きました:
4年前
再帰を使う場合の例です。
viewtopic.php?t=8820
そのリンク先のプログラムが正しいかどうか確認しましたか?

#7 のプログラムは入力が 1 ~ 65535 の場合にしか正しい結果を出しません。

では、入力が 1 ~ 2147483647 に対応する再帰プログラムに書き直してみましょう。

コード:

#include <stdio.h>

void factor(int n)
{
    int r = 1;
    if (n > 0) {
        if (n > 1)
            for (r = 2; n % r; r++) ;
        printf("%d = %d", n, r);
        factor(-n / r);
    }
    else if (n < -1) {
        for (r = 2; n % r; r++) ;
        printf(" x %d", r);
        factor(n / r);
    }
}

int main(void)
{
    int n;
    while (printf(">> "), scanf("%d", &n) == 1)
        factor(n), putchar('\n');
}

Re: リンカエラー2001 1120について

#17

by Math » 4年前

再帰を使う場合の例です。
viewtopic.php?t=8820

Re: リンカエラー2001 1120について

#16

by かずま » 4年前

Math さんが書きました:
4年前
素因数分解はhttps://qiita.com/Wakaba_C/items/16d076ef2cc07836a29d等 多い題材ですが
リンクを張るのは、引用じゃないからいいのですが
なぜ、不完全なプログラムを紹介するのですか?

そのリンク先のプログラムには、
printf("%b %n");
という行があって、コンパイル時に警告が出ますし
Linuxで実行すると Segmentation fault (コアダンプ) となります。

2147483647 という入力にも対応していません。

Re: リンカエラー2001 1120について

#15

by Math » 4年前

素因数分解はhttps://qiita.com/Wakaba_C/items/16d076ef2cc07836a29d等 多い題材ですが
過去ログに何度も質問されていて 5950 件 ありますよ。

Re: リンカエラー2001 1120について

#14

by かずま » 4年前

おすし さんが書きました:
4年前
ようやく理解出来ました…
理解できたのは #2、#9、#10、#11 のどのプログラムですか?
#6 のプログラムはどこが悪いのか説明できますか?

#10のプログラムで、入力が 2147483647 でも高速に処理できるように
するには、次のようにすればよいのが分かりますか?

コード:

#include <iostream>
using namespace std;

int main()
{
	int suuzi;
	int a, c, i;
	int sosuu[32];
	const int M = 46340; // M = sqrt(2の31乗)

	cout << "数字を入れてください           ";
	cin >> suuzi;

	c = 2;
	for (a = 0; a < 32; a++) {
		for (i = c; i < M  && suuzi % i != 0; i++) ;
		if (i == M) i = suuzi;
		suuzi = suuzi / i;
		sosuu[a] = i;
		if (suuzi == 1) break;
		c = i;
	}

	cout << "suuzi = " << sosuu[0];
	for (c = 1; c <= a; c++)
		cout << " x " << sosuu[c];

	cout << "\n適当なキーを打って終了します";
	cin >> suuzi;
}
分からない時は、どこが分からないのかを言ってもらえれば説明します。

Re: リンカエラー2001 1120について

#13

by おすし » 4年前

ようやく理解出来ました…
何度もご指導いただき本当にありがとうございました!

Re: リンカエラー2001 1120について

#12

by かずま » 4年前

Math さんが書きました:
4年前
素因数分解 プログラム例

著作権を侵害せずに文章や画像を引用・転載する方法
著作物の無断利用ができる引用の条件は、次のとおりである。
(1) 既に公表されている著作物であること
(2)「公正な慣行」に合致すること
(4) 報道、批評、研究などのための「正当な範囲内」であること
(4) 引用部分とそれ以外の部分の「主従関係」が明確であること
(5) カギ括弧などにより「引用部分」が明確になっていること
(6) 引用を行う「必然性」があること
(7) 「出所の明示」が必要(コピー以外はその慣行があるとき)
とても模範解答と思えないプログラムを引用する必然性は何ですか?
引用部分でない部分はどこですか?


そのプログラムが模範解答と思えないのは次の点です。
・規格外の void main() となっている。
・gets を使っている。
・2147483647 の入力に対して正しく動作しないことが分かっているのに
 そのバグを修正していない。
・n だけあれば、n0 は不要ではないのか?
・ns = 2; が 2個所にある。
・if (j > 0) printf(...); と書けば continue; は不要。
・gets があれば、fflush は不要。

Re: リンカエラー2001 1120について

#11

by Math » 4年前

素因数分解 プログラム例

●数値を入力して、素因数分解の結果を表示するプログラムです。
●long型整数の正の最大値(2の31乗-1=2147483647)までの計算ができますが、
 実際に最大値を入力すると、正しい動作をしない場合があります。
 プログラムが終了しない場合は、Ctrlキーを押しながらCを押して強制終了します。

コード:

/****************/
/*  素因数分解  */
/****************/
#include <stdio.h>
#include <stdlib.h>

void  main( )
{
    char  c[128];
    int   n0,n;   // 整数
    int   ns=2;   // 素因数
    int   j;      // 乗数

    printf("\n★素因数分解★\n");
    printf("\n分解する整数: "); fflush(stdout);
    gets(c); n0=atoi(c);                    // 整数を入力

    for( n=n0,ns=2; n>=ns; ns++ )
      {
        for( j=0; n%ns==0; j++ )            // 割り切れる間繰り返す
         {
           n/=ns;
         }

        if ( j==0 ) continue;               // 1回も割り切れなかった

        printf("素因数:%d  乗数:%d\n",ns,j);
     }
}

[注]
●プログラムの著作者、著作権者は佐伯英子です。
●このプログラムは、複製、改変、無償再配布できます。

Re: リンカエラー2001 1120について

#10

by かずま » 4年前

おすし さんが書きました:
4年前
書くのを忘れてました…すみません。
yakusuuとsosuuの要素数を256にしました。

コード:

	for (a = 0; a < 8;a++)
	{

		for (i = 1; suuzi % i != 0; i++)
		{
			suuzi = suuzi / i;

			sosuu[a] = i;
		}

元のプログラムのこの部分でやりたかったことが少しわかってきました。
これを活かして書き直してみると、

コード:

#include <iostream>

using namespace std;
int suuzi;
int a, c, i;
int sosuu[32];   // 256 は多過ぎ。32で十分

int main()
{
	cout << "数字を入れてください           ";
	cin >> suuzi;

	for (a = 0; a < 32; a++) {  // 8 を 32 に
		for (i = 2; suuzi % i != 0; i++) ;  // 2から始める。ループ本体なし
		suuzi = suuzi / i;     // 割り切る数 i が見つかったので割る
		sosuu[a] = i;          // sosuu に i を登録
		if (suuzi == 1) break; // 1 なら素因数分解完了
	}

	cout << "suuzi = " << sosuu[0];
	for (c = 1; c <= a; c++)
		cout << " x " << sosuu[c];

	cout << "\n適当なキーを打って終了します";
	cin >> suuzi;
}
ただし 2以上の数値を入力しないとだめです。

実行例

コード:

数字を入れてください           30 (入力)
suuzi = 2 x 3 x 5
適当なキーを打って終了します.  (. を入力)
[/coce]

Re: リンカエラー2001 1120について

#9

by かずま » 4年前

おすし さんが書きました:
4年前
if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break;
つまりこの部分で0が出ないよう修正すればいいということですかね?
違います。

コード全体がわけの分からないものになっています。

cin >> suuzi; で、キーボード入力の数値が suuzi に入ります。
これが 30 だったとしましょう。

for (a = 0; a < 8; a++) で a は 0 になり、これは 8 より小さいので
for文の中に入り、for (i = 1; suuzi % i != 0; i++) に進みます。
i は 1 です。
suuzi % i は 12 を 1 で割った余りなのでその値は 0 です。
その値が 0 と等しいのでこの for文の中には入りません。
{ suuzi = suuzi / i; sosuu[a] = i; } は全く実行されません。

suuzi が 12 であろうが、30であろうが、なんであったとしても
それを 1 で割れば割り切れます。余りは 0 です。
suuzi % 1 は常に 0 です。
この for文のループは一度も実行されません。
無意味なコードを書いているわけです。

suuzi++; で suuzi は 31 になります。
sosuu[a]++; で sosuu[0] は 1 になります。

これも意味が分かりません。
suuzi を 31 にして何がしたいんですか?
sosuu[0] が 1 になっていいんですか?

すべての変数や、文や式の処理には意味があります。
適当に並べているのではありません。
プログラムとはそういうものです。

30 を素因数分解すると 2 x 3 x 5 です。
やりたいことは
 sosuu[0] = 2
 sosuu[1] = 3
 sosuu[2] = 5
となるようにすることですよね。

30 を 2 で割ってみると、割り切れて商は 15。
30 = 2 x 15
15 は 2 で割り切れないから、30 の中に 2 は 1個しかない。
今度は 15 を 3 で割ってみる。
15 = 3 x 5
5 は 3 で割り切れないから、30 の中に 3 は 1個しかない。
次に 5 を 4 で割ってみる。
なんで 4 で割るんだ?
4 は素数じゃないぞ。
5 で割るべきだろう。
そうなんだけど、今まで、2、3 と割ってきて、
次の素数が 5 だということはまだ分かっていません。
割る数は、2、3、4、5、6... と順番に行くしかありません。
素数じゃない 4 は 2 x 2 で、2で割ることは既に済んでいるので
もう 4 で割り切れることはありません。
最後に 5 を 5 で割ってみて、商は 1。
1 になったら終わりです。

ここまでは分かりますか?
分からないところはどこですか?

分かったら次のようなコードが書けませんか?

コード:

	suuzi = 30;
	i = 0; // sosuuの添字 (sosuu[i])
	w = 2; // 割る数 (2, 3, 4...)
	while (1) {
		if (suuzi % w == 0) {  // 割り切れたら
			sosuu[i++] = w;      // w を sosuu に登録
			suuzi /= w;          // suuzi を更新
			if (suuzi == 1) break;  // 数字が 1 なら終了
		}
		else {  // 割り切れなかったら
			w++;  // 次の割る数
		}
	}

Re: リンカエラー2001 1120について

#8

by おすし » 4年前

入力データの意味すらあやふやでした、、、失礼しました。入力した数字は30です。
かずま さんが書きました:
4年前
仮に 12 を入力したとします。
期待する出力は suuzi = 2 x 2 x 3 ですよね。
違いますか?
おっしゃる通りです

コードの解説ありがとうございます。
if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break;
つまりこの部分で0が出ないよう修正すればいいということですかね?


#2のプログラムは参考にはなったのですが何処を修正すればよいのか見当がつきませんでした、、、

Re: リンカエラー2001 1120について

#7

by かずま » 4年前

最後に } がないのでコンパイルエラーになりますが、
まあ、これはコピペを失敗しただけでしょう。
かずま さんが書きました:
4年前
そのメッセージが出た時の「入力データ」を書いてください。
なぜ、こんな簡単なお願いに応えてくれないのでしょうか?
仮に 12 を入力したとします。
期待する出力は suuzi = 2 x 2 x 3 ですよね。
違いますか?

コードを追っていきましょう。

プログラムは main から始まります。

その時に、グローバル変数はすでに初期化されています。
int kaisuu = 0; のように初期値を明示的に書いていると
その値になります。
初期値の指定がない場合、すべて 0 に初期化されます。

cin >> suuzi; で、キーボード入力の数値が suuzi に入ります。
これが 12 だったとしましょう。

for (a = 0; a < 8; a++) で a は 0 になり、これは 8 より小さいので
for文の中に入り、for (i = 0; suuzi % i != 0; i++) に進みます。
i は 0 です。
suuzi % i は 12 を 1 で割った余りなのでその値は 0 です。
その値が 0 と等しいのでこの for文の中には入りません。
{ suuzi = suuzi / i; sosuu[a] = 1; } は全く実行されません。

suuzi++; で suuzi は 13 になります。
sosuu[a]++; で sosuu[0] は 1 になります。

int c; でローカル変数 c を宣言すると、
グローバル変数の c は参照できなくなります。

for (c = 1; c <= suuzi; c++) で c は 0 になり、その値は suuzi の
13 以下なので、for文の中に入ります。

if (suuzi % c == 0) で 13 を 1 で割った余りは 0 なので、if文の中に入り、
kaisuu++; で kaisuu は 1 になります。
yakusuu[kaisuu] = c; で kaisuu[1] が 1 になります。

for文の c++ に戻り、c は 2 になります。
これは suuzi の 13 以下なので、forループを継続します。

if (suuzi % c == 0) で 13 を 2 で割った余りは 1 なので、
if文の中には入りません。
{ kaisuu++; yakusuu[kaisuu] = c; } は実行されません。

for文の c++ に戻り、c は 3 になります。
これは suuzi の 13 以下なので、forループを継続します。

if (suuzi % c == 0) で 13 を 3 で割った余りは 1 なので、
if文の中には入りません。
{ kaisuu++; yakusuu[kaisuu] = c; } は実行されません。

for文の c++ に戻り、c は 4 になります。
これは suuzi の 13 以下なので、forループを継続します。

if (suuzi % c == 0) で 13 を 4 で割った余りは 1 なので、
if文の中には入りません。
{ kaisuu++; yakusuu[kaisuu] = c; } は実行されません。

for文の c++ に戻り、c は 5 になります。
これは suuzi の 13 以下なので、forループを継続します。

if (suuzi % c == 0) で 13 を 5 で割った余りは 3 なので、
if文の中には入りません。
{ kaisuu++; yakusuu[kaisuu] = c; } は実行されません。

for文の c++ に戻り、c は 6 になります。
これは suuzi の 13 以下なので、forループを継続します。

if (suuzi % c == 0) で 13 を 6 で割った余りは 1 なので、
if文の中には入りません。
{ kaisuu++; yakusuu[kaisuu] = c; } は実行されません。

このように for (c = 1; c <= suuzi; c++) のループを何度も回り、
c が 13 になった時、
if (suuzi % c == 0) で 13 を 13 で割った余りが 0 なので、
if文の中には入ります。
kaisuu++; で kaisuu は 2 になります。
yakusuu[kaisuu] = c; で yakusuu[2] は 13 になります。

for文の c++ に戻り、c は 14 になります。
これは suuzi の 13 以下ではないので、for文の中には入りません。
while (1) に進みます。

for (int d = 0; d <= kaisuu; d++) で d は 0。kaisuu の 2 以下なので
for文の中に入ります。

if (suuzi / yakusuu[d] == 0 では、suuzi が 12、yakusuu[0] が 0
なので、割り算の結果を求めることができず例外が発生し、
プログラムが異常終了します。

yakusuu[1] は 1、yaksuu[2] は 13 ですが、
yakusuu[0]、yakusuu[3]~yakusuu[255] はすべて 0 のままです。

ところで、#2 のプログラムは参考なりませんでしたか?

Re: リンカエラー2001 1120について

#6

by おすし » 4年前

書くのを忘れてました…すみません。
yakusuuとsosuuの要素数を256にしました。

コード:

#include <iostream>

using namespace std;
int suuzi;
int a,c, i;
int sosuu[256];
int Tekitou;
int yakusuu[256];
int kaisuu = 0;

int main()
{
	cout << "数字を入れてください           ";
	cin >> suuzi;

	for (a = 0; a < 8;a++)
	{

		for (i = 1; suuzi % i != 0; i++)
		{
			suuzi = suuzi / i;

			sosuu[a] = i;
		}
		suuzi++;
		sosuu[a]++;

		int c;
		        

		for (c = 1; c <= suuzi; c++)
		{
			if (suuzi % c == 0)
			{
				kaisuu++;
				yakusuu[kaisuu] = c;
			}
		}
		while (1)
		{
			for (int d = 0; d <= kaisuu; d++)
			{
				if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break; //ハンドルされていない例外
			}
			goto end;
		}
	}
	end:
	cout << "suuzi = ";
	for (int b = 0; b <= a; b++)
	{
		cout << sosuu[b] << "×";
	}
	cout << "適当なキーを打って終了します";
	cin >> Tekitou;

Re: リンカエラー2001 1120について

#5

by かずま » 4年前

おすし さんが書きました:
4年前
教えてもらった通りに修正したら、コンパイルは通ったのですが
どのように修正したのか、こちらから見えません。
コンパイルが通ったプログラム全体を見せてください。
おすし さんが書きました:
4年前
実行すると、
if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break;のところで『ハンドルされていない例外が発生しました。』というメッセージが出てしまいました。
yakusuu[d] が 0 だったんだと思います。
そのメッセージが出た時の「入力データ」を書いてください。

Re: リンカエラー2001 1120について

#4

by おすし » 4年前

返信ありがとうございます。
教えてもらった通りに修正したら、コンパイルは通ったのですが実行すると、
if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break;のところで『ハンドルされていない例外が発生しました。』というメッセージが出てしまいました。
これはどういう意味なんですかね。。。?

Re: リンカエラー2001 1120について

#3

by かずま » 4年前

かずま さんが書きました:
4年前

コード:

	for (int b = 1; b < a; b++)
a を i に訂正します。

コード:

	for (int b = 1; b < i; b++)

Re: リンカエラー2001 1120について

#2

by かずま » 4年前

おすし さんが書きました:
4年前
c++で素因数分解をするプログラムを作っているのですが実行しようとすると下のようなエラーが出てきてしまいます。どうやったら解決できますか?
配列を宣言するときは、サイズを指定しましょう。

コード:

#include <iostream>
using namespace std;

int main()
{
	int suuzi = 120, sosuu[32], a = 2, i = 0;

	do {
		if (suuzi % a == 0)
			suuzi /= sosuu[i++] = a;
		else
			a++;
	} while (suuzi > 1);
	cout << "suuzi = " << sosuu[0];
	for (int b = 1; b < a; b++)
		cout << " x " << sosuu[b];
	cin >> a;
}
これは、参考となるプログラムで、本当は suuzi を入力させたり、
suuzi が 1 の場合の処理の追加が必要です。

リンカエラー2001 1120について

#1

by おすし » 4年前

c++で素因数分解をするプログラムを作っているのですが実行しようとすると下のようなエラーが出てきてしまいます。どうやったら解決できますか?
ご教授お願いします。

LNK2001 外部シンボル ""int * sosuu" (?sosuu@@3PAHA)" は未解決です。
LNK2001 外部シンボル ""int * yakusuu" (?yakusuu@@3PAHA)" は未解決です。
LNK1120 2 件の未解決の外部参照

コード:

#include <iostream>

using namespace std;
int suuzi;
int a,c, i;
int sosuu[];
int Tekitou;
int yakusuu[];
int kaisuu = 0;

int main()
{
	cout << "数字を入れてください           ";
	cin >> suuzi;

	for (a = 0; a < 8;a++)
	{

		for (i = 1; suuzi % i != 0; i++)
		{
			suuzi = suuzi / i;

			sosuu[a] = i;
		}
		suuzi++;
		sosuu[a]++;

		int c;
		        

		for (c = 1; c <= suuzi; c++)
		{
			if (suuzi % c == 0)
			{
				kaisuu++;
				yakusuu[kaisuu] = c;
			}
		}
		while (1)
		{
			for (int d = 0; d <= kaisuu; d++)
			{
				if (suuzi / yakusuu[d] == 0 && yakusuu[d] != 1 && yakusuu[d] != suuzi) break;
			}
			goto end;
		}
	}
	end:
	cout << "suuzi = ";
	for (int b = 0; b <= a; b++)
	{
		cout << sosuu[b] << "×";
	}
	cout << "適当なキーを打って終了し/ます";
	cin >> Tekitou;
}

ページトップ