Document

オブジェクト指向言語
オブジェクト指向言語演習
第05回 C言語の基礎
文字列
スケジュール(C言語)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
受講ガイダンスとプログラム開発基礎
Linuxの使い方と簡単なC言語プログラムの作成,実行
C言語 変数と式
(2004/10/4)
C言語 制御と流れ
(2004/10/4)
C言語 変数と式(復習)
(2004/10/18)
C言語 制御と流れ(復習)
(2004/10/18)
C言語 関数
(2004/10/25)
C言語 配列
(2004/10/25)
C言語 第1回到達度チェック試験
(2004/11/1)
C言語 文字列
(2004/11/1)
C言語 ポインタ
(2004/11/1)
C言語 構造体とユーザ定義型
(2004/11/8)
C言語 ファイル
(2004/11/8)
中間試験
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
2
出席確認
 出席確認WebPage
 http://www.iis.it-hiroshima.ac.jp/att/
 講義用WebPage
 http://www.iis.it-hiroshima.ac.jp/~nagasaka/
lect/oo/2004/
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
3
プログラミング言語 C
関数の引数に配列を使う
(function with array argument)
関数の引数に配列を使う(1)
 関数を呼び出すときは実引数の値を関数の仮引数に
コピーすると説明したが、もし引き渡されるものが
配列だった場合、配列全部をコピーするのは効率が
悪い。
 引数が配列であった場合以下の方法でデータを受け
渡す。
 配列要素を関数に渡す場合
実引数を「配列名[i]」とし、仮引数は「変数名」とする。
この場合、通常の変数の受け渡しと同じ。
 配列全体を関数に渡す場合
実引数を「配列名」とし、仮引数は「配列名[]」とする。
この場合、参照(アドレス)渡しとなる。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
5
関数の引数に配列を使う(2)
実引数の記述例 仮引数の記述例
データの渡され方
関数内での変更
配列名 x
double w[];
参照渡し
データコピーなし
実引数も変更される
配列要素 x[i]
double w;
値渡し
データコピー
実引数は変更されない
int func1(int);
int main(void){
int x[10], ret;
ret = func1( x[1] );
....
x[1]の内
}
容変化なし
int func1(int w){
w = 10;
....
}
変数として受け取る
main
x[1]
27.Sep.2004
値をコピー
func1
w
void func2(int);
int main(void){
int x[10], ret;
ret = func2( x );
x[1]の
....
内容が変
}
わる
void func2(int w[]){
w[1] = 10;
....
}
配列として受け取る
main アドレスを渡す func2
x
書き換えられる
Object Oriented Language - Y.Nagasaka: [email protected]
w[]
6
プログラミング言語 C
文字列
( String )
文字列の表現
 文字の復習
 文字型変数 → 1文字(1byte)
 文字型変数の宣言
 char
letter;
/*文字型変数letterの宣言*/
 文字型定数
 ‘A’ ‘B’ ‘0’ ‘\n’
文字Aを出力するプログラム
#include <stdio.h>
int main(void){
char letter;
letter = ‘A’;
printf(“%c\n”,letter);
return 0;
}
27.Sep.2004
letter=‘A’;
letter=65;
letter=0x41;
letter=0101;
letter=‘\101’;
letter=‘\x41’;
Object Oriented Language - Y.Nagasaka: [email protected]
/*文字*/
/*10進ASCII*/
/*16進ASCII*/
/*8進ASCII */
/*8進文字定数*/
/*16進文字定数*/
8
文字配列
 変数では1文字しか表せないので、配列を使って文字
列を表す。
 文字列をprintf関数を使って打ち出すときには、
printf(“HELLO”);
と書いた。この2重引用符で囲まれた“HELLO” が文
字列定数である。
 この”HELLO”は’H’,’E’,’L’,’L’,’O’と文字列
の終端を表す’\0’の6文字で構成される。
 この文字列を格納するために、文字配列を用いる。
例えば5文字を格納するための配列の宣言は、
char str[6];
最後の’\0’を入れるために6文字分宣言する必要がある。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
9
配列に文字を格納する
 文字列の終端を表す文字”\n”はNULL文字とも呼ば
れ、ASCIIコードで0である。
文字配列をコピーする関数strcpy
を利用
文字配列に1文字づつ代入
#include <stdio.h>
int main(void){
char str[6];
str[0] = ‘H’;
str[1] = ‘E’;
str[2] = ‘L’;
str[3] = ‘L’;
str[4] = ‘O’;
str[5] = ‘\0’;
printf(“%s\n”,str);
return 0;
}
str
27.Sep.2004
#include <stdio.h>
#include <string.h>
int main(void){
char str[6];
strcpy(str, “HELLO”);
printf(“%s\n”,str);
return 0;
}
0
1
2
3
4
5
H
E
L
L
O
\0
Object Oriented Language - Y.Nagasaka: [email protected]
10
文字配列の初期化
 文字型変数の初期化
 char c = ‘A’;
 文字配列の初期化
 char str2[6]=“HELLO”;
 初期化時に文字配列のサイズが指定されない場合
 char str7[] = “HELLO”;
 初期化時に必要サイズの6が自動的にセットされる。
 注意!!
