ページ 11

ポインタ malloc

Posted: 2013年4月22日(月) 01:25
by 魔王
c言語の練習問題なのですが平均値の関数などはなんとかできるのですがmallocとか言われて訳分からなくなっています。
よろしくおねがいします。ただしrand10000.csvのデータはこちらにあるので読み込ますプログラミングをよろしくおねがいします。


問)長さ n の整数型配列ary[] の平均値を求める関数を作成し, その関数にポインタ変数 int *pで指定されるメモリ領域を与えて平均値を表示させなさい. ただし,p で指定される領域は, main() 関数において, 正の整数値 n を scanf() 関数で決定させ,malloc() 関数を 用いて確保した領域とし,その領域に rand10000.csv のデータを読み込ませたものを用いるものとする.

Re: ポインタ malloc

Posted: 2013年4月22日(月) 07:14
by beatle
mallocは基本的な(けれどもprintfなどよりは応用的な)C言語の関数です。
取り扱っている教科書も多いと思いますが、お手持ちの書籍には書いてありませんか?

web教科書ではC言語編 第34章 ポインタ④(動的なメモリ①)あたりに書いてあります。
掲示板でかいつまんだ説明を読むより、まとまった本なりホームページなりで学習するといいと思います。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 10:02
by 魔王
まだc言語はじめてまもないのでよくこのへんはわかっていません。
できればプログラム例を示していただいたほうがwebとの比較で勉強になるのですが。
一例示してはいただけないでしょうか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 11:01
by softya(ソフト屋)
フォーラムルールで丸投げは禁止させて頂いております。
http://dixq.net/board/board.html
フォーラムルールに質問テンプレートがあるのでお使いください。

問題と関係なく分からないmallocの例を上げて頂ければ説明できると思います。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 11:16
by 魔王

コード:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define N 500

int average(int ary[],int n)

int main (void)
{
	int i,ave;
	int ary[N];
	int *p;

	p=(int*)malloc(sizeof(int)*N);
	
	if(p==0) exit(0);


	for(i=0;i<N;i++)
	{
		scanf("%d",ary[i]);
	}
	ave=average(ary,N);
	printf("%d",ave);

	free(p);


	return 0;
}

int average(int ary[],int n)
{
	int i;
	int sum;
	for(i=0;i<=N;i++)
	{
		sum+=ary[i];
	}

	return sum/N;
}
一応webをみながらまねて作ってみたのですがよくわかりません。とくにmain関数部分が。修正、指摘をしていただけないでしょうか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 11:38
by softya(ソフト屋)
codeタグを直しておきました。[]が必要なのでプレビューで確認してくださいね。

とりあえず問題文の回答とは違うプログラムなのですね。
そうですね。
まず、mallocの動作を理解しないと話になりませんね。

どの位理解しているかですが、この穴埋め問題は分かりますか?

コード:

#include <stdio.h>
#include <stdlib.h>
 
int main (void)
{
	int n=10;
	int i;
	int *p;

	//	メモリを確保する サイズは[(1)]バイトで[(2)]型のポインタ値を得る。
	p=(int*)malloc(sizeof(int)*n);
	//	[(3)]だったら、終了する。
	if(p==0) exit(0);
	
	//	mallocしたpを[(4)列]として扱い[(5)]とした値を入れる。
	for( i=0 ; i<n ; i++ ) {
		p[i] = n-i;
	}

	//	p[(4)列]に入れた値を表示する。入れた値の並びは[(6)]となる。
	for( i=0 ; i<n ; i++ ) {
		printf( "%d ", p[i]);
	}
	printf("\n");

	return 0;
}
実行せずに、お答えください。

【補足】 この場合のint型は4バイトとします。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 11:42
by usao
現状だと mallocした領域をまるで使ってないように思いますが…
問題文を見る限り

(1) n の値を scanf()でユーザが指定する
(2) n個の整数を格納できる領域を malloc() で確保する
(3) (2)で確保した領域に,ファイルrand10000.csvからデータをn個読み込む
(4)平均値を計算
(5) (2)で確保した領域を free() で解放

という手順を踏むものと思いますが,現状ではいろいろと違っている模様.

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:17
by 魔王
10
int
NULL
配列
五番六番は分かりません

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:30
by 魔王

コード:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

int average (int ary[] , int n)

	int main (void)
{
	int i;
	int n;
	int *p;
	int sum;
	scanf("%d",&n);
	p=(int*)malloc(sizeof(int)*n);

	if(p==0) exit(0);

	for(i=0;i<n;i++)
	{
		scanf("%d",&p[i]);
		
	}


	int ave;
	ave = average(p,i );

	free(p);

	return 0;


}

int average(int ary[],int n)
{
	int i;
	int sum;
	for(i=0;i<n;i++)
	{
		sum+=ary[i];
	}

	return sum/i;
}
もう一度作ってみました。少しはマシにはなったと思ってるんですが。。。。。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:40
by usao
かなりよくなったというか あとは 配列に値をscanf()で一個ずつ入れているところを
ファイル読込にすれば完成でしょう.がんばれー.

