Presentation is loading. Please wait.

Presentation is loading. Please wait.

C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1.

Similar presentations


Presentation on theme: "C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1."— Presentation transcript:

1 C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1

2 文字列の基本 2

3 2 進数 8 進数 10 進数 16 進数 0000 1111 10222 11333 100444 101555 110666 111777 10001088 10011199 10101210a 10111311b 11001412c 11011513d 11101614e 11111715f 10000201610 3 2 の桁へ 桁上がり 4 の桁へ 桁上がり 8 の桁へ 桁上がり 16 の桁へ 桁上がり 8 の桁へ 桁上がり 10 の桁へ 桁上がり 16 の桁へ 桁上がり

4 2 進数 8 進数 10 進数 16 進数 11111000370248f8 11111001371249f9 11111010372250fa 11111011373251fb 11111100374252fc 11111101375253fd 11111110376254fe 11111111377255ff 100000000400256100 100000001401257101 100000010402258102 100000011403259103 100000100404260104 100000101405261105 100000110406262106 100000111407263107 100001000400264108 4 256 の桁へ 桁上がり 256 の桁へ 桁上がり

5 8bit 整数の 10 進表現 2進2進 0000000100100011010001010110011110001001101010111100110111101111 16 進 0123456789ABCDEF 0000 0 0123456789101112131415 0001 1 16171819202122232425262728293031 0010 2 32333435363738394041424344454647 0011 3 48495051525354555657585960616263 0100 4 64656667686970717273747576777879 0101 5 80818283848586878889909192939495 0110 6 96979899100101102103104105106107108109110111 0111 7 112113114115116117118119120121122123124125126127 1000 8 128129130131132133134135136137138139140141142143 1001 9 144145146147148149150151152153154155156157158159 1010 A 160161162163164165166167168169170171172173174175 1011 B 176177178179180181182183184185186187188189190191 1100 C 192193194195196197198199200201202203204205206207 1101 D 208209210211212213214215216217218219220221222223 1110 E 224225226227228229230231232233234235236237238239 1111 F 240241242243244245246247248249250251252253254255 下位 4 ビット 5 2 進数と 10 進数は桁数の対応で収まりが悪い

6 8bit 整数の 2 進表現 2進2進 0000000100100011010001010110011110001001101010111100110111101111 16 進 0123456789ABCDEF 0000 0 0000 00010000 00100000 00110000 01000000 01010000 01100000 01110000 10000000 10010000 10100000 10110000 11000000 11010000 11100000 1111 0001 1 0001 00000001 0001 00100001 00110001 01000001 01010001 01100001 01110001 10000001 10010001 10100001 10110001 11000001 11010001 11100001 1111 0010 2 0010 00000010 00010010 0010 00110010 01000010 01010010 01100010 01110010 10000010 10010010 10100010 10110010 11000010 11010010 11100010 1111 0011 3 0011 00000011 00010011 00100011 0011 01000011 01010011 01100011 01110011 10000011 10010011 10100011 10110011 11000011 11010011 11100011 1111 0100 4 0100 00000100 00010100 00100100 00110100 0100 01010100 01100100 01110100 10000100 10010100 10100100 10110100 11000100 11010100 11100100 1111 0101 5 0101 00000101 00010101 00100101 00110101 01000101 0101 01100101 01110101 10000101 10010101 10100101 10110101 11000101 11010101 11100101 1111 0110 6 0110 00000110 00010110 00100110 00110110 01000110 01010110 0110 01110110 10000110 10010110 10100110 10110110 11000110 11010110 11100110 1111 0111 7 0111 00000111 00010111 00100111 00110111 01000111 01010111 01100111 0111 10000111 10010111 10100111 10110111 11000111 11010111 11100111 1111 1000 8 1000 00001000 00011000 00101000 00111000 01001000 01011000 01101000 01111000 1000 10011000 10101000 10111000 11001000 11011000 11101000 1111 1001 9 1001 00001001 00011001 00101001 00111001 01001001 01011001 01101001 01111001 10001001 1001 10101001 10111001 11001001 11011001 11101001 1111 1010 A 1010 00001010 00011010 00101010 00111010 01001010 01011010 01101010 01111010 10001010 10011010 1010 10111010 11001010 11011010 11101010 1111 1011 B 1011 00001011 00011011 00101011 00111011 01001011 01011011 01101011 01111011 10001011 10011011 10101011 1011 11001011 11011011 11101011 1111 1100 C 1100 00001100 00011100 00101100 00111100 01001100 01011100 01101100 01111100 10001100 10011100 10101100 10111100 1100 11011100 11101100 1111 1101 D 1101 00001101 00011101 00101101 00111101 01001101 01011101 01101101 01111101 10001101 10011101 10101101 10111101 11001101 1101 11101101 1111 1110 E 1110 00001110 00011110 00101110 00111110 01001110 01011110 01101110 01111110 10001110 10011110 10101110 10111110 11001110 11011110 1110 1111 1111 F 1111 00001111 00011111 00101111 00111111 01001111 01011111 01101111 01111111 10001111 10011111 10101111 10111111 11001111 11011111 11101111 下位 4 ビット 6 2 進数は桁が多過ぎて直感的に分かり難い

