* 第4回 C言語の復習(ポインタと文字列) [#jac87001]
* 第3回 配列と関数 [#baab39cd]

** 目的 [#db13a39d]
** 目的 [#e56ca481]

前回と同じ。C言語を復習し実際に使うため、短いプログラムを自分で考えて作成する。

** 課題 [#x3d7bb23]
** 課題 [#w485af1f]

できない問題は、後回しにして進んだほうがいいかもしれません。
まず、[[../C言語基本の基本]]をよく読むこと。分かりやすいプログラムを書くために、必ず守ってほしいことがいくつかある。ここに書いてあることを、きちんと守った上でプログラムを書くこと。

基本的には前回と同じように、下記の問題から、各自自分のレベルに合った問題を解いて提出する。全ての問題を時間内に解くのはまず無理だろうから、適切なところからはじめればよいが、もちろん、高いレベルの問題をより多く解いていたほうがよい評価となる。

なお、[[第1回>../2003-F01]]のa1)〜b10)を解き終わっていない人は、まずひととおり解くこと。これらは、本当の基本問題であり、できなければ先に進むことができない。

提出は、[[提出エリア>../提出]]の自分の提出エリアにアップロードする。なお、プログラムは、きちんとコンパイルし、完全かつ正確に動作することを確認してから、提出すること。

- [[プログラムの提出のしかた>../提出]]
- [[C言語のコンパイルと実行のしかた>../C言語環境]]

*** 中級〜上級レベル [#jab39d95]
*** 初級レベル [#m6f1b605]

''ポインタ''
''配列''

g1) int型の変数aとint型へのポインタpを定義し、pを用いてaに好きな値を代入するプログラムを作成しなさい。
d1) 4つの要素を持つdouble型配列にキーボードから数値列を読み込み,合計と平均を求めるプログラムを作成しなさい.

g2) int型の変数a,bに適当な整数を代入する。pをaへのポインタ,qをbへのポインタとし,pとqをポインタを用いて変数a,bの内容を入れ替えなさい。結果を確認するため,入れ替える前と後の変数a,bの値を表示しなさい。
>【配列】 たとえばint a[N];と宣言した配列は、a[0]からa[N-1]までのN個の要素を持つ。a[N]は存在しないので注意。intでなくても同じ。
 int a[10];
 a[10] = 3;  /* 誤り!! */
上記は誤りだが、通常Cコンパイラはこれを検出しない。しかし、実行時に意味不明の挙動を示す原因となるので決してしてはならない。

g3) 長さ5のint型,char型の配列を作り,各要素に適当な値を代入しなさい。それぞれの配列について,ポインタを使って配列の要素のアドレスと中身を表示せよ。
d2) キーボードから、double型の配列v[2]およびw[2]を読み込み、これらを2次元ベクトルと考えて、和と内積を表示するプログラムを作成しなさい。
- 参考(ベクトルの加算) http://shigihara.hp.infoseek.co.jp/vect12.htm
- 参考(ベクトルの内積) http://shigihara.hp.infoseek.co.jp/vect16.htm

> 【ポインタの表示】 ポインタの値(アドレス)を表示するには%pを用いる。
 printf("%p\n", ptr);
d3) キーボードから10個の整数を読み込んだ後、平均以上の数値と平均未満の数値に分けて表示するプログラムを作りなさい。

g4) 10個の要素を持つ整数型配列に適当な初期値を入れ,その合計をポインタを使った計算で求めなさい。
d4) キーボードから10個の整数を読み込み,最後に逆順に表示して終了するプログラムを作成しなさい。

g5) 自分の名前(配列)と、アルファベット1文字をキーボードから読み込み,名前の中からそのアルファベットを検索して、そのアドレス(ポインタの値)を出力せよ
d5) キーボードから0以上100未満の整数を複数読み込み、1ケタ、10台、20台、30台…90台の整数がそれぞれ何個ずつあるか数えるプログラムを作成しなさい。途中で負数が入力された時点で、入力の終了とするようにせよ。※カウンタを配列にする。