・average()の第二引数は iじゃなくてnのほうがいいと思う.(値は結果として一緒だけど)
・main()のint sum は使われてない.投稿(?)する場合は不要なものは取っ払った方がいいかも.
・主題じゃないけど,平均って整数で良いのだろうか.

#ところで[(5)]と[(6)]になんという日本語を求められているのか,私もわからない…w

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:47
by 魔王

コード:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

int average (int ary[] , int n)

	int main (void)
{
	int i;
	int n;
	int *p;

	scanf("%d",&n);
	p=(int*)malloc(sizeof(int)*n);

	if(p==0) exit(0);

	for(i=0;i<n;i++)
	{
		p[i]=i;
		
	}


	int ave;
	ave = average(p,n);

	free(p);

	return 0;


}

int average(int ary[],int n)
{
	int i;
	int sum;
	for(i=0;i<n;i++)
	{
		sum+=ary[i];
	}

	return sum/i;
}
これでどうでしょうか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:52
by non
16行
if(p==0) exit(0);

if(P==NULL) exit(1);
が私の好み。

逆順か・・・

Re: ポインタ malloc

Posted: 2013年4月22日(月) 13:58
by 魔王
exit(0)とexit(1)とでは大きな差があるのですか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:03
by non
ないです。

ただ、慣例で、正常に終わったときに0をOSに返し、異常終了の場合は1を返します。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:07
by 魔王
ありがとうございます。
私が問題にそってつくったプログラムに修正点はありますか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:08
by usao
>これでどうでしょうか?

>rand10000.csv
なるファイルから値をn個読み込んで使う という話ではないのですか?
そのことが質問内容とはあまり関係なくて malloc(),free() の使い方あたりがわかればよい という目的なら,
あとはコンパイル通る形にされればよいかと思います.

細かい点を言えば,
・average()プロトタイプ宣言のとこの ; がさっきからないよ
・変数は初期値をいれておくように心がけたほうがいいと思う.(int *p=NULL; とか.)
・先ほどのaverage()への引数もそうでしたが,average()内の最後の行も sum/n としたいところです.
 変数の"役割を正しく"…とでもいうか.(nは要素の個数を表す役目だけど,iはちょっと違いますよね)

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:11
by softya(ソフト屋)
魔王 さんが書きました:10
int
NULL
配列
五番六番は分かりません
(1)は違います。10は数であってバイト数では無いですね。
(5)(6)が分からないのはポインタが分からないのか、配列が分からないのかどちらでしょう?

> (5)(6)が分からないのはポインタが分からないのか、配列が分からないのかどちらでしょう?
他にも分からないとの意見有ったので補足します。

(5) 配列に代入される数列のルールを記載してください。
(6) printfで一行に表示される値を記載してもらえば良いです。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:14
by usao
あっ,average()内のsumに初期値0が入ってないですね.
投稿前に ちゃんと自分で動かして確認してますか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:16
by box
魔王 さんが書きました:

コード:

	int ave;
ここでコンパイルエラーが出ませんか?変数定義の場所の件で。
魔王 さんが書きました:

コード:

	ave = average(p,n);
平均値を求めた後、それを出力しなくていいのですか?
魔王 さんが書きました:

コード:

	int sum;
	for(i=0;i<n;i++)
	{
		sum+=ary[i];
	}
sumを0で初期化せずに値を足し込んでいるのは、ひじょうにまずいと思います。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:17
by 魔王
わかりました。ありがとうございます。
変数がいっぱいになてくると何がなにやらわからなくなってくるんですよね。。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:24
by 魔王

コード:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

int average (int ary[] , int n);

	int main (void)
{
	int i;
	int n;
	int *p;

	scanf("%d",&n);
	p=(int*)malloc(sizeof(int)*n);

	if(p==0) exit(0);

	for(i=0;i<n;i++)
	{
		p[i]=i;
		
	}


	int ave;
	ave = average(p,n);
	printf("%d",ave);

	free(p);

	return 0;


}

int average(int ary[],int n)
{
	int i;
	int sum=0;
	for(i=0;i<n;i++)
	{
		sum+=ary[i];
	}

	return sum/n;
}
ご指摘ありがとうございます。
修正しなおしました。またこれでエラーは起こりませんでした。
また手元にデータファイルrand10000.csvがないので答えは確認できませんが
このプログラミング自体最初は意味不明だったのでエラーがなくさらに綺麗にできるようにするのが自分への課題です。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:32
by non
まだ、ファイルの読み込みを作らなくてはいけないのでは?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:35
by 魔王
ファイルの読み込み?
それはコンパイル時に  ./ソースファイル<rand10000.csv
では読み込まれないのでしょうか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:42
by softya(ソフト屋)
私の問いにも答えてもらった方が理解が進むと思います。

>また手元にデータファイルrand10000.csvがないので答えは確認できませんが

テストのためには自分で作る必要があります。

>それはコンパイル時に  ./ソースファイル<rand10000.csv
>では読み込まれないのでしょうか?