7 8bit 整数 16 進表現 2進2進 0000000100100011010001010110011110001001101010111100110111101111 16 進 0123456789ABCDEF 0000 0 000102030405060708090a0b0c0d0e0f 0001 1 101112131415161718191a1b1c1d1e1f 0010 2 202122232425262728292a2b2c2d2e2f 0011 3 303132333435363738393a3b3c3d3e3f 0100 4 404142434445464748494a4b4c4d4e4f 0101 5 505152535455565758595a5b5c5d5e5f 0110 6 606162636465666768696a6b6c6d6e6f 0111 7 707172737475767778797a7b7c7d7e7f 1000 8 808182838485868788898a8b8c8d8e8f 1001 9 909192939495969798999a9b9c9d9e9f 1010 A a0a1a2a3a4a5a6a7a8a9aaabacadaeaf 1011 B b0b1b2b3b4b5b6b7b8b9babbbcbdbebf 1100 C c0c1c2c3c4c5c6c7c8c9cacbcccdcecf 1101 D d0d1d2d3d4d5d6d7d8d9dadbdcdddedf 1110 E e0e1e2e3e4e5e6e7e8e9eaebecedeeef 1111 F f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 下位 4 ビット 7 2 進数と 16 進数は相性が良い。 2 進数 4 桁が 16 進数 1 桁に対応するので直感的に分かり易い

8 ASCII 文字コード表 16 進 0123456789ABCDEF 0NULSOHSTXETXEOTENQACKBELBSHTLFVTFFCRSOSI 1DLEDC1DC2DC3DC4NAKSYNETBCANEMSUBESCFSGSRSUS 2SP!"#$%&'()*+,-./ 30123456789:;<=>? 4@ABCDEFGHIJKLMNO 5PQRSTUVWXYZ[\]^_ 6`abcdefghijklmno 7pqrstuvwxyz{|}~DEL 8 9 A B C D E F 下位 4 ビット 赤字は制御コード 教科書 p.51., 第 2 週資料 p.67. http://ja.wikipedia.org/wiki/ASCII 8

9 標準ヘッダ // 文字コードの調査 (c が該当する文字なら真を返す ) int islower(int c); // 小文字 int isupper(int c); // 大文字 int isdigit(int c); //10 進数 ( 数字 ) int isxdigit(int c);//16 進数 int isalpha(int c); // 英字 (isupper(c)||islower(c)) int isalnum(int c); // 英数字 (isalpha(c)||isdigit(c)) int iscntrl(int c); // 制御文字 (0x00 ~ 0x1f, 0x7f) int isspace(int c); // 空白文字 (' ','\f','\n','\r','\t','\v') int isprint(int c); // 印字可能文字 (0x20 ~ 0x7e) int isgraph(int c); // 印字可能文字 ( スペースを除く ) isprint(c)&&!isspace(c) int ispunct(int c); // 印字可能文字 ( スペース、英数字を除 く )isgraph(c)&&!isalnum(c) // 文字コードの変換 int tolower(int c); //c を小文字に変換 int toupper(int c); //c を大文字に変換 9 [1] pp.303. JM: isalpha (3)isalpha touppertoupper (3) 講義資料の ctype_test.c, ctype_test.xlsx も参照

10 char 型変数と文字コード char, unsigned char 型 半角文字の文字コードを1つ つまり 1 バイト (=8 ビット ) を格納出来るサイ ズ char: -128 ~ 127 unsigned char: 0 ~ 255 10 教科書 pp.44, 96-99., 第 2 週資料 pp.54-63. c 0110 1000 変数の実体は N バイト (8N ビット ) のメモリ つまり内部的には 2 進数が入っている 16 進数リテラルによる初期化 char c = 0x68; // =104='h' 文字コードに対応する文字を表示 printf("%c\n", 104); // "%c" に文字コードを与えると対応する文字が表示される

