簡単な閾値処理

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

簡単な閾値処理

#1

投稿記事 by けるびん » 18年前

いつもお世話になっています。今、下のような課題が出されたのですが。


【実行の流れ】
1.コマンドラインから配列の縦(横)の値(2≦N≦10)と閾値(1≦th≦9)を与える.

2.入力されたNの値に従って,N×Nの配列を生成する.

3.1~9までの乱数を発生させ、配列の全ての要素に値を代入し,その結果を表示する.

4.コマンドラインから入力した閾値の値よりも,配列の各要素が大きければ"1"を,小さければ"0"を代入し,結果を再び表示する.

(例)
配列の行(列)数:N = 4、閾値:threshold = 5のとき

乱数を配列の各要素ごとに代入
┌─┬─┬─┬─┐
│2│7│2│9│
├─┼─┼─┼─┤
│6│5│6│7│
├─┼─┼─┼─┤
│1│3│8│6│
├─┼─┼─┼─┤
│4│3│3│5│
└─┴─┴─┴─┘

    ↓

5以上の値は"1"に,5より小さい値は"0"になる.
┌─┬─┬─┬─┐
│0│1│0│1│
├─┼─┼─┼─┤
│1│1│1│1│
├─┼─┼─┼─┤
│0│0│1│1│
├─┼─┼─┼─┤
│0│0│0│1│
└─┴─┴─┴─┘

課題1では配列処理で、課題2ではポインタもしくはポインタのポインタを使った処理を実行するようなプログラムを作成しなければいけないんです。

配列処理のほうはできたので、課題2は課題1の入力部分をポインタ(またはポインタのポインタ)にすればいいかという考えでいたんですが、セグメンテーション違反になってしまい、実行できません。

先生が言うには、アドレス操作にfor文を使うと危ないと言うので、試行錯誤したんですがなかなかできません。

この配列処理のどこをどう工夫すればポインタ(またはポインタのポインタ)で表現できるのでしょうか?教えてください。

また、セグメンテーション違反の原因はどういうことが考えられるのか教えてください

けるびん

Re:簡単な閾値処理(追伸)

#2

投稿記事 by けるびん » 18年前

プログラムです

Re:簡単な閾値処理(追伸)

#3

投稿記事 by » 18年前

まず確認します。
このプログラムはCまたはC++ですよね?
違いましたら以下の文章は無視してください。

…このプログラムは実行できましたか?
僕の方はコンパイルが通らなかったので^^;
配列はこういう制御が不可能だったと思うのですがどうでしょうか?

セグメンテーションという単語は僕は分からないのですが、配列の設定ミスのことでは無いんですよね?

Re:簡単な閾値処理(追伸)

#4

投稿記事 by » 18年前

まず確認します。
このプログラムはCまたはC++ですよね?
違いましたら以下の文章は無視してください。

…このプログラムは実行できましたか?
僕の方はコンパイルが通らなかったので^^;
配列はこういう制御が不可能だったと思うのですがどうでしょうか?

セグメンテーションという単語は僕は分からないのですが、配列の設定ミスのことでは無いんですよね?

もう一つ、このプログラムを実行した結果を載せてください。
配列の方も完成はしていません。
きちんと実行して確認してください。

このままだと課題を適当にやっているだけで、丸投げと変わらないです。

Re:簡単な閾値処理(追伸)

#5

投稿記事 by » 18年前

すいません、編集のつもりでミスをしました。
一つ目の方を無視してください。

miyaza

Re:簡単な閾値処理(追伸)

#6

投稿記事 by miyaza » 18年前

int array[N][N];
とありますがプログラム中で配列の要素数を変更することは出来ません。
ただ、GCCは出来るそうですが、よく知りません。

Re:簡単な閾値処理(追伸)

#7

投稿記事 by » 18年前

一様ポインターの方も出来ました。
ただ、
>先生が言うには、アドレス操作にfor文を使うと危ない
が、理解できていないので、無視して行っています。

それで良く、そちらが実行可能なものをアップしていただければ、
こちらもアップしたいと思っています。
(.cppファイルですが.cの方がよい時は少しいじれば思った動きになるはずです。)

けるびん

Re:簡単な閾値処理(追伸)

#8

投稿記事 by けるびん » 18年前

返信ありがとうございます。
どうやら、与える情報が少なかったようです。失礼しました。
プログラムはC言語で、gcc~といった感じでコンパイルします。
OSはLINUXでKNOPPIXを使っています

int array[N][N];

の部分はやってみた結果、問題ありませんでした。
あと、コンパイルも問題なくできました。

実行した結果は

配列の行(列)数:N = 4、閾値:th= 4のとき

