1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1

Similar documents
Microsoft Word - report#8.docx

* ライブラリ関数 islower(),toupper() を使ったプログラム 1 /* 2 Program : trupper.c 3 Student-ID : K 4 Author : TOUME, Kouta 5 Comments : Used Library function i

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

プログラミングI第10回

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

Taro-リストⅢ(公開版).jtd

memo

Microsoft Word - no12.doc

memo

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Microsoft Word - no202.docx

Microsoft PowerPoint - 計算機言語 第7回.ppt

1. 入力した文字列を得る 1.1. 関数 scanf() を使う まずは関数 scanf() を使ったプログラムを作ってみましょう 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: #include<stdio.h> #define SIZE 128 main(

Taro-ポインタ変数Ⅰ(公開版).j

PowerPoint プレゼンテーション

Microsoft Word - Cプログラミング演習(12)

Taro-リストⅠ(公開版).jtd

Microsoft Word - no15.docx

memo

Microsoft Word - Cプログラミング演習(7)

Microsoft PowerPoint - kougi9.ppt

02: 変数と標準入出力

Microsoft Word - 3new.doc

PowerPoint プレゼンテーション

memo

program7app.ppt

Microsoft PowerPoint - C_Programming(3).pptx

Taro-スタック(公開版).jtd

Microsoft Word - Cプログラミング演習(11)

Microsoft PowerPoint - CproNt02.ppt [互換モード]

PowerPoint Template

02: 変数と標準入出力

Microsoft Word - Cプログラミング演習(10)

プログラミング基礎

Microsoft Word - no103.docx

02: 変数と標準入出力

PowerPoint プレゼンテーション

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft PowerPoint - prog03.ppt

演算増幅器

Microsoft Word - no206.docx

データ構造

プログラミング基礎

ポインタ変数

第1回 プログラミング演習3 センサーアプリケーション

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

本サンプル問題の著作権は日本商工会議所に帰属します また 本サンプル問題の無断転載 無断営利利用を厳禁します 本サンプル問題の内容や解答等に関するお問 い合わせは 受け付けておりませんので ご了承ください 日商プログラミング検定 STANDARD(C 言語 ) サンプル問題 知識科目 第 1 問 (

Prog1_10th

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

Microsoft PowerPoint pptx

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

Microsoft PowerPoint - 11.pptx

gengo1-8

Microsoft PowerPoint - prog04.ppt

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

< F2D837C E95CF CF68A4A94C5816A2E6A>

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

C 言語講座 Vol 年 5 月 29 日 CISC

Prog1_15th

PowerPoint プレゼンテーション

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

Microsoft PowerPoint - 5Chap15.ppt

PowerPoint Presentation

02: 変数と標準入出力

r07.dvi

Microsoft Word - Cプログラミング演習(8)

Microsoft Word - no204.docx

文字列 2 前回の授業ではコンピュータ内部での文字の取り扱い 文字型の変数 文字型変数への代入方法などを学習した 今回は 前回に引き続き 文字処理を学習する 内容は 標準入出力 ( キーボード ディスプレイ ) での文字処理 文字のファイル処理 文字を取り扱うライブラリ関数である 標準入出力 Lin

Taro-再帰関数Ⅲ(公開版).jtd

ohp07.dvi

kiso2-09.key

PowerPoint プレゼンテーション - 物理学情報処理演習

Microsoft PowerPoint - CproNt11.ppt [互換モード]

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

kiso2-03.key

Java プログラミング Ⅰ 3 回目変 数 今日の講義講義で学ぶ内容 変数とは 変数の使い方 キーボード入力の仕方 変 数 変 数 一時的に値を記憶させておく機能 変数は 型 ( データ型 ) と識別子をもちます 2 型 ( データ型 ) 変数に記憶する値の種類変数の型は 記憶できる値の種類と範囲

PowerPoint プレゼンテーション

gengo1-11

PowerPoint Presentation

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

slide5.pptx

Report#2.docx

プログラミング実習I

Report#2.docx

memo

Microsoft Word - Training10_プリプロセッサ.docx

02: 変数と標準入出力

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

第2回

Report#2.docx

Microsoft Word - no205.docx

02: 変数と標準入出力

Taro-最大値探索法の開発(公開版

4 分岐処理と繰返し処理 ( 教科書 P.32) プログラムの基本的処理は三つある. (1) 順次処理 : 上から下に順番に処理する ぶんきそろ (2) 分岐処理 : 条件が揃えば, 処理する はんぷく (3) 反復処理 : 条件が揃うまで処理を繰り返す 全てのプログラムは (1) から (3) の

Transcription:

1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1 文字が 0( 零 ) 10 進数 : 先頭 1 文字が 0( 零 ) 以外の数字 1.1 プログラム 1.1.1 ソースコード : cardinal.c 01 /* 02 Program : cardinal.c 03 Comment : 基数変換と整列処理 04 */ 05 06 #include <stdio.h> 07 #include <string.h> 08 #define MAX 256 09 10 void conv10(char **x, int *k, int n); 11 void select_sort(int x[], int m[], int n); 12 void print_num(char *x[], int m[], int n); 13 void msg(); 14 15 int main(){ 16 char *dt[50], num[10], buf[max], *p=buf; 17 int n=0, len, i10[50], move[50]; 18 19 puts("-------- Input"); 20 while(gets(num)!= NULL) { 21 len = strlen(num); 22 if(p > buf + MAX - len - 1 ) break; 23 strcpy(p, num); 24 dt[n] = p; 25 p += len + 1; 26 n++; 27 } 28 puts("-------- Result"); 29 conv10(dt, i10, n); 30 select_sort(i10, move, n); 31 print_num(dt, move, n); 32 msg(); 33 34 return(0); 35 } - 1 -

