http://www.phys.ynu.ac.jp/labs/cosmic/shibata/jisshu/ 物理情報処理基礎実習II 第10回 文字と配列 ~char型変数・文字列~ 柴田 [email protected] (原 [email protected]) 石川 [email protected] §課題8 方程式の根解答例 aplsrvky01% cat exercise8.c #include <stdio.h> #include <math.h> #define f(x) ((x)*(x)-sin((x))) main() { double x1,x2,eps; double f1,fm,xm; int i,n=10000; printf("input xmin,xmax(xmin<xmax),eps="); scanf("%lf %lf %lf",&x1,&x2,&eps); for(i=0;i<n;i++){ xm=(x1+x2)/2; f1=f(x1); /* f1=x1*x1-sin(x1); */ fm=f(xm); /* fm=xm*xm-sin(xm); */ if(fabs(f1)<=eps||fabs(fm)<=eps)break; if(f1*fm<0.0){ x2=xm; } if(f1*fm>0.0){ x1=xm; } } printf("%d)x1,f1:x2,f2=%15.10lf,%15.10lf: %15.10lf,%15.10lf\n",i,x1,f1,xm,fm); } aplsrvky01% cc exercise8.c –lm -o exercise8;./exercise8 input xmin,xmax(xmin<xmax),eps=0.1 1.0 1.0e-6 16)x1,f1:x2,f2= 0.8767196655, -0.0000072951: 0.8767265320, 0.0000003526 input xmin,xmax(xmin<xmax),eps=0.5 2.0 1.0e-6 19)x1,f1:x2,f2= 0.8767251968, -0.0000011344: 0.8767266273, 0.0000004588 aplsrvky01% exit ※16回,19回で収束している。 ※解はそれぞれ 0.8767196655<x< 0.8767265320 0.8767251968 <x< 0.8767266273 にある。 §課題9 フローチャート (大文字・小文字変換) 1文字入力 C EOF ? No Yes 大文字 ? Yes No C=C+32 Cを出力 EXIT 小文字 ? Yes C=C-32 No §char型変数 “文字”は、 アスキーコードの0~127に対応している。 整数型のメモリサイズは4バイト(注)、 しかし、英数字1文字を表すには1バイトで十分。 char型変数 変数 に1バイトの領域を割り当てる。 宣言方法 char 変数名; ※1バイト(byte)=8ビット(bit) 2進数なので、 28 =256通りの表現が可能。 §文字列(char型配列) 文字列 char型の変数を多数ならべたもの。 配列 メモリ空間で連続な変数の並び char型変数の配列なら、char型配列、と呼ぶ。 宣言方法と初期値 配列の型 配列名[ 要素数 ]= { 初期値の並び } ; ※初期値を書く場合、要素数は省略可能 ex.) char str[8] = {‘Y’,’o’,’k’,’o’,’h’,’a’,’m’,’a’}; ※str[0] = ‘Y’ 等と書くのと同じことになる。 §文字列 -例- -I 配列の要素を出力 ※ cf. ex313.c。for文や関数putcharを使用。 #include <stdio.h> 2. main() 3. { 4. char str[8] = {‘Y’,’o’,’k’,’o’,’h’,’a’,’m’,’a’}; 5. int i; 6. for( i=0 ; i<8 ; i++ ){ ※iが0から7のとき次を実行 7. putchar(str[i]); ※1文字を出力する関数 8. } 9. putchar(‘\n’); ※最後に改行を出力 10. } 1. 実行結果 Yokohama §文字と文字列 表記の仕方 文字(1文字)は、‘ ’(シングルクォート)で囲む。 文字列は、“ ”(ダブルクォート)で囲む。 配列の初期値は次のようにも書ける。 char str[9] = “Yokohama”; ※8文字を表せばいいのに、 何故配列要素数を9にしたか? 文字列の約束ごと 文字列の終わりには、自動的に、 “終わり”を意味するNULL(=‘\0’)が付加される。 ※上記例でstrの要素数が9である理由! §文字列 -例- -II 先ほどの例を文字列を用いて書きかえる。 →非常に簡単に! 1. 2. 3. 4. 5. 6. #include <stdio.h> main() { char str[9] = “Yokohama” ; printf(“%s\n”, str); ※%sは文字列出力の書式 } 実行結果 Yokohama §文字列入力関数 C言語には様々な入力関数が用意されており、 目的に応じて使い分ける。 scanf scanf(“%s”,格納文字配列) 格納文字配列はchar型配列で宣言されたもの。 scanfの今までの使い方と違い、“&”を付けない。 ※この理由はポインタの章で fgets 指定長さ, stdin) 標準入力(stdin = standard input)から、 指定長さ未満の文字列を取り込み、 格納文字配列に格納する。 ※改行コードも取込むので注意すること。 使う前に、次の様に格納文字配列を宣言する。 char 格納文字配列名[BUFFERSIZE] fgets(格納文字配列, §文字列入出力関数 -例- fgets cf. 教科書p.137 ex324.c 1. 2. 3. 4. 5. 6. 7. 8. #include <stdio.h> #define BUFFERSIZE 1024 main() { char buffer[BUFFERSIZE]; fgets(buffer, BUFFERSIZE, stdin);※1行入力 printf(“input string : %s\n”, buffer); ※\nは省略可(文字列の最後に改行があ る) } §文字列操作関数 -I文字列代入 strcpy (strings copy) 代入元文字配列) 代入元文字配列から代入先文字配列へ 文字配列の内容を複製する。 ※このとき、2つの配列の大きさに注意すること。 ※直接 = を用いた代入はできない! strcpy(代入先文字配列, 文字列の長さ strlen (strings length) strlen(文字配列) 文字配列の長さを返す。 ※文字配列の最後にあるNULLは含まない。 §文字列操作関数 -II文字列の比較 strcmp (strings compare) 比較文字配列2) 比較文字配列を比較して以下の様な値を返す。 strcmp(比較文字配列1, 0 : 一致 正数 :比較文字配列1 > 比較文字配列2 負数 :比較文字配列1 < 比較文字配列2 ※1文字ごとにアスキーコードを比較する。 ※一致以外には使わない方が無難! strcpy、strlen、strcmpを使うときには、以下が 必要。 #include <string.h> §文字列操作関数 -例- とftp ftpサーバから以下のようにして、 password.cというファイルをダウンロードせよ。 ファイルをダウンロードする方法 aplsrvky01% ncftp ftp.phys.ynu.ac.jp ※サーバーに接続 接続に成功すると ncftp> というプロンプトに変わる。 ncftp> cd pub/jisshu/primer ※目的のdirectoryに移る ncftp> ls ※ファイル名一覧表示 ncftp> get password.c ※ダウンロード ncftp> quit ※終了 §password.c -I1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. #include <stdio.h> #include <string.h> main() { char str1[80]; ※最大79文字を格納する(+NULL文字) char str2[80]; int n1,n2,i,match=0; system(“stty -echo”); ※echo off while(match==0){ printf("Password:"); fgets(str1,80,stdin); ※文字列入力 n1=strlen(str1); ※文字列str1の長さ putchar(10); ※改行 printf("Enter again:"); fgets(str2,80,stdin); n2=strlen(str2); §password.c -II19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. putchar(10); if(n2<n1){ printf("2nd input is shorter than 1st one, n1=%d, n2=%d\n",n1,n2); }else if(n2>n1){ printf("2nd input is longer than 1st one, n1=%d, n2=%d\n",n1,n2); }else{ i=strcmp(str1,str2); ※文字列比較 if(i==0){ printf("matching ok.\n"); match=1; }else{ printf("unmatching, do it again.\n"); } } } system(“stty echo”); } ※echo on §文字列操作関数 -例- 解説 password.c の内容 パスワードを二度入力して比較し、 入力ミスがあると再度入力を促す。※string.hを使用 system(“stty –echo”) キー入力の内容を画面に再表示するのを抑制するために 使われている(入力文字が画面に表示されなくなる)。 fgetsを用いて、80の大きさを持つ 文字配列str1とstr2に入力文字列を格納する。 strlenで入力文字列の長さを調べ、不一致なら長さを表示。 長さが一致している場合、strcmpで文字列を比較。 while文で、2つの入力文字列が一致するまで繰り返す。 matchという変数は、一致が得られていないとき0(初期値)、 一致が得られたら1となるように使われている。 ※フラグと呼ぶ使い方、フラグを立てる、等と言う。 最後に入力文字表示をするように戻して終了。(エコーバック) §課題10 今回の内容に関する課題 はなし。ただし、試験問題の問い4をレ ポート課題とする。 ある実験でn個の有効数字7桁の実数値データを得た。そのデータを 順次入力したのち、平均値、最大値、最小値を求め表示するプログラム を作成せよ。ただし、実数値は0から10の間の値をとるものとし、倍精度 で扱うこと。nは未定で、ユーザーが指定した個数とする。その指定の しかたは工夫せよ。簡単なフローチャートも書け。
© Copyright 2024 ExpyDoc