g6) 整数型の配列aと,整数型へのポインタpを定義し,配列の好きな要素a[i]に適当な値を代入し,pにa[i]のアドレスを代入する。a[i],&a[i], *p, pを表示すること。また,*pに別の値を代入するとどうなるか。
d6) まず,ともに要素数5の整数配列aとbを定義し,キーボードから数値を読み込む.そして,aとbに共通の要素があるかどうか調べ,ある場合にはそれらをすべて表示するC言語のプログラムを作成しなさい。

g7) 日曜日を0としてn日目の名前を返す関数を作りなさい。※曜日名は文字列定数で定義済みのものを利用すること。たとえば「return "Sunday"」とするとよい。
 char *dayname(int d);
使用例
 printf("Today is %s.\n", dayname(i));
''文字列''

g8) 欠番。
d7) 文字型の配列を自分の名前(ローマ字)で初期化し、その配列中の文字を1文字づつ画面に表示するプログラムを作成しなさい。

g9) 2つの整数x,yを引数に取り、商と余りを同時にもとめる関数を作成しなさい。なお、y=0なら0を返し,それ以外なら1を返すようにせよ。
 int divide(int x, int y, int *sho, int *amari);
使用例
 int a, b, c;
 c = divide(5, 3, &a, &b);
 if (c != 0) printf("%d %d\n", a, b);
>【文字列】 文字列の最後は、ヌル文字('\0': 終端文字)で終わる。よって、文字列を格納するためには、その文字列の長さ+1文字分の領域(charの配列)が必要である。
 char str[] = "Tamagawa";
の場合、下記のように9文字分の領域を取る。
       0   1   2   3   4   5   6   7   8
 str ['T'|'a'|'m'|'a'|'g'|'a'|'w'|'a'|'\0']

g10) 整数型へのポインタを2つ取り、それらの指す整数値を交換する関数swapを作成せよ。
 void swap(int *p, int *q);
使用例
 int a = 3, b = 5;
 swap(&a, &b);
 printf("a=%d b=%d\n", a, b);
d8) scanfを用いて,自分の出身地(都道府県など)をローマ字で読み込み,表示するプログラムを作成しなさい。

''文字列''
>【文字列の読込み】 文字列の文字配列への読み込みには、%sを用いる。
 char str[128];
 scanf("%s", str);

h1) 長さ10文字のchar型の配列fromとtoを定義し、キーボードからfromに文字列を読み込んだ後、ポインタ2つを用いてtoにこの文字列をコピーするプログラムを作成しなさい。
d9) キーボードからアルファベットからなる文字列を読み込み,その中のそれぞれの文字を a→d,s→v,x→a,z→cのように,アルファベット順で3文字後にずらし,その結果の文字列を出力するプログラムを作成しなさい。ただし,zの次はaとする。

> 【ポインタによる連続コピー】 ポインタによる連続コピーでは、よく以下のような書き方が用いられる。
 *p++ = *q++;
d10) キーボードから文字列strと整数n,mを読み込み,strの中のn文字目からm文字分の文字列を切り出して新しい文字列に代入し,最後にその切り出された文字列を表示するC言語のプログラムを作成しなさい.

h2) 適当な配列に,キーボードから自分の名前をアルファベットで入力しなさい。配列の内容を表示した後,ポインタを使用して配列の中身を逆順に入れ替え,そのときの配列の内容を表示しなさい。
>【文字列の作成】 自分で文字列を作成する場合には、終端のヌル文字も自分で設定しなければならない。
 str[5] = '\0';