11 char 型変数と文字コード 以下の変数宣言と初期化は全く同じ結果 11 教科書 pp.44, 96-99., 第 2 週資料 pp.54-63. c 0110 1000 どの方法で初期化しようと結局 char 型 (1 バイト ) の変数 c を 0b01101000 で初期化している 文字コードを代入したい場合 文字定数リテラルで書くと 数値リテラルで書くよりも 意味が分かり易くなる 結果は同じでも読んだ時 分かり易いのはどれだろう? 必要であれば 読んだ人が分かり易いよう コメントで情報を補うと良い 文字定数リテラルによる初期化 char c = 'h'; // 0x68 10 進数リテラルによる初期化 char c = 104; // 'h' 16 進数リテラルによる初期化 char c = 0x68; // 'h' c 104 c 0x68 c 'h'

12 char 型配列と文字列 以下の変数宣言と初期化は全く同じ結果 12 文字定数リテラルによる初期化 char s[] = {'h', 'e', 'l', 'l', 'o', '\0'}; 文字列定数リテラルによる初期化 char s[] = "hello"; 教科書 pp.44, 96-99., 第 2 週資料 pp.54-63. 10 進数リテラルによる初期化 char s[] = {104, 101, 108, 108, 111, 0}; 16 進数リテラルによる初期化 char s[] = {0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00}; s[0] 'h' s[1] 'e' s[2] 'l' s[3] 'l' s[4] 'o' s[5] '\0' 文字列は配列に格納した 一連の文字コード 終端には 0 を格納する どれで書いても良いが 普通は面倒だから 文字列の初期化は 文字列定数リテラルを 用いる

13 char 型配列と文字列 文字列の表示 13 文字列定数リテラルによる初期化 char s[] = "hello"; 教科書 pp.44, 96-99., 第 2 週資料 pp.54-63. s[0] 'h' s[1] 'e' s[2] 'l' s[3] 'l' s[4] 'o' s[5] '\0' 文字列の表示 printf("%s\n", s); // "%s" に与えたアドレス以降 '\0' が現れるまで // メモリに格納された文字コードに対応する文字が表示される

14 関数の引数とよく使われる名前 p, ptr, pointer : ポインタ c, ch, chr, character : 文字 s, str, string : 文字列 s, src, source : 発信元 d, dst, destination : 送信先 t, txt, text : テキスト l, len, length : 長さ w, wid, width : 幅 h, hei, height : 高さ n, num, number : ( 個 ) 数 s, size : サイズ b, buf, buff, buffer : バッファ i, idx, index : 添え字 s, stat, status : 状態 14

15 標準ヘッダ 15

16 strlen 関数 size_t strlen(const char *s); 文字列 s の長さを返す 引数 : s: 長さを調べる文字列 戻り値 文字列 s の長さを返す 16 教科書 p.312., [1] pp.313-315. JM: strlen (3)strlen

17 strcpy 関数 char *strcpy(char *dst, const char *src); '\0' を含めて src を dst へコピーする 引数 : dst: コピー先のアドレス src: コピー元の文字列 戻り値 dst を返す dst が十分な大きさでないとバッファオーバーフローを引き起 こすので注意 17 教科書 p.308., [1] pp.313-315. JM: strcpy (3)strcpy

18 strncpy 関数 char *strncpy(char *dst, const char *src, size_t n); src から最大 n 文字 dst へコピーする 引数 : dst: コピー先のアドレス src: コピー元の文字列 n: コピーする最大文字数 戻り値 dst を返す src が n 文字より短い場合は、残りの dst の末尾に '\0' を詰めて、合計 n バイト書き込む 18 教科書 p.308., [1] pp.313-315. JM: strcpy (3)strcpy

19 strcat 関数 char *strcat(char *dst, const char *src); 文字列 dst の末尾に文字列 src を連結する 引数 : dst: 連結先の文字列 src: 連結元の文字列 戻り値 dst を返す dst が十分な大きさでないとバッファオーバーフローを引き起 こすので注意 19 教科書 p.309., [1] pp.313-315. JM: strcat (3)strcat

