913 :
デフォルトの名無しさん:
[1] 授業単元:Cプログラミング演習
[2] 問題文:50個の整数データを読み込み、それらを小さい順に出力する
cプログラムを作成せよ。バブル整列法は使ってはいけない。
[3] 環境
[3.1] OS:Linux
[3.2] コンパイラ名とバージョン: gcc
[3.3] 言語: Cのみ
[4] 期限: 2006年12月23日12:00まで
よろしくお願いします。
>913
前スレにも書いた?
915 :
796:2006/12/12(火) 21:22:36
>>889 free( (void*)p ) とか memset( (void*)p, 0x00, size ) とかの (void*) は付けなくても問題は無い。
しかし、warning を生じる環境も過去に存在したので脊髄反射的に付ける様になった。
言わば職業病。
ヘ_ヘ
917 :
888:2006/12/12(火) 21:31:34
>>892-895 自動変数は定義した順にスタックへ積まれるが、アドレス低位→高位に積まれるか
アドレス高位→低位に積まれるかは環境依存。
solaris の場合は後者だったと記憶する。
linux では...バッファオーバーランのバグ追った事が無いので知らん。
引数が後ろから積まれるとは限らない。
Win3.1 の PASCAL 型関数の場合、前から積まれてた。
>>909 #include <stdio.h>
#include <stdlib.h>
#define MAX 100000
int main(){
int i; FILE *fp;
fp = fopen("data.txt","w");
srand(time(NULL));
for(i = 0;i < MAX;i++) fprintf(fp,"%d\n",rand());
return 0;}
やる気があるならこれでも使ってくれ
俺はソート全部はやる気にならんな
919 :
787:2006/12/12(火) 21:43:49
>>846>>847 昼間はお世話になりました。おかげで課題も間に合わせることが出来ました。
これから教えてもらった答えをよみなおしてみます。
ありがとうございました
どういたしまして。
がんばってね。
>912
start,endの範囲チェックは自分で足してね
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void f(int *a, int start, int end)
{
int i, j, l, temp, *p;
l = end - start + 1;
p = a + start;
for(i=0; i<l-2; i++) {
for(j=l-1; j>i; j--) {
if(p[j] > p[j-1]) {
temp = p[j];
p[j] = p[j-1];
p[j-1] = temp;
}}}}
int main(void){
int i, start, end,a[20];
srand(time(NULL));
scanf("%d", &start);
scanf("%d", &end);
for(i=0; i<20; i++) a[i] = rand() % 256;
for(i=0; i<20; i++) printf("%3d ", a[i]); putchar('\n');
f(a, start, end);
for(i=0; i<20; i++) printf("%3d ", a[i]); putchar('\n');
return 0;
}
922 :
912:2006/12/12(火) 22:19:36
>>921 ありがとうございました!
参考にさせていただきます。
924 :
889:2006/12/12(火) 23:44:38
皆さん、レスありがとうございます。
if( ppArea[i] )とif( ppArea[i] != NULL)が同義だったのですか、初めて
知りました。
(void *)は付けなくても大丈夫なのですね。分かりました。
あと、
char** allocArea(void)
{
char** ppRet;
int i;
size_t tSize;
tSize = sizeof( char* ) * MAX_LINE;
ppRet = (char**)malloc( tSize );
if( ! ppRet )
return NULL;
memset( (void*)ppRet, 0x00, tSize );
return ppRet;
}
の意味が全く解らない(他のは、意味は解りました。)ので、この関数を
外してコンパイルと実行をしてみたのですが、コンパイルも通って実行も
、まともに出来ました。
しかし、実行して辞書順に並び替わった後に「セグメントエラー」と表示さ
れます。
これを入れると関数が一つ多くなる上に意味が全く解らなくてコメントや
説明が書けないので何とかしたいのですが何か良い方法は無いでしょうか?
例えば、メイン関数の中で1、2行で簡単な表現で表せたり。
ほほう、自動車を軽くしたいからエンジンを外すのか
>>918をありがたく利用させてもらって書いてるけど、
Insertion sortでめげそう
10万個のソートってこんなに時間かかるのね
927 :
デフォルトの名無しさん:2006/12/13(水) 00:01:22
>>924 char** allocArea(void)
{
char** ppRet;
int i;
size_t tSize;
tSize = sizeof( char* ) * MAX_LINE;//割り当てるメモリのサイズを計算
ppRet = (char**)malloc( tSize );//メモリを割り当てる
if( ! ppRet )
return NULL;//割り当てに失敗したらNULLを返す
memset( (void*)ppRet, 0x00, tSize );//割り当てられた領域を0で埋める
return ppRet;//割り当てられた領域のポインタを返す
}
Cあんまり詳しくないけどこういう事?
>>864の課題の記述にミスがありましたので、補正を加えて再貼りします。
[1] 授業単元:計算機演習2
[2] 問題文(含コード&リンク):上記のfor文で数を読み取る部分をscanfの型に直す。
今のままだと、getcharで取り込んだ数が不具合を起こして、入力した数が正常に表示されません。
このプログラムでは一回試行する毎にランダムの数が書き変わってしまいます。
数を言い当ててComplete!が表示されるまで、設定された数が書き変わらないようにしてください。
このプログラムは数字4桁の数当てゲームですが、ランダムに選択される数字は全て異なっていなければなりません。
今の状態だと数字が重なる場合があるのでそこを補正してください。
[3] 環境
[3.1] OS: Linux
[3.2] gcc -o
[3.3] 言語: C
[4] 期限: 2006.12.15
929 :
924:2006/12/13(水) 00:16:00
>>927 レスありがとうございます。
この関数の一つ一つの行の意味が解らないっていうのもありますし、この
関数自体が何をするためにあるのかも解りません。
それと、問題に「6つの関数から構成する」って書いてあったので、これ
以外の関数だけで十分(説明しにくいのですが、本当は必要ないのにこれを
付け加えることによってプログラムとしてより優れた物にするような物)な
のかと思ってしまって。
930 :
デフォルトの名無しさん:2006/12/13(水) 00:23:38
長さ n を入力とし、整列算法を指定して、乱列の整列時間を求める。 Note586 でシャッフル列を発生させる。 Note585 の3つの単純整列算法を選択する。 Note432 で実行時間を計測する。
{
//---- 宣言
//---- 初期化
乱数の初期化
while ( 1 ) {
//---- 入力
算法の選択、長さの入力
switch ( 処理 ) {
case 終了: { return 0; }
case 入力: { 乱列入力; }
case 生成: { 乱列生成; 乱列出力; }
}
//---- 計算
時間計測の開始
整列算法の実行
時間計測の終了
//---- 出力
時間と回数の出力
}
っていう問題ですどう手を着けていいのやら
おねがいします
932 :
デフォルトの名無しさん:2006/12/13(水) 00:31:18
[1] 授業単元:Cプログラミング演習
[2] 問題文:0 から n-1 まで長さ n ; n≧1 のシャッフル列を生成する処理 shuffle(arr, n) を再帰的に定義する。以下のような漸化式で考える。
事前処理 arr[n-1] に n-1 を代入
n=1 のとき そのまま返却
n≧2 のとき 再帰呼出 長さ n-1 のシャッフル列の生成 shuffle(arr, n-1)
事後処理 n 未満の整数乱数 r を発生
位置 r と n-1 の要素を交換
[3] 環境
[3.1] OS:windowsXP
[3.2] コンパイラ名とバージョン: bcc32
[3.3] 言語: Cのみ
[4] 期限: 2006年12月13日12:00まで
よろしくお願いします。
>>236 サンクス
わからんから助けを求めにきたが先行者がいたか・・・
あいつの説明わかりにくいもんなぁ
>>929 簡単に言えばメモリ領域を確保して 0 で埋める作業をしている
これしないと国有地でバーベキューするみたいな感じだぞ(意味不明?)
ちゃんと自分の敷地くださいと言って国有地を分けてもらわないとバーベキューしたときに怒られます
935 :
929:2006/12/13(水) 01:01:29
この関数をどうにか消そうと思ってたのですが、重要そうですし、教えて
下さってるので理解する方向で行こうと思います。
>>934 レスありがとうございます。つまりmallocの奴と同じメモリの動的確保
ってことですか?
でも、それだとしたら、
ファイルを読み込む関数
int readFile(char* sPath,char** ppArea )
{
int iLine = 0;
FILE* fp;
char sBuf[ MAX_LEN + 1 ];
fp = fopen( sPath, "rt" );
while( iLine < MAX_LINE && fgets( sBuf, MAX_LEN, fp ) ) {
ppArea[iLine] = (char*)malloc( strlen( sBuf ) + 1 );
if( ! ppArea[iLine] )
return -1;
strcpy( ppArea[iLine], sBuf );
iLine++;
}
fclose( fp );
return iLine;
}
の
ppArea[iLine] = (char*)malloc( strlen( sBuf ) + 1 );
でメモリの動的確保は行われていると思うのですが…。
936 :
デフォルトの名無しさん:2006/12/13(水) 01:06:37
>>924 >>927 の解説でOK。
もし、allocArea() を使いたくない場合は main() の ppArea を配列で定義するんだな。
memset() も習ってないなら
char** ppArea;
↓
int i;
char* ppArea[MAX_LINE];
for( i = 0; i < MAX_LINE; i++ )
ppArea[i] = 0x00;
これで ppArea の確保と初期化ができたので allocArea() は不要となる。
この場合、 freeArea() 内で free( (void*)ppArea ); を行うとセグメンテーションフォルトが生じるので削除する。
だけどよー、スタックに40Kbyteも積む下品なコード書きたくねぇよー。
>>937 static char *ppArea[MAX_LINE];
でおk。
memset()もいらなくなる。
939 :
デフォルトの名無しさん:2006/12/13(水) 01:18:43
>>913 何個か書いていただいたのですが
コンパイルはできるものの題意を満たすように
実行できません 間違いとか分からないんで
教えてください
システムコール習ってて
// forkして親子に分かれる
// ...
// 親プロセスにて子の終了待ち
while( wait( (int *)0 ) != pid);
ってのがあったんですが
waitの引数は子の状態情報を記憶しておくポインタを与えるもの
と思ってたんですが
(int *)0
↑0へのポインタを渡すってどういうことでしょう?
またwhileでwaitするのって意味あるんですか?
wait関数が、子プロセスが終了するまで待つのなら
いらないと思うのですが
//ポインタを保存する領域を確保
ppRet = (char**)malloc( tSize );
//データを入れる領域を確保してそのポインタを保存
ppArea[iLine] = (char*)malloc( strlen( sBuf ) + 1 );
違い分かる?
>>940 man 2 wait
wait()にNULLを渡した場合は、「終了ステータスは別に要りませんよ」という
意味になり、wait()は単に子プロセスの終了を待つだけの動作をする。
while()でループしているのは、割り込みなどによってwait()が異常終了した
場合などを考慮しているのだろう。
が、今時wait()を使うこと自体が、本当は良いスタイルではないな。
せめてwaitpid()を使うべき。
>>935 熱心だから解説しちゃる。
readFile() での malloc() は読み込んだ一行を保存するための領域だ。
よって (char*) で確保する。
んだども、確保した領域のアドレスは何処に保存する?
allocArea() で確保してる (char**) x 10000 は 10000 行の (char*) を保存する為の領域だ。
つまり
ppArea[0][1][2][3][4]...[9999] のそれぞれに readFile() で確保したアドレスが格納される訳だ。
行数が10000 に満たない場合、ppArea の格納されなかった場所には初期値の NULL が入ってる。
よって、開放する時に
if( ppArea[i] ) free( (void*)ppArea[i] );
ちゅう判定が必要になる訳。
.
説明下手でスマソ。
ま、10000行決めうちの確保だから、わざわざmalloc()使って
動的に確保する必要はないんだけどな。
static配列で十分。
945 :
デフォルトの名無しさん:2006/12/13(水) 01:30:06
[1] 授業単元:データ構造とアルゴリズム
[2] ファイルを読み込み、英字のみか、先頭が英字で二文字目以降が英字または数字である文字列を抽出し、
文字列の長さが長い順に並べ、その文字列の頻度と共に表示するプログラムを作成したい。
但し、文字列の長さが同じものに関しての順序は任意で良い。以下の設問にしたがって回答しなさい。
[3] 環境
[3.1] Windows XP
[3.3] CかC++かJava
[4] 期限: 2006年12月20日20:00まで
[5] その他の制限: Windows の API は使用しないで作って下さい。
946 :
デフォルトの名無しさん:2006/12/13(水) 01:31:16
実行例
入力
#include <stdio.h>
#include <ctype.h>
int main(void){
int c0;
char c1;
b='\0';
while((c0=getchar())!=EOF){
if((!isalnum(c1))&&isalnum(c0)){
printf("\n");
}
if(isalnum(c0)){
printf("%c",c0);
}
c1=c0;
}
return 0;
}
947 :
デフォルトの名無しさん:2006/12/13(水) 01:32:03
出力
getchar:1
include:2
isalnum:3
printf:2
return:1
stdio:1
while:1
ctype:1
char:1
main:1
void:1
EOF:1
int:2
if:2
c1:4
c0:6
h:2
n:1
c:1
>>945-947 よろしくお願いします
>>938 静的領域の 0x00 って保障されてたっけ?
なんか環境依存の様な気が...手元にK&Rも無いので確認でけんけど。
JISならオンラインで読めたはずだが
0で初期化されるのは確かだけど、それがNULLとして有効かは知らない。
むしろ、厳密にはmemsetのほうがまずいような。
>>942 ありがとうございます
(int *)0 でNULLポインタになるんですね
初めて知りました
952 :
935:2006/12/13(水) 01:40:29
>>937-938 レスありがとうございます。
>>941 >>943 レスありがとうございます。
メモリの動的確保って言ってもデータを入れるためのメモリとアドレスを
入れるためのメモリの違いってことだったのですか。
詳しい解説ありがとうございました。
>>948 staticなオブジェクトが0初期化されるのは立派にC言語の仕様であり
保障されているから心配無用。
どーしてもautoにしたいんなら
char *ppArea[MAX_LINE] = { 0 } ;
でよい。
NULL == 0 ではないが、0はNULLという仕様
callocなら領域確保と同時にゼロクリアされる。
JIS のページ探すの面倒くさい。
でも多数決で 0x00 は環境依存じゃないということで...
第一 static で取れば下品なコードじゃなくなるな。
>>952 ちゅことで
>>938 でOK。だけど freeArea() の一行削除は忘れるな。
>>950 ポインタ変数を全て 0 で埋めてそれが NULL にならないと言うことは...NULL って何?
\0でNULLになるんじゃないの?
959 :
952:2006/12/13(水) 02:04:44
>>956 はい、分かりました。
色々とありがとうございました。
>>956 (void *)0はNULLだけど、NULLが全ビット0とは限らない。
961 :
デフォルトの名無しさん:2006/12/13(水) 02:08:12
↑へ?どんな処理系?
>>945 #include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
class symdata
{
public:
string name;
int cnt;
int len;
symdata() { cnt = 0; len = 0; }
symdata(const string& s, int n)
{ name = s; cnt = n; len = s.length(); }
};
bool cmp(symdata *a, symdata *b)
{
return (a->len > b->len);
}
>>962のつづき。
main()
{
string s;
map<string, symdata> table;
vector<symdata*> v;
while (cin >> s) {
if (table.find(s) == table.end()) {
table[s] = symdata(s, 1);
v.push_back(&table[s]);
} else {
++table[s].cnt;
}
}
sort(v.begin(), v.end(), cmp);
for (vector<symdata*>::iterator i = v.begin(); i != v.end(); ++i)
cout << (*i)->name << ":" << (*i)->cnt << endl;
}
3vs3で開始する
966 :
デフォルトの名無しさん:2006/12/13(水) 02:13:40
>>959 教えていて気持ちがいいね。
熱心だしすぐ理解してくれるし。
でも毎回名前の番号が変わるからちょっと認識しにくかった。
まぁどうでもいいけど。
>>956 0をポインタに変換したらNULLに変換されるし
(NULLの内部表現が0でない環境ではコンパイラが変換コードを生成する必要がある)
NULL==0は NULL==(void *)0 と解釈されて1を返すけど
memsetはvoid *sの引数を*(unsigned char *)s=0見たいな感じで埋められるから
そこをchar *の値として参照してもNULLじゃないかもしれない
Randomized quick sortまで実装したけどあってるかどうかの判別がつかない・・・ orz
純粋に規格的な話だと、staticオブジェクトの初期化は大丈夫。
memset()はNGかな。
まぁ、NULLのビット表現が0でない処理系なんて、intが16bitだったり
文字セットがEBCDICだったりするような処理系より全然レアっつか
俺は見たことないし、ぶっちゃけ気にする必要はないけどな。
んな処理系で動かしたら、多分他の部分で問題山積みだぞw
>>967 signed bit の話なら立ってれば補数なので 0 なら立たないよ。
いや、俺が君の話を理解できないだけなんだけど。
まぁ疑問なら試せば良いと思う。
>>971 >>967が言ってるのは全然そういう話ではない。
memset()は「ビット的に」ゼロにしてしまう。
だから、NULLが「ビット的に」ゼロで無い実装では、それを
「ポインタとして」解釈するとnull pointerではないということになる。
一方、ポインタへのゼロの代入は、たとえNULLが「ビット的に」ゼロでない
実装でも、いつでもnull pointerとして扱われる。
そうした実装の場合、staticなpointerオブジェクトに対しては、
null pointerをあらわすビット値が、おそらくCランタイムの
スタートアップコードによって書き込まれるはずだ。
規格に準拠するならば。
↑なるほど、言いたいことは理解した。
けど、不毛だよ。
>>956 で俺が書いた
> ポインタ変数を全て 0 で埋めてそれが NULL にならないと言うことは...NULL って何?
は『ビット的にゼロじゃないNULL』なんか無いだろって事。
君らは『ビット的に非ゼロなNULL』が存在しても良いって前提で話をしてるでしょ。
これは原理主義者と現実主義者の議論でしかないから....
俺はずっと memset() でポインタ初期化を続けるよ、まぁこれも memset() が個別代入より
早いっていう原理主義なんだけどね。
>>973 単に「規格的はどうか」という議論をしているのに「俺様脳内方針」を
ブチ挙げる君も、随分空気読めてない人だな。
勝手にすれば?としか。
ま、実際問題としてはそれでOKであることは否定しないだろ、誰も。
まぁまぁ。お二人とも。
宿題なんだから提出して採点者の前で動けばいいのだ。
じゃだめ?
今はそんな話ではない。黙ってろ。
じゃあ、俺はもう寝る
つうかstaticオブジェクトの初期化についても知らないわ
サイズ固定の配列をわざわざmalloc()で確保するわ
null pointerに関する規格上の定義も知らないわ
しまいには俺は何がなんでもmemset()で初期化するんだとか逆切れか
なんか面白いもん見せてもらったわw
↑お前バカ?
俺が書いたのは話が噛み合わない理由が
・俺は現実的な話をしてる
・俺以外は規格上の話をしてる
事を認めた上で不毛と書いただろ。
噛み合わない話を続けた非は認めるけどな。
なるほど、規格も知らないで
「現実的な話」かwwwww
981 :
979:2006/12/13(水) 03:01:41
983 :
982:2006/12/13(水) 03:48:18
命令実行回数とか数え間違えてるかもしれないからチェックがんばって orz なんかもう眠い
984 :
982:2006/12/13(水) 03:55:50
あとSelection sortは教科書見て書き直さないとバレると思うぞ
連投スマソ
>>985 どうせWikiに各種ソートのプログラム置かなきゃいけないからついでだと思って。
地味に面倒だったけどやり始めたら止まらなくなった。
あとグローバル変数の宣言がおかしいところを発見したけど修正は自分でやってくれ
というかなんでこれコンパイルエラーにならないんだろ・・・
>932
void shuffle(int *arr, int n)
{
int r, t;
arr[n-1] = n - 1;
if(n==1) return;
else {
shuffle(arr, n-1);
r = rand() % n;
t = arr[n-1];
arr[n-1] = arr[r];
arr[r] = t;
}
}
988 :
デフォルトの名無しさん:2006/12/13(水) 07:20:24
[1] 授業単元:Cプログラミング
[2] 問題文:
BCDコードに変換する関数を作成しなさい。
IN :ASCIIコード(NULLストップ)
OUT:BCDコード、桁数
[3] 環境
[3.1] OS: (Windows)
[3.2] bcc
[3.3] C言語
[4] 期限: 無期限
[5] その他の制限:
宜しくお願い致します。
>>988 BCDコードなんだから入力される文字列は0〜9で考えていいんだよな?
あと変換されたBCDコードはどうやって出力すりゃいいんだ?
@printfで出力?(画面に変換結果表示するだけ)
A戻り値をchar*にして返す?(受け取った方は不要になったらfreeする必要がある)
Bそれとも既に確保されてるメモリのポインタを受け取って
そっちに出力?(確保領域が溢れる場合が有る)
とりあえず簡単な@で書いとく。
#define B(c,n) (((c-0x30)>>n)&0x01)
void strtobcd(char* str)
{
printf("before:\n%s\n",str);
int i=0;
printf("after :\n");
while(str[i]){
if(str[i]<'0' || str[i]>'9'){printf("decode error\n");break;}
printf("%d%d%d%d ",B(str[i],3),B(str[i],2),B(str[i],1),B(str[i],0));
i++;
}
}
>>848 上2つのテキスト、内容まったく同じじゃね?
991 :
長岡:2006/12/13(水) 10:16:17
長岡係数を求めるプログラムを早急に作成してください。。
お願いします
>>991 >>1を読んでテンプレ守って書き直してね。
長岡係数って何?
その辺の説明も書こうね。
993 :
長岡:2006/12/13(水) 10:23:54
自分もよくその辺もわからないんでそれも説明していただくとありがたいです。図々しくてすみません。。。
ABのスレできいてるやつか
ここはBASICのスレじゃねえぞ
>>1を読んで理解できないのなら日本語を勉強してくださいとしか…
998 :
長岡:2006/12/13(水) 10:29:06
>>996 ググって出てくるくらいの情報はいいです
書けないんなら黙っていてください
999 :
992:2006/12/13(水) 10:29:13
>>993 長岡係数とやらを理解して説明できるようになったらまたおいで。
プログラムの部分しか請け負わないよ。
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。