プログラミング演習Ⅱ 第13回 文字列とポインタ(2) 情報・知能工学系 山本一公 [email protected] 前回の課題の解説・ポイント(1) • 課題11-1 – 配列は連続領域に確保される • st[0][0]~st[2][5]でアドレスが1ずつ増える – 文字列リテラルは必ずしも連続した領域に確 保されるわけではない • が、ここの環境では連続した領域に確保される • 配列と違って、必要な領域しか確保されない • pt[1][3]とpt[2][0]のアドレスが同じに! – 文字列の長さが変わると影響の出方も変わる 前回の課題の解説・ポイント(2) • 配列の場合 st[0][0] ↓ T u st[1][0] ↓ r b o \0 N A st[2][0] ↓ \0 • ポインタの場合 pt[0][0] ↓ 1 2 pt[1][0] ↓ 3 4 5 \0 1 2 \0 \0 \0 D O 1 ↑ pt[1][3] 2 C \0 \0 何が入っているか 分からない pt[2][0] ↓ \0 H 3 4 \0 ↑ pt[2][5] 前回の課題の解説・ポイント(3) • 課題11-2 ポインタを入れる配列 入先1 っ頭次 てア元 いド配 るレ列 スの が 実際に数値を入れる配列 課題10の採点結果から • 課題10-1 – 累和を入れる変数の初期化を忘れている人が 何人かいた • 勝手に0に初期化してくれるので、ここ(計算機 室)の環境で動かしていると気づきにくいが、コ ンパイラによっては正しく動かないので注意する こと • 共通 – 課題が何か分かってない人が! 今日の内容 • 教科書 pp.254~265 • 文字列とポインタ • ポインタによる文字列の操作 • 文字列を扱うライブラリ関数 ポインタによる文字列の操作(1) • 文字列の長さを求める関数 – p.254, List 11-6 – 「ポインタをポインタらしく使って」 • ↓ここ while (*s++) len++; /* ポインタの指すところが移動して行く! */ /* p.255, Fig.11-6 を見よ! */ • ↓今までなら、こんな感じ while (s[len]) len++; /* これで十分だけどね */ const なポインタ • ポインタを const で定義すると、 「ポインタを介した値を書きかえること ができなくなる」 – 「ポインタ変数の値を書きかえることが できなくなる」んじゃないよ ポインタによる文字列の操作(2) • 文字列をコピーする関数 – p.256, List 11-7 – 「ポインタをポインタらしく使って」 • ↓ここ while (*d++ = *s++) ; /* ポインタの指すところが移動して行く! */ /* p.257, Fig.11-7 を見よ! */ • ↓今までなら、こんな感じ while (d[i] = s[i]) i++; /* これで十分だけど、上と比べると */ /* i という変数が余分にいる */ 文字列の不正なコピー • p. 258, List 11-8 • 文字列リテラルとして確保された領域へ上書き するのは良くないこと – そもそも処理系によってはできない – 文字列リテラルは const だと思っておけ! • 確保されていない領域への書き込み – p.259, Fig. 11-8 – 確保されている領域の外が使えるかどうか分からな い……というか、普通は使っちゃダメ! – 行列も同じ!確保した領域より多く使っちゃダメ! ポインタを返す関数 • p.259の下半分 • プログラムがちょっと短くなるだけで何が嬉し いのか……という感じ? • 例えば「文字列の途中のポインタを返す関数」 「行列の中の、ある行ベクトルへのポインタを 返す関数」というような使い方ができる • 前回の演習課題の解説のところで説明した malloc() は確保したメモリの先頭アドレスを返す 文字列を扱うライブラリ関数(1) • 文字列の長さを求める関数 – size_t strlen(const char *s) • s が指す文字列の長さを返す • 文字列をコピーする関数 – char *strcpy(char *s1, const char *s2) – char *strncpy(char *s1, const char *s2, size_t n) • s2 が指す文字列を s1 が指す領域にコピーする • strncpy() の場合は n 文字コピー(足りない分は 0) • 返り値は s1 の値(普通、使わない) 文字列を扱うライブラリ関数(2) • 文字列を連結する関数 – char *strcat(char *s1, const char *s2) – char *strncat(char *s1, const char *s2, size_t n) • s1 が指す文字列の末尾に s2 が指す文字列を連結す る • strncat() の場合は最大で n 文字連結 • 返り値は s1 の値(普通、使わない) 文字列を扱うライブラリ関数(3) • 文字列を比較する関数 – char *strcmp(const char *s1, const char *s2) – char *strncmp(const char *s1, const char *s2, size_t n) • s1 が指す文字列と s2 が指す文字列の文字コード (p.200)における大小関係の比較を行う • 等しければ 0を、s1 の方が大きければ正の整数値、 s2 の方が大きければ負の整数値を返す – 「等しいときに 0 を返す」というのが感覚と逆なので、 「文字列が等しければ」のつもりで 「if (strcmp(str1, str2)){…}」とやってしまいがち。注意。 文字列を扱うライブラリ関数(4) • 文字列を数値に変換する関数 – int atoi(const char *nptr) • 文字列を int 型の整数値に変換 – long atol(const char *nptr) • 文字列を long 型の整数値に変換 – double atof(const char *nptr) • 文字列を double 型の実数値に変換 – 結果の値がそれぞれの型で表現できないとき の動作は未定義 今週の課題 1. 教科書 p. 260、演習11-2のプログラムを作成せ よ。main関数等も作成して、完成したプログラ ムを作成すること。 2. 教科書 p. 262、演習11-5のプログラムを作成せ よ。main関数等も作成して、完成したプログラ ムを作成すること。 レポートについて • 電子メールで提出 – 提出先は [email protected] – Subjectを「プログラミング演習2 課題12提出 番号・氏名 」とすること – C言語ソースファイルを添付する 学籍 • メールの本文には何も書かなくて良いです – ソースファイルの頭にコメントで以下の情報を入れる • 学籍番号・氏名 • プログラムの説明(どのように動くのか、工夫した点等) • 実行結果(長い場合は一部)を貼る – 提出締切は、2月6日(水) 12:00 (1週間後) 授業用Webサイト • URL: http://www.slp.cs.tut.ac.jp/~kyama/programming2/ – 課題のpdfファイルが置いてあります。 – 授業で使ったpptファイルを置いていきます。 • 質問メールは、以下のどちらかのアドレスまで – [email protected] – [email protected] • C-515へ直接質問しに来ても構いません
© Copyright 2024 ExpyDoc