#includeの事なら、一般的にヘッダファイルの読み込みの機能でデータを読み込むものではありません。
ファイル操作は理解されていないでしょうか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:49
by non
リダイレクションかも知れないけど、問題の感じからすると、
恐らく、ファイルをオープンしてテキストファイルの読み込みだと思う。
できれば、rand10000.csvの書式を知りたいところ。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:49
by 魔王
下記の全文書を参照しています。

dat ファイルなどのデータファイルをプログラムへ読み込ませる方法は?という質問があったので例として回答してみます.

scanf() などを使ったキーボードからのデータ読み込み(正確には標準入力 stdin からの読み込み)をファイルなどから行いたい場合には,リダイレクトを使います.

#include <stdio.h>

int main( void )
{
int x;
scanf( "%d", &x );
printf( "input x is %d\n", x );
return 0;
}

などをコンパイルして,a.out などの実行ファイルを作った場合,

さらにデータファイルとして,

123

などと1行目にデータが入ったテキストのファイルを作り,data.txt とした場合,

$ ./a.out < data.txt
x = 123

となるはずです.

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:53
by softya(ソフト屋)
私のは答えてもらえそうにないですね。
引っ込みます。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 14:58
by 魔王
配列は分かってるつもりですがポインタは現在進行中で躓いています
見逃していました。すみませんでした

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:08
by softya(ソフト屋)
見逃していたのなら、他に見逃しが無いか確認してみてください。

この問題ですが、ファイルを読み込むやmalloc以前にポインタを理解していないといけない問題です。
なので、問題を解く事だけを急がずにポインタを理解・復習をまずすべきだと私は思います。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:16
by non
リダイレクトなわけね。

2行目以降のデータはどうなっているのか?
csvファイルならカンマ区切りの可能性が高いが、1行のデータ個数は可変か、固定かなど不明点が多い。
それとも、スペース区切りと考えて良いのだろうか。それとも1行に1データ?

100歩譲っても、添付のプログラムでは、データが読み込まれない。

P.S.
mallocで確保されたバイト数とポインタpとの関係はよく理解しておいた方が良いと私も思います。
絵を描いてみた方が良いのですが。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:17
by 魔王
ポインタを理解しようとおもうのですが毎回あいまいに終ってしまいます。
よろしければ何か参照webページありますか?
自分は今苦しんで覚えるc言語で勉強しています。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:21
by 魔王
読み込まれないのですか?
うーん。。どうしたらよいのかわかりません。

絵をかくのですか?ポインタあたりからwebでも絵を使い出してきて意味不明になってしまいました。
あの絵は重要なのですか。。。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:38
by non
リダイレクトでも、scanfなどを使わないとデータは読み込めません。

絵は重要だと私は思います。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:42
by 魔王
malloc関数の上にscanfがありますがそこにはいかないのでしょうか?

絵を描いてもう一度勉強してみます。
ちなみにオススメ参考webまたは書物などはありますか?

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:48
by non
あれは、データの個数を読んでます。
実際のデータは20行目の
p=i;
のところで読みます。

それより、
まず、ソフト屋さんの質問でmallocされたバイト数はいくらでしょうか?ソフト屋さんが答えを待ってますよ。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 15:58
by usao
「C ポインタ」で検索して最初にでてきたページだけど
絵→ここに書いてあるような概念図を自分のコードに当てはめて描ければいいのかな?
http://www9.plala.or.jp/sgwr-t/c/sec10.html

本としては,
先日,本当に初心者の人がバイトで入ってきた(!)際に,「やさしい C++」という本を買いました.
何も知らない人が,Cの導入~C++のさわり くらいを学習するのによさそうな丁寧具合だったので.
実際,彼は1週間くらいでちょっとしたファイル操作くらいはできる状態になりましたので,たぶんおすすめ.
(Cオンリーの「やさしいC」もある模様)

Re: ポインタ malloc

Posted: 2013年4月22日(月) 16:04
by 魔王
では20行目にscanf("%d",&i)がいるということですか?

バイト数は分かりません。とりあえず1ビット=8バイトなのとmallocのあとに必要なバイト数がくることは分かります

その書物一度検討させていただきます

Re: ポインタ malloc

Posted: 2013年4月22日(月) 16:07
by softya(ソフト屋)
> バイト数は分かりません。とりあえず1ビット=8バイトなのとmallocのあとに必要なバイト数がくることは分かります
ヒントは書いておいたんですが。

「初心者のためのポイント学習C言語」 ← ここは図が多いので読んでみてください。
http://www9.plala.or.jp/sgwr-t/index.html
第 2 章 データの扱い
第 9 章 2次元配列
第10章 ポインタ
を読んで分からないことを試してみて、それでも分からないなら聞いてください。

>絵を描いてもう一度勉強してみます。
>ちなみにオススメ参考webまたは書物などはありますか?

図の豊富な「Cの絵本」です。

Re: ポインタ malloc

Posted: 2013年4月22日(月) 16:12
by 魔王
分かりました。
勉強してみます。
参考文献紹介ありがとうございます