1.1.2 ソースコード : conv10.c 01 /* 02 Program : conv10.c 03 */ 04 05 void conv10(char **x, int *k, int n){ 06 while(n-- > 0){ 07 switch(**x){ 08 case '0' : 09 sscanf(*x + 1, "%o", k); 10 break; 11 case 'x' : 12 case 'X' : 13 sscanf(*x + 1, "%x", k); 14 break; 15 default : 16 sscanf(*x, "%u", k); 17 break; 18 } 19 x++; 20 k++; 21 } 22 } 1.1.3 ソースコード : select_sort.c 01 /* 02 Program : select_sort.c 03 */ 04 05 void select_sort(int x[], int m[], int n){ 06 int i, j, k, w; 07 08 for(i=0; i<n; i++) m[i]=i; 09 for(i=0; i<n-1; i++){ 10 k=i; 11 for(j=i+1; j<n; j++) 12 if(x[k] < x[j]) k=j; 13 w = x[i]; 14 x[i] = x[k]; 15 x[k] = w; 16 w = m[i]; 17 m[i] = m[k]; 18 m[k] = w; 19 } 20 } - 2 -

1.1.4 ソースコード : print_num.c 01 /* 02 Program : print_num.c 03 */ 04 05 void print_num(char *x[], int m[], int n){ 06 int i; 07 08 for(i=0; i<n; i++){ 09 puts( x[m[i]] ); 10 } 11 } 1.1.5 ソースコード : msg.c /* Program : msg.c */ int msg(){ printf("#### Message from C #### By Kouta,TOUME\n"); return(0); } - 3 -

1.2 makefile 1.2.1 ソースコード : makefile # # cardinal.c _ makefile # cardinal : cardinal.o conv10.o select_sort.o print_num.o msg.o cc -o cardinal cardinal.o conv10.o select_sort.o print_num.o msg.o cardinal.o : cardinal.c cc -c cardinal.c conv10.o : conv10.c cc -c conv10.c select_sort.o : select_sort.c cc -c select_sort.c print_num.o : print_num.c cc -c print_num.c msg.o : msg.c cc -c msg.c 1.2.2 実行結果 : makefile new-host:report8 kouta$ make -f makefile cc -c cardinal.c cc -c conv10.c conv10.c: In function conv10 : conv10.c:9: warning: incompatible implicit declaration of built-in function sscanf cc -c select_sort.c cc -c print_num.c cc -c msg.c msg.c: In function msg : msg.c:5: warning: incompatible implicit declaration of built-in function printf cc -o cardinal cardinal.o conv10.o select_sort.o print_num.o msg.o - 4 -

1.3 実行結果 : cardinal.c new-host:report8 kouta$./cardinal -------- Input warning: this program uses gets(), which is unsafe. x21 021 X51 34 -------- Result X51 34 x21 021 #### Message from C #### By Kouta,TOUME 1.4 考察 1.4.1 main 関数 (1) : cardinal.c 20 行目 : while 文 条件文が gets(num)!= NULL なので "control + D" で終了 21 行目 : strlen 関数で num の文字列の長さを調べ 変数 len に格納 23 行目 : strcpy 関数で ポインタ変数 p に配列 num の文字列をコピーする p は buf[max] の先頭アドレスを持っているので buf[max] に文字列をコピーしていることになる 24 行目 : 配列 dt[n] に p のアドレスを格納 26 行目 : 変数 n をインクリメント - 5 -

main 関数では 以下のような処理が行われている - 配列 buf に 入力されたデータを格納 - 配列 dt には 入力されたデータそれぞれの先頭アドレスを格納 よって 22 行目の if 文は 配列 buf にデータが入りきれないとき break する という条件式になると考えられる - 配列 buf の開いている領域は buf + MAX p - 配列 num に格納されている文字列の長さは len + 1 以上のことより buf + MAX p len -1 < 0 となり if 文の条件式は p > buf + MAX len 1 25 行目の代入式について 配列 buf に格納した文字列を上書きさせない為に格納した文字列分 p のアドレスも移動しなければいけない - 配列 num に格納されている文字列の長さは len + 1 よって p += len + 1 となる プログラム 29 32 行目の各関数への引数は後で解説する 1.4.2 conv10 関数 : conv10.c 6 行目 : while 文 n が 0 より小さくなるまで 処理を繰り返す これより 変数 n は 入力された文字列の個数だと考えられる 7 行目 : switch 文 **x の先頭の文字が '0' or 'x' or 'X' or それ以外の場合に処理を行っている **x は入力された文字列を格納していると考えられる main 関数で文字列を格納しているのは 配列 buf であるが ここでは 1 文字取り出したいので 入力されたデータそれぞれの先頭アドレスを格納している 配列 dt が **x となる - 6 -

sscanf 関数について - 書式 : sscanf(*str, format, *temp); format は書式指定文字列 - 意味 : 文字列 *str を format の書式に変換し 配列 temp に格納 8 行目 : **x が '0' のとき つまり8 進数のとき以下のような処理が行われる - 文字列を %o(8 進数 ) に変換し 配列 k に格納 11-12 行目 : **x が 'x', 'X' のとき 16 進数とき以下のような処理を行う - 文字列を %x(16 進数 ) に変換し 配列 k に格納 15 行目 : それ以外の場合 つまり10 進数のときは - 文字列を %u( 符号なし10 進数 ) に変換し 配列 k に格納 8 進数と16 進数の先頭 1 文字は 場合分けの文字なので 1 文字ずらす必要がある よって *x +1 となる 10 進数の場合は 識別する文字がないので *x となる while 文で入力された文字列分 処理が繰り返されるので 以下の値を更新する必要がある - 参照する文字列の先頭アドレス *x - 変換した文字列を格納する配列 k 1つずらせば良いので 19, 20 行目はそれぞれ x++, k++ となる - 7 -

1.4.3 select_sort 関数 : select_sort.c 8 行目 : 配列 m に 0 から n( 文字列の数 ) まで 順番よく数値を格納する 9-12 行目 : 先頭から順に値を確定していく 選択ソートである 降順に並べるので if 文の条件式は x[k] < x[j] となる 13-18 行目 : for 文 if 文の結果に応じて値を入れ替える 配列 x に対応させて 配列 m も同様に入れ替える 1.4.4 print_num 関数 : print_num.c 8 行目 : 0 から n( 入力した文字列の数 ) まで 処理を繰り返す select_sort 関数で 配列 m に 0 から n までの数値を順に格納し 配列 x と対応させて 配列 m もソートしている つまり 配列 m は ソートする前の配列 x の添字を保持していることになる よって 9 行目の puts 関数で x[m[i]] を出力となる 1.4.5 msg 関数 : msg.c ソート終了後にメッセージを出力するための関数 - 8 -

1.4.6 main 関数 (2) : cardinal.c 各関数への引数について (ⅰ) conv10 関数 char **x は 入力した文字列それぞれの先頭アドレスを格納している 配列 dt int *k は 変換後のデータを格納するため空の配列の配列 i10 int n は 入力された文字列の数なので 変数 n (ⅱ) select_sort 関数 int x[] は ソートする値なので変換されたデータが格納されている 配列 i10 int m[] は ソート前の配列 x の添字の役割をするので 空の配列の配列 move int n は 入力された文字列の数なので 変数 n (ⅲ) print_num 関数 char *x[] は 入力されたデータが格納されている 配列 dt int m[] は 配列 x の添字が格納されている配列 move int n は 入力された文字列の数なので 変数 n - 9 -

2. リスト構造プログラムの動作を考察しなさい 2.1 ソースコード : list.c 01 /* 02 Program : list.c 03 Comment : リスト構造 04 */ 05 06 #include <stdio.h> 07 #include <stdlib.h> 08 09 #define FALSE 0 10 #define TRUE!FALSE 11 12 typedef struct Node{ 13 int num; 14 struct Node *next_ptr; 15 }node; 16 17 node *start_ptr = NULL; 18 19 void ins(int idata){ 20 node *p = start_ptr; 21 22 start_ptr = (node *)malloc(sizeof(node)); 23 if (start_ptr == NULL) puts("not enough memory!"), exit(0); 24 25 start_ptr->num = idata; 26 start_ptr->next_ptr = p; 27 } 28 29 int main(){ 30 int idata; 31 node *p; 32 33 puts("enter a sequence of integers:"); 34 while(scanf("%d", &idata) == TRUE) ins(idata); 35 36 puts("in reverse order:"); 37 for(p = start_ptr; p!= NULL; p = p->next_ptr){ 38 printf("address=%p, Data=%3d\n", p, p->num); 39 } 40 puts("/end/"); 41 42 system("pause"); 43 return(0); 44 } - 10 -

2.2 実行結果 : list.c new-host:report8 kouta$./list Enter a sequence of integers: 21 13 56 78 45 In reverse order: Address=0x100160, Data= 45 Address=0x100150, Data= 78 Address=0x100140, Data= 56 Address=0x100130, Data= 13 Address=0x100120, Data= 21 /end/ sh: PAUSE: command not found 2.3 考察 : list.c 12-15 行目 : typedef を使うことで node という構造体の型を宣言する 自分自身と同じタグの構造体をポインタで宣言している 17 行目 : 先頭のポインタに NULL を設定する void 型関数 ins : 領域確保とデータの格納 リストの連結をしている 20 行目 : node 型ポインタ変数 p を宣言 start_ptr のアドレスを格納 malloc 関数について - 書式 : (void *)malloc(size) - 意味 : (void *) のためのメモリを size 分だけ確保する 22 行目 : (node *) のためのメモリを node の大きさ分だけ確保する そのメモリの先頭アドレスを start_ptr に格納 23 行目 : start_ptr が NULL ならば 言い換えるとメモリが確保できなければ Not enough memory! という文を出力する 25 行目 : int 型変数 num に idata を格納 26 行目 : 今までの先頭ポインタを次のポインタ p にする main 関数 : 整数の入力 入力された値を逆に出力 34 行目 : 整数が入力されたら idata に格納し 関数 int に渡す 37 行目 : 次のポインタが NULL になるまで処理を繰り返す - 11 -

- このプログラムを終了するには control + D - malloc 関数を使うことで メモリを無駄なく動的に確保している - 構造体へのポインタを参照するときは -> ( アロー演算子 ) というのを使う - 配列などと違い 要素の追加 削除が比較的容易に行える 3. 感想 今回のプログラミングのレポートは非常に時間がかかりました 最初のソートと基数変換のプログラムの穴埋めは予想以上に難しくて 授業でメモしたものを見ながらやっと解けるという感じでした 図など描きながら 何度もプログラムを見てるとだんだん意味が分かってきて どんな処理をしているのかも分かった気がします リスト構造プログラムの考察は 非常に難しくて 普段はまとめながら理解できるのですが 今回は 何となくは理解できたのですが 当たっているか少し不安です 特に構造体をポインタとして使うところは未だによく理解できていないので 理解したいと思います 4. 参考文献 - C 実践プログラミング第 3 版谷口功 ( 訳 ) 望月康司 ( 監訳 ) Steve Oualline( 著 ) - 初心者のためのポイント学習 C 言語 http://www9.plala.or.jp/sgwr-t/ - 12 -