20 strncat 関数 char *strncat(char *dst, const char *src, size_t n); 文字列 dst の末尾に文字列 src を最大 n 文字連結する 引数 : dst: 連結先の文字列 src: 連結元の文字列 n: 連結する最大文字数 戻り値 dst を返す dst は strlen(dst)+min(strlen(stc),n)+1 の大きさがな ければバッファオーバーフローが発生する 20 教科書 p.309., [1] pp.313-315. JM: strcat (3)strcat

21 strcmp 関数 char *strcmp(const char *s1, const char *s2); 文字列 s1 と s2 を比較する 引数 : s1: 比較する文字列 1 s2: 比較する文字列 2 戻り値 s1 が s2 に比べて小さければマイナスの値を返す s1 と s2 が等しければ 0 を返す s1 が s2 に比べて大きければプラスの値を返す 21 教科書 p.309., [1] pp.313-315. JM: strcmp (3)strcmp

22 strncmp 関数 char *strncmp(const char *s1, const char *s2, size_t n); 文字列 s1 と s2 の先頭 n 文字を比較する 引数 : s1: 比較する文字列 1 s2: 比較する文字列 2 n: 比較する最大文字数 戻り値 strcmp に同じ 22 教科書 p.310., [1] pp.313-315. JM: strcmp (3)strcmp

23 strchr 関数 char *strchr(const char *s, char c); 文字列 s のなかで最初に現れる c を見つける 引数 : s: 検索する文字列 c: 検索する文字 戻り値 最初に見つかった c へのポインタを返す 見つからなかった場合は NULL を返す 23 教科書 p.312., [1] pp.313-315. JM: strchr (3)strchr

24 strrchr 関数 char *strrchr(const char *s, char c); 文字列 s のなかで最後に現れる c を見つける 引数 : s: 検索する文字列 c: 検索する文字 戻り値 最後に見つかった c へのポインタを返す 見つからなかった場合は NULL を返す 24 教科書 p.313., [1] pp.313-315. JM: strchr (3)strchr

25 strspn 関数 int strspn(const char *s, const char *t); 文字列 s の先頭から、 t に含まれる文字だけからなる文字列の長 さを返す 引数 : s: 検索する文字列 t: 検索する文字の集合 戻り値 t に含まれる文字からなる接頭子 (prefix) の長さを返す 25 [1] pp.313-315. JM: strspn (3)strspn

26 strcspn 関数 int strcspn(const char *s, const char *t); 文字列 s の先頭から、 t に含まれない文字だけからなる文字列の 長さを返す 引数 : s: 検索する文字列 t: 検索する文字の補集合 戻り値 t に含まれない文字からなる接頭子 (prefix) の長さを返す 26 [1] pp.313-315. JM: strspn (3)strspn

27 strpbrk 関数 char *strpbrk(const char *s, const char *t); 文字列 s のなかで、 t に含まれる文字が最初に出てくる位置を見 つける 引数 : s: 検索する文字列 t: 検索する文字の集合 戻り値 t に含まれる文字が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す 27 [1] pp.313-315. JM: strpbrk (3)strpbrk

28 strstr 関数 char *strstr(const char *s, const char *t); 文字列 s のなかで、文字列 t が最初に現れる位置を見つける 引数 : s: 検索する文字列 t: 検索する文字列 戻り値 文字列 t が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す 28 教科書 p.314., [1] pp.313-315. JM: strstr (3)strstr

29 strtok 関数 char *strtok(char *s, const char *t); 文字列 s のなかから、 t に含まれる文字で区切られるトークンを 見つける 引数 : s: 検索する文字列 t: トークンを区切る文字の集合 戻り値 トークンへのポインタを返す 2 つ目以降のトークンは s を NULL にして呼ぶことで順次切り 出される トークンがなくなったらは NULL を返す s は区切り文字の位置が終端文字 '\0' で破壊される 29 [1] pp.313-315. JM: strtok (3)strtok

30 memset 関数 void *memset(void *s, int c, size_t n); s の先頭から n バイトを c で埋め s を返す 引数 : s: データで埋める先頭アドレス c: メモリを埋める 1 バイトのデータ n: データ c を埋めるバイト数 戻り値 s を返す 要 string.h 30 [1] pp.313-315. JM: memset (3)memset