h3) キーボードから入力された文字列を char 型への配列 str に読み込み、char型へのポインタ ptr を用いて、str 内の1文字目から最後までの文字列、2文字目から最後までの文字列、3文字目から最後までの文字列、…を順に出力するプログラムを作成せよ。
*** 中級レベル [#s41ebbbb]

出力例を示す。
 Tamagawa
 amagawa
 magawa
 agawa
 gawa
 awa
 wa
 a
''関数''

h4) 2つの文字列を比較し,同じなら1,異なる場合は0を返す関数を作成しなさい。
 int strequal(char *str1, char *str2);
e1) 半径rを引数として,円の面積と円周を表示する関数を作成しなさい。その関数の動作を確認するプログラムを作成しなさい。以下にプロトタイプ宣言の例を示す。
 void print_circle(double r);

h5) まず、3つの文字列 "end", "quit", "stop" を要素とする配列 bye を定義しておく。そして、キーボードから文字列 str を順次読み込んで、それが、bye の要素のいずれかと一致するまでその入力を繰り返すようなプログラムを作成せよ.※標準ライブラリ関数strcmpを用いる。
e2) 1からnまでを順に表示する関数を作成しなさい。その関数を利用してキーボードから段数を読み込むと、例(入力が5の場合)のように表示するプログラムを作成しなさい。
 12345
 1234
 123
 12
 1

h6) キーボードから文字列を読み込み,それが数値でない場合にはそのまま画面に表示し,数値ならばその逆数を表示するプログラムを作成せよ.※文字列を数値に変換する代表的な関数はatoiである。
e3) 西暦を引数とし,平成何年かを返す関数を作成しなさい。その関数の動作を確認するプログラムを作成しなさい。以下にプロトタイプ宣言の例を示す。
 int heisei(int seireki);

h7) キーボードから文字列patternとstrを読み込み、strにpatternが含まれる場合には「成功」と表示して終了し、含まれない場合には「失敗」表示として成功するまでstrの読み込みを繰り返すプログラムを作成せよ。※標準ライブラリ関数strstrについて調べてみよ。
e4) 関数f(x)=x+1をC言語で表し、整数nをキーボードから読み込み、f(0)+f(1)+f(2)+...+f(n)の値を表示するプログラムを作成しなさい。

e5) 2つの整数を引数として,値の小さい方を返す関数minを作成しなさい。これを利用して,10個の整数を読み込み,その最小値を求めるプログラムを作成しなさい。

e6) 円柱の体積を計算して出力するプログラムを作成しなさい。半径を引数とし、円の面積を返す関数circleと、半径と高さを引数とし、circleを使って円柱の体積を求める関数cylinderを定義して利用しなさい。

e7) double型の引数を取り、その絶対値を返す関数absoluteを定義し、さらにその関数を利用して関数 f(x) = |-x + 1|を定義しなさい。その関数の動作を確認するプログラムを作成しなさい。

''ライブラリ関数''
- 参考 http://www9.plala.or.jp/sgwr-t/c/sec07.html 

e8) 座標平面上の点 (x, y) から原点までの距離を計算するC言語のプログラムを作成し,コンパイル・実行させたい.キーボードからdouble型の数値xおよびyを読み込み,距離を計算して画面に表示するプログラムを作成しなさい.ライブラリ関数sqrtのマニュアルには、以下のように記述されている。
 #include <math.h>
 double sqrt(double x);

>【数学関数】 数学関係の標準ライブラリを使ったプログラムをコンパイルするには、コンパイル時に数学ライブラリをリンクする必要があることがある。gccのオプションで、-lmと指定する。
 gcc -lm ファイル名.c

e9) 三角形の2辺とその挟む角を引数とし、面積を返す関数を作成しなさい。ただし、角度の単位は“度”とする。※関数sinを利用するが、度からラジアンへの変換が必要である。
- 参考 http://shigihara.hp.infoseek.co.jp/sin53.htm
- 参考 http://www2.ocn.ne.jp/~atel.a/emath/sugakuc.html

e10) 自分の名前(ローマ字)をキーボードから読み込み、標準ライブラリ関数toupperを用いて大文字に変換した後、画面に表示するプログラムを作成しなさい。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS