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

Similar documents
& & a a * * ptr p int a ; int *a ; int a ; int a int *a

02: 変数と標準入出力

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

情報処理Ⅰ演習

Microsoft Word - no202.docx

memo

プログラミング基礎

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

Microsoft PowerPoint - 11.pptx

Microsoft Word - report#8.docx

Prog1_10th

Microsoft Word - no11.docx

Report#2.docx

Microsoft PowerPoint - prog03.ppt

Microsoft Word - 3new.doc

02: 変数と標準入出力

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

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

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

PowerPoint プレゼンテーション

C 言語第 3 回 2 a と b? 関係演算子 a と b の関係 関係演算子 等しい a==b 等しくない a!=b より大きい a>b 以上 a>=b より小さい a<b 以下 a<=b 状態 真偽 値 条件が満たされた場合 TRUE( 真 ) 1(0 以外 ) 条件が満たされなかった場合 F

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

gengo1-11

プログラミング実習I

< F2D837C E95CF CF68A4A94C5816A2E6A>

kiso2-09.key

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

Taro-ファイル処理(公開版).jtd

02: 変数と標準入出力

slide5.pptx

gengo1-12

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

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

PowerPoint プレゼンテーション

Microsoft Word - no15.docx

講習No.9

program7app.ppt

PowerPoint プレゼンテーション

gengo1-12

memo

Microsoft PowerPoint - prog04.ppt

CプログラミングI

02: 変数と標準入出力

02: 変数と標準入出力

PowerPoint プレゼンテーション

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

Prog1_12th

kiso2-03.key

2006年10月5日(木)実施

6 関数 6-1 関数とは少し長いプログラムを作るようになると 同じ処理を何度も行う場面が出てくる そのたびに処 理を書いていたのでは明らかに無駄であるし プログラム全体の見通しも悪くなる そこで登場す るのが 関数 である 関数を使うことを 関数を呼び出す ともいう どのように使うのか 実際に見て

PowerPoint プレゼンテーション

ポインタ変数

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft PowerPoint - lec10.ppt

memo

Microsoft PowerPoint - prog03.ppt

ポインタ変数

第9回 配列(array)型の変数

Microsoft Word - no103.docx

プログラミング演習3 - Cプログラミング -

Microsoft PowerPoint - 5Chap15.ppt

Microsoft PowerPoint - kougi7.ppt

講習No.12

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

Cプログラミング1(再) 第2回

プログラミング演習3 - Cプログラミング -

Prog1_6th

ソフトウェア基礎 Ⅰ Report#2 提出日 : 2009 年 8 月 11 日 所属 : 工学部情報工学科 学籍番号 : K 氏名 : 當銘孔太

ポインタ変数

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

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

DVIOUT

メソッドのまとめ

gengo1-10

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

講習No.10

Microsoft Word - no12.doc

<4D F736F F D2091E63589F182628CBE8CEA8D758DC08E9197BF2E646F6378>

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

Microsoft PowerPoint - 10Com2.ppt

ファイル入出力

PowerPoint Presentation

関数 C 言語は関数の言語 関数とは 関数の定義 : f(x) = x * x ; 使うときは : y = f(x) 戻り値 引数

PowerPoint プレゼンテーション

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

プログラミング実習I

Microsoft PowerPoint - kougi6.ppt

今までの復習 プログラムで最低限必要なもの 入力 ( キーボードから ファイルから ) 出力 ( 画面へ ファイルへ ) 条件分岐 : 条件の成立 不成立により 異なる動作をする 繰り返し : 一定の回数の繰返し 条件成立の間の繰返し 関数の定義 関数の呼び出し C ではそれ以外に ポインタ データ

02: 変数と標準入出力

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

Microsoft PowerPoint ppt

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

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

プログラミング入門1

Microsoft PowerPoint - prog07.ppt

プログラミングI第10回

C言語7

ファイル入出力

講習No.1

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Transcription:

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tolowerを使うため宣言*/ 3. 4. int get_n(char *); 5. void replace(char *,char *); 6. void print_data(char *,char *,int,int); 7. 8. int main(int argc,char **argv,char **str){ 9. int i,n; /* 変数 iを宣言 iはパラメータの番号を表す nはget_n 関数からの値を入れるためのもの */ 10. char dest[10][10]; /*char 型の2 次元配列を宣言 */ 11. str = argv;/*strとargvの先頭アドレスを同じにしている /* 12. printf("argc = %d n",argc); /* コマンドにいくつのパラメータがあるかを表す */ 13. for(i=1,argv++,str++;*argv!=null;i++,argv++,str++){ /*iの初期値を1に argvとstrのアドレスを1つずらし,argvの値がnullでないならiに1をたし argv とstrのアドレスを1つずらす */ 14. n = get_n(*argv);/* 関数 get_nを呼び出し その値を出力する */ 15. replace(*dest,*argv);/* 関数 replaceの呼び出し */ 16. print_data(*dest,*str,n,i); 17. } 18. } 19. 20. int get_n(char *pa){ /* 整数型の関数 get_nの定義 */ 21. int i; 22. for(i=0;*pa!=null;i++,pa++); /*iをに初期化 *paがnullになるまでポインタpaとiにを足す*/ 23. return(i); 24. } 25. 26. void replace(char *dest,char *str){/*void 型の関数 replaceの定義 */ 27. while(*str!=null){ /**strがnullになるまで繰り返す*/ 28. if(islower(*str)!=0) /* 英小文字なら真 (0 以外の数 ) を返す */ 29. *dest = toupper(*str);/* 小文字を大文字に変えて代入 */

30. else if(isupper(*str)!= 0) /* 英大文字なら真を返す */ 31. *dest = tolower(*str); /* 大文字を小文字に変えて代入 */ 32. else 33. *dest = *str; /* 上記に当てはまらないときそのまま代入 */ 34. dest++; /* ポインタdestのアドレスを1つずらす */ 35. str++; /* ポインタstrのアドレスを1つずらす */ 36. } 37. *dest = *str;/*destの値にstrの値( このときはNULLということ ) を代入する */ 38. } 39. void print_data(char *dest,char *str,int n,int i){/*void 型の関数 print_dataの定義 40. printf(" nparameter(%02d) n",i); 41. printf(" 文字数 = %2d 文字 ",n); 42. printf(" t( 変換前 )%s => ( 変換後 )%s n",str,dest); 43. } 実行結果 C: Program Files Microsoft Visual Studio 9.0 VC report6>report0 123 ASDF zxcvb QwErTy argc = 5 parameter(01) 文字数 = 3 文字 ( 変換前 )123 => ( 変換後 )123 parameter(02) 文字数 = 4 文字 ( 変換前 )ASDF => ( 変換後 )asdf parameter(03) 文字数 = 5 文字 ( 変換前 )zxcvb => ( 変換後 )ZXCVB parameter(04) 文字数 = 6 文字 ( 変換前 )QwErTy => ( 変換後 )qwerty 解説 2 行目 : troupper,islower,isupper,tolower を使うために必要なヘッダー 4~6 行目 : main 関数内で関数を使うためのプロトタイプ宣言関数 replace 関数,print_data 関数は void 型 get_n 関数は int 型で宣言している

8 行目 ~main 関数 main 関数にも引数を渡すことができる この役割をコマンドライン引数という 渡せる引数は 引数の総個数 引数の文字列を指すポインタの配列の 2 つである 9 行目 : 変数 i,n の宣言 i はパラメータの番号を表すために n は get_n 関数からの値を入れるためのもの 10 行目 char 型で 2 次元配列 dest を宣言 11 行目 :str と argv のアドレスの先頭アドレスを一致させている 12 行目 :main 関数で引き渡された引数の総個数を表示させている ここで実行結果をみると引数の総個数が 5 となっているのは report0(.exe) が引数の 1 番最初に入っているからである 13 行目 ~17 行目 for 文によるループ文 13 行目 :iの初期値を1に argvとstrのアドレスのアドレスを1つずらし,argvの値がnullでないならiに1をたし argvとstrのアドレスを1つずらす iの初期値を1にargvとstrのアドレスのアドレスを1つずらしているのは report0の変換結果を表示させないためである ちなみにiの初期値を0にアドレスのアドレスをずらさないと下記ような実行結果が追加される parameter(00) 文字数 = 7 文字 ( 変換前 )report0 => ( 変換後 )REPORT0 14 行目 : 変数 nにget_n 関数で処理した値が入る **argvのアドレス(*argv) が *paに引き渡される 15 行目 :replace 関数により変換をする replace 関数の内容はサブルーチンで説明する *destは*destに *argvが*strに引き渡されてる 16 行目 print_data 関数により出力される print_data 関数の内容はサブルーチンで説明する 14 行目で出された値が引き渡されて出力される 20 行目 ~24 行目 : 文字数を求めるget_n 関数スペースにより区切られた物を1つの文字列として文字数として出力される Return(i) によりmain 関数に引き渡している 26 行目 ~36 行目 : replace 関数による変換 27 行目 while 文により **strがnullになるまで繰り返す 28 行目 islowerによる小文字の判定 29 行目 : 小文字だったらtoupperにより大文字に変換する 30 行目 isupperによる大文字の判定 31 行目 tolowerにより大文字を小文字に変換する 32 33 行目その他 ( アルファベット以外 ) の時は そのまま *destに*strを出力する 34 35 行目 :*str *argvのアドレスに1を足す 39 行目 : void 型の関数 print_dataの定義 40 行目 :parameterの番号の表示 41 行目 : 各パラメータの文字数を表示

42 行目 : 変換前の文字列と変化後の文字列の表示 考察 argc 5 argv[0] argv[1] argv[2] argv[3] argv[4] report0.exeのアドレス 123のアドレス ASDFのアドレス zxcvbのアドレス QwErTyのアドレス アドレス 配列 変換前 アドレス 配列 変換後 0x373494 str[0] A 0x12ff00 dest[0] a 0x373495 str[1] S 0x12ff01 dest[1] s 0x373496 str[2] D 0x12ff02 dest[2] d 0x373497 str[3] F 0x12ff03 dest[3] f 0x373499 str[0] z 0x12ff00 dest[0] Z 0x37349a str[1] x 0x12ff01 dest[1] X 0x37349b str[2] c 0x12ff02 dest[2] C 上記の表のように main 関数へ引数が渡されている そして変換前のアドレス 配列 値 変換後のアドレス 配列 値は図のようになってい る 文字列を反転して表示するプログラムも作成せよ ( 例 "abcd" => "dcba") 1. #include <stdio.h> 2. 3. void reverse(char *,char *,char *);/*reverse 関数のプロトタイプ宣言 */ 4. 5. int main(int argc,char **argv){ 6. int i,; 7. char dest[10][10]; 8. for(i=1,argv++;*argv!=null;i++,argv++){ 9. printf("[parameter][%02d]",i); 10. reverse(*dest,*argv,*argv); 11. }

12. } 13. 14. void reverse(char *dest,char *argv,char *str){ 15. int i,j; 16. if(*argv == NULL) 17. return; 18. else 19. for(i =0;str[i]!= NULL;i++)/* 配列 str[] について null 文字が現れるまで */ 20. argv[i] = str[i]; /* 配列 argv[] に配列 str[] の内容をコピー */ 21. for(j = i;i >=0;i--) /* 配列 str[] の [ 要素数 ] 回ループ */ 22. dest[i] = argv[j-i-1]; /* argv[] の内容を逆から dest[] にコピー */ 23. dest[j+1] = NULL; /* 配列 dest[] の一番うしろに null 文字を追加 */ 24. printf("[ 反転前 ] %s -> [ 反転後 ] %s n",str,dest); 25. } 実行結果 C: Program Files Microsoft Visual Studio 9.0 VC report6>report2 what are you doing now. [parameter][01][ 反転前 ] what -> [ 反転後 ] tahw [parameter][02][ 反転前 ] are -> [ 反転後 ] era [parameter][03][ 反転前 ] you -> [ 反転後 ] uoy [parameter][04][ 反転前 ] doing -> [ 反転後 ] gniod [parameter][05][ 反転前 ] now? -> [ 反転後 ]?won 解説 3 行目 :Reverse 関数のプロトタイプ宣言 6 行目 : 変数 i の宣言 I はパラメータの番号を表示させるのに使う 14 行目 ~24 行目 :void 型の reverse 関数 15 行目 : 変数 i とjの宣言 16 行目 :*str[0] の値が NULL だったら何もしない 19 20 行目 : それ以外だった場合 配列 str を NULL が表れるまで配列 argv にコピー 21 行目 : 配列 str の要素数分だけ繰り返す 22 行目 : argv[] の内容を逆から dest[] にコピー 23 行目 : 配列 dest[] の一番うしろに null 文字を追加 24 行目 : 反転前と反転後を表示させる 考察

argv[2] areのアドレス argv[1][1] h argv[3] youのアドレス argv[1][2] a argv[4] doingのアドレス argv[1][3] t 変換前 変換後 argv[1][0] w i=1 dest[0] t argv[1][1] h dest[1] a argv[1][2] a dest[2] h argv[1][3] t dest[3] w argv[1][4] NULL dest[4] NULL : : argv[5][0] n i=5 dest[0]? argv[5][1] o dest[1] w argv[5][2] w dest[2] o argv[5][3]? dest[3] n argv[5][4] NULL dest[4] NULL 図のように変換されていると思われる エラー報告 コンパイルしたときに report2.c(22) : warning C4047: '==' : 間接参照のレベルが 'int' と 'void *' で異なっています report2.c(25) : warning C4047: '!=' : 間接参照のレベルが 'int' と 'void *' で異なっています report2.c(29) : warning C4047: '=' : 間接参照のレベルが 'char' と 'void *' で異なっています という風にでるがこの warning を直せなかった 二重ポインタで宣言してないのに二重配列の型を使ってしまうと下記のように怒られる report2.c(31) : error C2109: 配列または ポインタでない変数に添字が使われました 感想 この課題をやって自分がポインタを理解していないことを痛感しました 課題を通してポインタの理解が深まったと思います 参考資料 c 実践プログラミング 新 The UNIX Super Text( 上 ) 初心者のためのポイント学習 C 言語 http://www9.plala.or.jp/sgwr-t/index.html Makefile の書き方 http://www.c.csce.kyushu-u.ac.jp/~seiichirou/wiki/index.php?makefile%a4%ce%bd%f1%a 4%AD%CA%FD