31 memcpy 関数 void *memcpy(void *dst, const void *src, size_t n); dst に src の内容を n バイトコピーする dst と src は領域が重なっていてはならない。重なっている場合 は memmove を用いる 引数 : dst: データのコピー先 src: データのコピー元 n: コピーするバイト数 戻り値 dst を返す 要 string.h 31 [1] pp.313-315. JM: memcpy (3)memcpy

32 memmove 関数 void *memmove(void *dst, const void *src, size_t n); dst と src は領域が重なっていても良い点を除けば、 memcpy と同 じ 引数 : dst: データのコピー先 src: データのコピー元 n: コピーするバイト数 戻り値 dst を返す 要 string.h 32 JM: memmove (3)memmove [1] pp.313-315.

33 memcmp 関数 int memcmp(const void *s1, const void *s2, size_t n); s1 と s2 の最初の n バイトを比較する 引数 : s1: 比較するメモリ 1 s2: 比較するメモリ 2 n: 比較するバイト数 戻り値 strcmp に同じ 要 string.h 33 JM: memcmp (3)memcmp [1] pp.313-315.

34 memchr 関数 void *memchr(const void *s, int c, size_t n); s の中で c が最初に現れる位置を見つける 引数 : s: 検索するメモリ c: 検索する値 n: 検索する範囲のバイト数 戻り値 c が最初に見つかった位置へのポインタを返す 見つからなかった場合は NULL を返す要 string.h 34 JM: memchr (3)memchr [1] pp.313-315.

35 標準ヘッダ // 文字列を数値に変換 double atof(const char *s); // 文字列を double 型の数値に変換 int atoi(const char *s); // 文字列を int 型の数値に変換 long atol(const char *s); // 文字列を long 型の数値に変換 double strtod(const char *s, char **endp); long strtol(const char *s, char **endp, int base); unsigned long strtoul(const char *s, char **endp, int base); // 文字列を double, long, unsigned long 型の数値に変換する // endp が NULL でない場合、 // *endp は変換に用いた最後の文字の次の文字へのポインタとなる // base は変換元の文字列の基数 // base が 0 の場合、文字列先頭の 0 や 0x を解釈し // 8 進数や 16 進数として扱う 35 [1] pp.316-317. JM: atof (3)atof atoiatoi (3) strtodstrtod (3) strtolstrtol (3)

36 シーザー暗号 文字列の演習 36

37 シーザー暗号 アルファベットを N 文字シフトする暗号 例 : IBM→1 文字左へ →HAL 37

38 演習 : caesar.c 与えられた文字列をシーザー暗号で暗号化する関数 caesar(n,s) を作成せ よ。 文字コードが 0x20 ~ 0x7e の文字ついてのみ処理し、それ以外の文字につい ては処理せずそのまま残すこと。 0x20 ~ 0x7e からはみ出す値は値域の反対側に繋がるよう循環するよう変換 せよ。例えば n=1 なら 0x61('a') は 0x62('b') に、 0x7e は 0x20 に変換され る変換される。 n=-1 の場合も同様で、 0x20 は 0x7e に変換される。 caesar_main.c と共にコンパイルして動作を確認せよ 引数 : int n : 暗号鍵 ( シフトする文字数 ) char s[] : 暗号化する文字列 ( 終端が '\0') 戻り値 なし (void) 与えた配列 s を上書きしてシーザー暗号で 暗号化した文字列で上書きせよ 38 mintty + bash + GNU C $ gcc caesar_main.c caesar.c &&./a n = 1 s = hal ibm

39 ヒント プロトタイプ宣言の末尾の ; を {} に変え れば関数の定義になる。 文字の末尾は \0 で終端されている。 i を増やしながら s[i] != '\0' の間ループを 続ければ良い。 s 全体を暗号文で上書きするには各 s[i] を暗号化して s[i] に戻してやれば良い。 39 caerar_main.c void caesar(int n, char s[]);4

40 ヒント 0x20 未満、 0x7e 超になった場合の処理は 幾つかやり方がある if 文等で場合分けする方法 剰余算を使う方法 等々 40

41 参考文献 [1] B.W. カーニハン /D.M. リッチー著 石田晴 久 訳、プログラミング言語 C 第 2 版 ANSI 規 格準拠、共立出版 (1989) 41


Download ppt "C 言語入門 第 12 週 プログラミング言語Ⅰ ( 実習を含 む。 ), 計算機言語Ⅰ・計算機言語 演習Ⅰ, 情報処理言語Ⅰ ( 実習を含 む。 ) 1."

Similar presentations


Ads by Google