char str[] = “Hello, world!”; /*初期化の時は文字列を
代入できる*/
char str[14];
char = “Hello World!”;
/*文字配列に代入はでき
ない*/
とはできない。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
11
文字列の操作 文字列のコピー
 文字列に対して代入操作ができないので、関数によ
り実現する必要がある。
 システムが用意している関数はstrcpyであり、ヘッダファ
イルのstring.hを読み込むことで使用可能
/*srcをdstにコピーする関数*/
void srt_copy( char dst[], char src[]) {
int i;
/* srcの文字列の終
for (i =0; src[i] != ‘\0’; i++) {
端が繰るまで1文字
dst[i] = src[i];
づつコピーする */
}
dst[i]= ‘\0’;
/* コピー先の配列にも終端を加える */
}
 この関数を使う例題は教科書p.257のリスト7.8
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
12
文字列の操作 文字列の長さ(1)
 文字列の長さを数える関数
 システムが用意している関数はstrlenであり、ヘッダ
ファイルstring.hを読み込む必要がある。
/* strの長さを数える関数*/
int srt_length( char str[] ) {
int i;
for (i =0; str[i] != ‘\0’; i++)
;
return i;
}
/* srcの文字列の終
端が来るまでiをカ
ウントアップ*/
for文で反復ごとに何もする必要が無い場合は、
for(初期値;条件式;更新式) ;
とすることができる。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
13
文字列の操作 文字列の長さ(2)
 文字列の長さを数える関数を使って、電報の文字数
と料金を計算するプログラム
#include <stdio.h>
int str_length(char []);
int main( void ) {
char telegram[100];
int len, charge;
printf(“Input Telegram >>>”);
/*一行の入力でscanfが利用
できない理由はp.262の落とし
穴を参照*/
printf(“The length of your telegram is %d.\n”, len);
printf(“The charge is %d yen\n”,len *5);
return 0;
gets( telegram );
len = str_length(telegram);
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
14
gets関数
 gets関数の使い方
 端末でman getsと打ち込んでみる。
manコマンドの出力の要約
gets
標準入力から一行読み込み、引数の文字配列に入れる
書式
#include <stdio.h>
char *gets(char []);
使い方 ret = gets(文字配列);
戻り値 関数が成功すると文字配列のポインタを返し、ファイル終
わりあるいは失敗するとNULLを返す。
 配列全体を渡したいので、前ページの例題では
gets( telegram );
とした。この場合、戻り値は無視した。
 この関数は少し危険であるのでコンパイル時に
warningが出る。本来ならfgetsを使うべき。
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
15
課題1
 キーボードから入力された文字列の文字順を逆にし
て出力するプログラムを作りなさい(oo09-1.c)。
 ヒント:2つの配列を使い、入力文字列の長さを数え、
後ろからコピーをする。最後に\0を加える。
0
1
2
input
H
i
r
reverse
a
0
...
len-1
a
...
宣言長-1
...
宣言長-1
\0
\0
1
2
...
len-1
実行例
# ./oo09-1
Input a string: Hiroshima
Original is Hiroshima, Reverse output is amihsoriH.
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
16
課題2
 与えられた文字列srcの文字順を逆にして文字列dstにコピーす
る関数str_revを作りなさい。メイン関数は以下の通りとなる
(oo09-2.c)。
#include <stdio.h>
#include <string.h>
void str_rev(char [], char[]);
int main(void){
char input[100], reverse[100];
printf("Input a string: ");
gets(input);
str_rev(input, reverse);
printf("Original is %s, Reverse output
is %s.\n",input,reverse);
return 0;
}
void str_rev(char src[], char dst[]){
この部分を作る
}
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
17
コンパイルと実行
 まずはじめに
 作業ディレクトリの作成
一度実行すればよい
% mkdir ~/wrk/
% mkdir ~/wrk/oo/
 次に




作業ディレクトリへの移動
プログラミング
コンパイル・リンク
実行
% cd ~/wrk/oo
% vi lect01-1.c
% gcc -o lect01-1 lect01-1.c
% ./lect01-1
* C言語プログラムのファイル名は、.c でなければならない
27.Sep.2004
Object Oriented Language - Y.Nagasaka: [email protected]
18