基礎プログラミングおよび演習 第9回 担当:長谷川晶一@5階522/520
文字と文字列
変数の型とメモリ上でのサイズ 変数の型をもういくつか int (整数)と double (実数) 以外: char (整数) short(整数) long(整数)と float(実数) たくさんの数を表すにはたくさんのメモリが必要 同じ整数でも表せる数の範囲が違う
変数の型とメモリ上でのサイズ 整数の型 実数の型 型名 範囲 メモリ使用量 char -127~+128 1byte(8bit) short int, long -32768~+32767 -2147483648~+2147483647 2byte(16bit) 4byte(32bit) (16bit CPUの場合、 int は short と同じになります) 型名 範囲(float.hにあります) メモリ使用量 float -3.402823466×1038~ +3.402823466×1038 1byte(8bit) double -1.7976931348623158×10308~ +1.7976931348623158×10308 4byte(32bit) 8byte(64bit)
文字列 文字列は、実は char 型整数の配列です 中身は文字コード 長さが、文字数+1個の配列になります。 ”abc”[0] == ’a’ ”abc”[1] == ’b’ ”abc”[2] == ’c’ ”abc”[3] == 0 長さが、文字数+1個の配列になります。 なので こんな事も #include <stdio.h> int main(){ printf(”’%c’ : %d\n”, ”abc”[0], ”abc”[0]); printf(”’%c’ : %d\n”, ”abc”[1], ”abc”[1]); printf(”’%c’ : %d\n”, ”abc”[2], ”abc”[2]); printf(”’%c’ : %d\n”, ”abc”[3], ”abc”[3]); } 'a' : 97 'b' : 98 'c' : 99 ' ' : 0 文字列の終わりには、0が入ってる。 #include <stdio.h> int main(){ char str[4]; str[0]=’a’; str[1]=’b’; str[2]=’c’; str[3]=0; printf(str); } abc
配列の面倒 配列は代入できません 初期化だけはできます。 代入はだめ 関数の引数にできません 関数の戻り値にできません では、printf()はどうやってるの? ⇒ 最後の方の授業でお話します。 初期化だけはできます。 初期化:宣言と同時の代入 int func1(char s[4]){ printf(s); } char func2[4](){ int main(){ char str[4]; str = ”abc”; #include <stdio.h> int main(){ char str1[5] = "abcd"; printf(str1); char str2[5] = {'a', 'b', 'c', 'd', 0} ; printf(str2); double array[2] = {10.0, 1.25}; } int main(){ char str1[5]; str1 = "abcd"; } 代入はだめ
文字列の編集 文字列は配列なので、一つ一つを書き換えると、文字列を書き換えられる 例:小文字から大文字へ 例:2文字の文字列に #include <stdio.h> int main(){ int c; char str[5] = "abcd"; for(c=0; str[c]; ++c){ str[c] = str[c]+(’A’-’a’); } printf(str); #include <stdio.h> int main(){ int c; char str[5] = "abcd"; str[2] = 0; printf(str); } 文字列の配列は最後に0が入っている 最後の0でforを抜ける
文字列の編集 キーボードから文字列を入力 str[end-1] まで文字が詰ってる getchar() で文字入力 改行文字なら終了 printf() で表示 #include "curses_subset.h" int main(){ cbreak(); noecho(); clear(); char str[200]; int end = 0; while(1){ int ch = getchar(); if (ch=='\n'){ break; }else if (ch >= ' '){ str[end] = ch; end ++; } str[end] = 0; clear(); printf(str); cbreak(); noecho(); edit.c
課題15 文字列の編集 ^ キーが入力されたとき、 最後の文字を1文字削除するような文字列編集 プログラムを作ってください。 課題15 文字列の編集 ^ キーが入力されたとき、 最後の文字を1文字削除するような文字列編集 プログラムを作ってください。 余裕があれば、ラインエディタを作ってみてください: ←キーでカーソル1文字左 →キーでカーソル1文字右 カーソル位置に文字を挿入 BSで、カーソル前の文字を削除 Delで、カーソル位置の文字を削除
変数のメモリ上での表現 メモリの最小単位は bit(ビット)。 1bit は 0 か 1を記憶できるメモリ。 Bitが8個集まると byte (バイト)になる。 00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000 : 11111110 11111111 全部で、28 =256個のパターンがある。 ⇒ 256種類の値を記憶できる
整数とビット Bitが8個集まると byte になる。 27 =128個 各パターンに左のように 数値を割り当てている 27 =128個 00000000 00000001 00000010 : 01111110 01111111 10000000 10000001 10000010 10000011 11111110 11111111 1 2 : 126 127 -128 -127 -126 -125 -2 -1 27 =128個 各パターンに左のように 数値を割り当てている 27 =128個
ビットと2進数 00000000 : 0×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 0×21 + 0×20 = 0 00000001 : 0×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 0×21 + 1×20 = 1 00000010 : 0×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 0×20 = 2 00000011 : 0×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 1×20 = 3 : 01111110 : 0×27 + 1×26 + 1×25 + 1×24+ 1×23+ 1×22 + 1×21 + 0×20 =126 01111111 : 0×27 + 1×26 + 1×25 + 1×24+ 1×23+ 1×22 + 1×21 + 0×20 =127 10000000 : 1×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 1×20 – 256=-128 10000001 : 1×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 1×20 – 256=-127 10000010 : 1×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 1×20 – 256=-126 10000011 : 1×27 + 0×26 + 0×25 + 0×24+ 0×23+ 0×22 + 1×21 + 1×20 - 256 : = 128+2+1-256=-125 11111110 : 1×27 + 1×26 + 1×25 + 1×24+ 1×23+ 1×22 + 1×21 + 0×20 - 256= -2 11111111 : 1×27 + 1×26 + 1×25 + 1×24+ 1×23+ 1×22 + 1×21 + 1×20 - 256= -1 1の位 2の位 4の位 8の位 100000000
変数とbit char型は、メモリ上での8bit のパターンと整数値が前頁のように対応する。 short, int/long型では、16bit,32bitのパターンが整数値と対応する(前頁の表が伸びる) double, float は もうちょっとややこしい 00000010 10000000 : 640 00000010 10000000 00000100 00000011 : 41944067
Bitの演算子 C言語は整数をビット単位で操作できます。 00000001 : 1 00010000 : 16 00010010 : 18 #include <stdio.h> int main(){ char c = 1; c = c<<4; printf("%d\n", c); c = c | 2; c = ~c; c = c&14; } 00000001 : 1 00010000 : 16 00010010 : 18 11101101 : -19 00001100 : 12 00001110 : 14 16 18 -19 12
Bit演算子 << 左 Bit Shift >> 右Bit Shift & Bit And | Bit OR i & 3 iと3で両方が1のビットだけを1にした整数 | Bit OR i | 3 iと3でどちらかでも1のビットを1にした整数 ^ Bit XOR i ^ 3 iと3でビットが異なるビットを1にした整数 ~ Bit Complement ~i iのビットの0と1を入れ替える
課題16 Bit演算子を使ってみよう 2進数で表示すると 10101010101010101010101010101010 となるような数値を、定数を書くのではなく、for文などを使って作り10進数と2進数で表示する。 この数とgetchar()でキー入力した文字コードの&を取って10進数と文字で表示する。 ようなプログラムを 作ってください int print8bit(int c){ int i; for(i=0; i<8; ++i){ if (c & (1<<(7-i)) ) printf("1"); else printf("0"); } 整数 c を2進数で表示する関数