┌─┬─┬─┬─┐
│2│7│2│9│
├─┼─┼─┼─┤
│6│5│6│7│
├─┼─┼─┼─┤
│1│3│8│6│
├─┼─┼─┼─┤
│4│3│3│5│
└─┴─┴─┴─┘
   ↓
┌─┬─┬─┬─┐
│0│1│0│1│
├─┼─┼─┼─┤
│1│1│1│1│
├─┼─┼─┼─┤
│0│0│1│1│
├─┼─┼─┼─┤
│1│0│0│1│
└─┴─┴─┴─┘

というふうになります。
2値化が分かりやすいようにしているつもりです。

プログラムはもう少し考えてからUPさせてもらいます。
こちらではコンパイルできるのに雷様の場合できないというのは明らかにおかしいので。

こちらがおかしいということを前提に考えますので、もう少し待ってもらえませんか?
もし、できた場合はUPを御願いします

miyaza

Re:簡単な閾値処理(追伸)

#9

投稿記事 by miyaza » 18年前

>プログラムはC言語で、gcc~といった感じでコンパイルします。
GCCを使用されていたようですね。
それならint array[N][N];
でエラーしないのもわかります。

フリオ

Re:簡単な閾値処理(追伸)

#10

投稿記事 by フリオ » 18年前

 
 式文の途中での変数の宣言、配列の宣言時での要素数の変数の使用
が標準になるのは、C99からだったはずなので、こちらで試したところ、

OSは、Windows2000 SP4、

BCC32 5.5.1では、当然、
 エラー E2140 test001.c 19: ここでは宣言はできない(関数 main )
 エラー E2313 test001.c 19: 定数式が必要(関数 main )
 エラー E2313 test001.c 19: 定数式が必要(関数 main )
で、コンパイルできず。

gcc 3.4.4(cygwin)では、コンパイル、実行、共に問題無しでした。

一応、私が考えたものを載せておきます。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int **Make(int n)
{
	int **array, i;
	
	if(!(array = malloc(sizeof(int *) * n))) return NULL;
	for(i = 0; i < n; i ++){
		if(!(array = malloc(sizeof(int) * n))){
			while(i --) free(array);
			free(array);
			return NULL;
		}
	}
	return array;
}

void Init(int **array, int n)
{
	int i, j;
	
	srand(time(NULL));
	for(i = 0; i < n; i ++){
		for(j = 0; j < n; j ++) array[j] = rand() % 9 + 1;
	}
}

void Threshold(int **array, int n, int th)
{
	int i, j;
	
	for(i = 0; i < n; i ++){
		for(j = 0; j < n; j ++) array[j] = (array[j] >= th);
	}
}

void Print(int **array, int n)
{
	int i, j;
	
	for(i = 0; i < n; i ++){
		for(j = 0; j < n; j ++) printf("%d ", array[j]);
		putchar('\n');
	}
}

void Free(int **array, int n)
{
	int i;
	
	for(i = 0; i < n; i ++) free(array);
	free(array);
}

int main(void)
{
	int **array, n, th;
	
	scanf("%d %d", &n, &th);
	if(!(array = Make(n))) return 1;
	Init(array, n);
	Print(array, n);
	putchar('\n');
	Threshold(array, n, th);
	Print(array, n);
	Free(array, n);
	return 0;
}

けるびん

Re:簡単な閾値処理(実行結果)

#11

投稿記事 by けるびん » 18年前

やはり、ちゃんとコンパイルできました。
謎が深まるばかりです。
OSの違いでしょうか?

あまり詳しくないので良く分かりませんが、
友達はWINDOWSでコンパイルするのと
KNOPPIXでコンパイルするのでは、コンパイルが通るときと通らないときがあるとか。

謎です

けるびん

Re:簡単な閾値処理

#12

投稿記事 by けるびん » 18年前

やはり、malloc関数が使ってありますか。
またこれも、「malloc使ってもいい」と先生に言われていたんですが、
よく分からなかったので使っていませんでした。

プログラムの流れはよく分かるんですが、できればmalloc関数について
詳しく教えていただきませんか?

Re:簡単な閾値処理(実行結果)

#13

投稿記事 by » 18年前

すいません。
こちらはBCCでやっていました。
GCCと言うものを知らず、申し訳ありませんでした。

一様UPしておきますが、ポインタは適当に代入しちゃっています。
して良いことかどうかは分かりませんが、、、
見当違いな発言、すいませんでした。

けるびん

Re:簡単な閾値処理(お礼)

#14

投稿記事 by けるびん » 18年前

返信ありがとうございました。
いろいろ調べてみます。

閉鎖

“C言語何でも質問掲示板” へ戻る