...

講義用資料

by user

on
Category: Documents
10

views

Report

Comments

Transcript

講義用資料
プログラムの設計と実現 I(第5回:2016/05/12)
◎第4回の演習の解答例
#include <stdio.h>
int combination(int n, int r)
{
if (r == 1) { /* nC1 = n */
return n;
} else if (n == r) { /* nCn = 1 */
return 1;
} else { /* nCr = n-1Cr-1 + n-1Cr */
return combination(n-1,r-1) + combination(n-1,r);
}
}
int main(void)
{
int num1, num2;
do {
printf("nCr を計算します。\n");
do {
printf("正の整数 n を入力してください:");
scanf("%d", &num1);
} while (num1 <= 0);
do {
printf("正の整数 r (r<=n) を入力してください:");
scanf("%d", &num2);
} while (num2 <= 0);
} while (num1<num2);
printf("nCr は%d です。\n", combination(num1, num2));
return 0;
}
◎文字型
文字型変数の定義
char ch;
ch は文字型の変数(実際には 1 バイト整数型)
各文字には数値が決められている → ASCII 文字コード(世界共通)
※文字コードはいろいろ存在し、漢字等の扱い方法も様々である。
英数字は ASCII でほぼ問題はない。
漢字については、最近は UTF が用いられることが多いが、JIS,
ShiftJIS, EUC も利用されている。
◎ASCII 文字コード
0x00~0x1f,0x7f 制御文字,
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
0x20
0x21
0x22
0x23
0x24
0x25
0x26
0x27
0x28
0x29
0x2a
0x2b
0x2c
0x2d
0x2e
0x2f
!
"
#
$
%
&
'
(
)
*
+
,
.
/
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
0x30
0x31
0x32
0x33
0x34
0x35
0x36
0x37
0x38
0x39
0x3a
0x3b
0x3c
0x3d
0x3e
0x3f
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
0x40
0x41
0x42
0x43
0x44
0x45
0x46
0x47
0x48
0x49
0x4a
0x4b
0x4c
0x4d
0x4e
0x4f
0x20~0x7e 印字可能文字
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
0x50
0x51
0x52
0x53
0x54
0x55
0x56
0x57
0x58
0x59
0x5a
0x5b
0x5c
0x5d
0x5e
0x5f
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
0x60
0x61
0x62
0x63
0x64
0x65
0x66
0x67
0x68
0x69
0x6a
0x6b
0x6c
0x6d
0x6e
0x6f
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
0x70
0x71
0x72
0x73
0x74
0x75
0x76
0x77
0x78
0x79
0x7a
0x7b
0x7c
0x7d
0x7e
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
※C 言語では ASCII 文字コードに限定していないが、少なくとも数字の
0~9 はこの順で一つずつ値が大きくなることを規定している。
◎文字の入出力
キーボードから入力した文字を画面に表示するプログラム
#include <stdio.h>
int main(void)
{
int ch;
/* 文字読み込み用の変数。ch は int 型であることに注意 */
while ((ch = getchar()) != EOF) {
/* 1文字読み込み、返り値が EOF になるまで繰り返す */
/* キーボード入力の場合、Ctrl+d を入力すると EOF となる */
printf("%c", ch);
/* 読み込んだ文字を画面に出力する */
/* char 型の値をプリントアウトするには %c を用いる */
}
/* getchar()が EOF の場合、上のループを抜けて、ここに到達。*/
printf("%d\n", ch);
/* EOF の値(ch)を確認。表示の型が int であることに注意 */
return 0;
/* 正常終了 */
}
getchar()
・標準入力から一文字読込む関数。
・文字が読込まれた場合はその文字の数値が返る。
・ファイル終端の場合や予期せぬエラーの場合、EOF が返る。
・EOF は stdio.h で定義されており、マイナスの値をとる(そのため、
getchar() の返り値の型は int 型でなければならない)
。
1 文字出力する関数として、putchar()という関数も存在する。上記の
printf("%c", ch);
は以下のように変更可能。
putchar(ch);
◎文字定数
文字を' 'でくくると、その文字の数値(ASCII コード等)となる。
たとえば上記のプログラム例の while を以下のように変えると、
文字 E を入力した時に終了するようになる。
while ((ch = getchar()) != 'E') {
'E'は実際には 69 という整定数を表すが、プログラマはその値を知る必
要はなく、'E'と書くだけでよい。
◎文字列
文字列とは文字が連続したもの
→C 言語では文字の配列として表現される(配列の各要素は一文字)
プログラム例(List9-2)
#include <stdio.h>
int main(void)
{
char str[4];
str[0]
str[1]
str[2]
str[3]
=
=
=
=
'A';
'B';
'C';
'\0';
メモリ空間
配列
str[]
'A' (65)
str[0]
'B' (66)
str[1]
'C' (67)
str[2]
‘¥0' (0)
str[3]
printf("文字列 str は%s です。\n", str);
return 0;
}
'\0'は特別な記号 → 文字列の終端を表わす
文字列をプリントアウトするには%s を用い、文字列(配列)の[]は
付けない('\0'の直前の文字までが出力される)
C 言語では配列変数の大きさは最初に決めなければいけない
→文字列を記憶する配列はあらかじめ大きめに確保しておき、終端を
'\0'で示すことにより実現している
上記の前半部分は以下のようにも書ける。
char str[] = {'A', 'B','C', '\0'};
または
char str[] = "ABC";
/* " " で囲まれた文字列を文字列定数/文字列リテラルと呼ぶ */
たとえば、以下のように配列のサイズを指定した場合、
char comp[10] = "Mozart";
メモリー上には以下のように配置される。
プログラム例(List9-4)
#include <stdio.h>
int main(void)
{
char name[40];
printf("お名前は:");
scanf("%s", name);
/* scanf で文字列も読込める。
なぜ&がなくて配列名だけなのかは後日に理解可能となる */
printf("こんにちは、%s さん!!\n", name);
return 0;
}
◎文字列の応用プログラム例
#include <stdio.h>
int str_length(char s[])
/* 文字列 s を受け取り、その長さ('\0'は含まない)を返す関数 */
{
メモリ空間
int len = 0;
'A' (65)
len=0
while (s[len] != '\0') {
配列
'B' (66)
len=1
len++;
s[]
'C' (67)
len=2
}
‘¥0' (0)
len=3
return(len);
}
void str_copy(char s[], char t[])
/* 文字列 s と t を受け取り、s に t の内容をコピーする関数 */
{
メモリ空間
int i;
for (i=0; t[i] != '\0'; i++) {
'A' (65)
文字'A'のコピー
s[i] = t[i];
配列
'B' (66)
文字'B'のコピー
s[]
/* '\0'の直前までコピーする */
'C' (67)
文字'C'のコピー
}
'¥0' (0)
終端記号'¥0'の代入
s[i] = '\0';
/* 最後に'\0'を追加 */
'A' (65)
return;
配列
'B' (66)
}
t[]
'C' (67)
int main(void)
‘¥0' (0)
{
char s[100];
char t[100];
printf("文字列 t を入力してください:");
scanf("%s", t);
printf("文字列 t\"%s\"の長さは%d です。\n", t, str_length(t));
printf("文字列 s に文字列 t\"%s\"をコピーすると", t);
str_copy(s,t);
printf("文字列 s は\"%s\"となります。\n", s);
return 0;
}
実行例:
文字列 t を入力してください:ABC
文字列 t"ABC"の長さは 3 です。
文字列 s に文字列 t"ABC"をコピーすると文字列 s は"ABC"となります。
◎文字列の配列
文字列の配列も作成可能で、二次元配列として表現される。
プログラム例(List9-11 改)
#include <stdio.h>
void put_strary(char s[][6], int n)
{
int i;
for (i = 0; i < n; i++) {
printf("s[%d]=\"%s\"\n", i, s[i]);
/* s[][]の括弧が一つだけであることに注意 */
}
return;
}
int main(void)
{
char s[][6] = {"Turbo", "NA", "DOHC"};
put_strary(s, 3);
return 0;
}
メモリ上には 6×3 バイトの
連続領域に配置される。
配列
s[3][6]
s[0]
s[1]
s[2]
メモリ空間
'T'
'u'
'r'
'b'
'o'
'¥0'
'N'
'A'
'¥0'
???
???
???
'D'
'O'
'H'
'C'
'¥0'
???
s[0][0]
s[0][1]
s[0][2]
s[0][3]
s[0][4]
s[0][5]
s[1][0]
s[1][1]
s[1][2]
s[1][3]
s[1][4]
s[1][5]
s[2][0]
s[2][1]
s[2][2]
s[2][3]
s[2][4]
s[2][5]
Fly UP