ViVi Home > 技術文書 > ポインタ入門 > 基礎 演習問題


 

 

C/C++ ポインタ入門 > 基礎 演習問題
Nobuhide Tsuda
Oct-2013

※ テストコードを用意しているので、それをダウンロードし、利用しなさい。

※ まずは正しく動作するプログラムを作成することを目標にしなさい。
全テストケースをパスするからといって、正しいプログラムとは限りません。 泥縄的にテストケースをパスするように修正するのは止めましょう。
なるべく余分な作業領域は使用しないようにしなさい。

※ それができたら、単に答えが合っているだけでなく、できるだけトークン数の少ない簡潔なコードを書きなさい。
トークン数が解答例より極端に多い(1.5倍程度以上)場合は、コードの見直しをしなさい。
トークン数の定義についてはここを参照しなさい。

演習問題

  1. int my_strlen(const char *str) 引数に文字列をとり、文字列の長さを返す関数を実装しなさい。
  2. int my_count_char(const char *str, char c) 文字列 str に文字 c が何個含まれるかを返す関数を実装しなさい。
  3. const char *my_strchr(const char *str, char c) 引数に 文字列 str、文字 c をとり、文字列中に文字cがあれば、 そこへのポインタを返す関数を実装しなさい。文字列中に文字cが無い場合は0を返しなさい。
  4. char my_maxchar(const char *str) 引数文字列 str の中で、文字コードが最も大きい文字を返しなさい。str が空文字列の場合は 0 を返しなさい。
  5. const char *my_maxcharptr(const char *str) 引数文字列 str の中で、文字コードが最も大きい文字へのポインタを返しなさい。 最も大きい文字が複数ある場合は、最も大きい文字の中で最初の文字へのポインタを返しなさい。 str が空文字列の場合は、0 を返しなさい。
  6. void my_strfill(char *dst, char c, int n) 文字配列 dst に、文字 c を n 個設定し、 最後にヌル文字('\0')を設定する関数を実装しなさい。dst は充分な領域が確保されていると仮定してよい
  7. void my_erase_head(char *str, int n) 文字列 str の先頭 n バイトを削除し、その後の文字列を前に移動する関数を実装しなさい。n が str の文字数より大きい場合は str を空文字列にしなさい。
  8. void my_erase_tail(char *str, int n) 文字列 str の末尾 n バイトを削除する関数を実装しなさい。n が str の文字数より大きい場合は str を空文字列にしなさい。
  9. void my_push_back(char *str, char c) 文字列 str の末尾に、文字 c を追加する関数を実装しなさい。str には充分な領域があると仮定してよい。 c がヌル文字('\0')の場合は、何も処理をしなくてよい
  10. void my_push_front(char *str, char c) 文字列 str の先頭に、文字 c を挿入する関数を実装しなさい。str には充分な領域があると仮定してよい。 c がヌル文字('\0')の場合は、何も処理をしなくてよい
  11. char my_pop_back(char *str) 文字列 str の末尾文字を削除し、削除した文字を返す関数を実装しなさい。str が空文字列の場合はヌル文字('\0')返しなさい
  12. char my_pop_front(char *str) 文字列 str の先頭文字を削除し、削除した文字を返す関数を実装しなさい。str が空文字列の場合はヌル文字('\0')返しなさい
  13. void my_strcpy(char *dst, const char *src) 引数に 文字列 src, コピー先 dst をとり、src を dst にコピーする関数を実装しなさい。
  14. int my_size(const int *first, const int *last) first から last 直前までのデータ数を返す関数を実装しなさい。first > last の場合は考慮しなくてよい。
  15. int my_accumulate(const int *first, const int *last) first から last の直前までポインタが指すデータを合計した値を返す関数を実装しなさい。first <= last と仮定してよい。
  16. const int *my_find(const int *first, const int *last, int value) first から last の直前までポインタが指すデータを検索し、最初の value のアドレスを返す関数を実装しなさい。 value が無かった場合は last を返しなさい
  17. int my_count(const int *first, const int *last, int value) first から last の直前までポインタが指すデータを走査し、値が value のデータの個数を返す関数を実装しなさい。
  18. void my_set_zero(int *first, int *last) first から last の直前までのポインタが指す先に 0 を格納する関数を実装しなさい。first <= last と仮定してよい。
  19. void my_set_value(int *first, int *last, int v) first から last の直前までのポインタが指す先に v を格納する関数を実装しなさい。first <= last と仮定してよい。
  20. int my_accumulate(const int *first, size_t size) first から size 個のデータを合計した値を返す関数を実装しなさい。
  21. ★★char my_pop_nth(char *str, int n) str の n 番目の文字を削除し、削除した文字を返す関数を実装しなさい。n は 0 オリジン(最初の文字を消す場合は n = 0)とします。 n がマイナス、または n が str の文字数以上の場合は、何も削除せず '\0' を返しなさい。
  22. ★★void my_push_nth(char *str, int n, char c) str の n 番目に文字 c を挿入する関数を実装しなさい。n が 0 の場合は c を文字列の先頭に挿入するものとします。 n がマイナスの場合は先頭に挿入しなさい。n が str の文字数より大きい場合は末尾に挿入しなさい。
  23. ★★void my_trim_left(char *str) 引数 str の先頭の空白類(' ' または '\t')を削除し、その後の文字列を前に移動する関数を実装しなさい
  24. ★★void my_trim_right(char *str) 引数 str 末尾の空白類(' ' または '\t')を削除する関数を実装しなさい
  25. ★★void my_strcat(char *dst, const char *src) 引数に 文字列 dst, 文字列 src をとり、src を dst 末尾にコピー(src と dst を連結)する関数を実装しなさい。 dst には充分な領域が確保されていると仮定してよい
  26. ★★void my_strins(char *dst, const char *src) 引数に 文字列 dst, 文字列 src をとり、src を dst の最初に挿入する関数を実装しなさい。dst には充分な容量があると仮定してよい。
  27. ★★void my_strrev(char *str) 与えられた文字列の文字順序を反転(例:"abc" → "cba")する関数を実装しなさい。
  28. ★★void my_str_rot_left(char *str) 与えられた文字列の最初の文字を最後に移動する(例:"12345" → "23451")する関数を実装しなさい。
  29. ★★void my_str_rot_right(char *str) 与えられた文字列の最後の文字を最初に移動する(例:"12345" → "51234")する関数を実装しなさい。
  30. ★★const char *my_strrchr(const char *str, char c) 引数に 文字列 str、文字 c をとり、文字列中に文字cがあれば、 最後の c へのポインタを返す関数を実装しなさい。文字列中に文字cが無い場合は0を返しなさい。
  31. ★★bool my_is_matched(const char *text, const char *pat) pat の指す文字列の長さが len の時、text の先頭 len 文字が pat に一致すれば true を、そうで無ければ false を返す関数を実装しなさい
  32. ★★void my_toupper(char *str) 引数の文字列中の英小文字('a' ~ 'z')を英大文字('A' ~ 'Z')に変換しなさい。
  33. ★★void my_toggleCase(char *str) 引数の文字列中の英大文字('A' ~ 'Z')を英小文字('a' ~ 'z')に、小文字を大文字に変換しなさい。
  34. ★★ int my_pop_front(int *first, int *last) first から last 直前までデータがある時、先頭データを削除し、それ以降のデータを前に移動し、削除した値を返す関数を実装しなさい。 first >= last の場合は、何も処理をせず、-1 を返しなさい。
  35. ★★ void my_push_front(int *first, int *last, int data) first から last 直前までデータがある時、データをひとつずつ後ろにずらし、データ先頭に data を代入する関数を実装しなさい。 ただし、データを挿入しても、データ領域サイズは増加しない(last の指す先のデータは変化しない)ものとする。 first <= last と仮定してよい。
  36. ★★★void my_strmix(char *dst, const char *src1, const char *src2) src1 の内容と src2 の内容を交互に dst にコピーする関数(例:src1 = "abc" , src2 = "123" ならば、dst = "a1b2c3")を実装しなさい。 src1 と src2 の長さが異なる場合は、余った文字列を単に後ろに追加しなさい(例:src1 = "abc" , src2 = "1" ならば、dst = "a1bc")。 dst には充分な領域が確保されていると仮定してよい
  37. ★★★char *my_strdup(const char *src) 引数に文字列をとり、その文字列分のメモリを確保し、そこに元の文字列をコピーし、 確保したメモリの先頭アドレスを返す関数を実装しなさい
  38. ★★★char *my_strdup2(const char *src) 引数に文字列をとり、 その文字列数*2個分のメモリを確保し、そこに元の文字列を各文字を2文字にしてコピー(例:"abc" → "aabbcc")し、 確保したメモリの先頭アドレスを返す関数を実装しなさい
  39. ★★★char *my_strleft(const char *src, int n) メモリを new でアロケートし、そこに src の先頭 n バイトをコピーして返しなさい。 n が src の文字数より多い場合は、src の文字数までをコピーしなさい。
  40. ★★★int my_strcmp(const char *lhs, const char *rhs) 文字列 lhs、rhs の中身の文字を文字コード順比較し、 lhs の指す文字列の方が rhs より小さければ -1 を、lhs と rhs の指す文字列が同じなら 0 を、lhs の指す文字列の方が rhs より大きければ 1 を返す関数を実装しなさい。
  41. ★★★const char *my_strstr(const char *text, const char *pat) 引数に 文字列 text、pat をとり、 文字列 text 中に文字列 pat があれば、その位置へのポインタを返す関数を実装しなさい。文字列中にpatが無い場合は0を返しなさい。 pat が空文字列の場合は常に text を返しなさい
  42. ★★★bool my_ends_with(const char *text, const char *pat) pat の長さが len の時、text の末尾 len 文字が pat に等しければ true を、そうで無ければ false を返す関数を実装しなさい
  43. ★★★int my_atoi(const char *str) str の先頭が数字列であれば、それを10進数に変換した値を返す関数を実装しなさい(例:"123" の場合は 123 を返す)。 str の先頭が数字で無い場合は -1 を返しなさい。
  44. ★★★★void my_strins(char *dst, int ix, const char *src) 引数に 文字列 dst, 文字列 src をとり、src を dst の ix の位置に挿入する関数を実装しなさい。 ix がマイナスだった場合は先頭に src を挿入しなさい。ix が dst の文字数以上の場合は末尾に src を挿入しなさい。
  45. ★★★★void my_strdel(char *str, int ix, int sz) 文字列 str の ix 番目から sz 文字を削除する関数を実装しなさい。 sz が大きい場合、str の文字列を超えて削除しないよう注意しなさい。 ix がマイナスだった場合、sz が0以下だった場合は何も処理をしなくてよい。 ix が str の文字数以上だった場合も何も処理をしなくてよい。
  46. ★★★★char *my_strright(const char *src, int n) メモリを new でアロケートし、そこに src の末尾 n バイトをコピーして返しなさい。
  47. ★★★★char *my_strmid(const char *src, int ix, int n) メモリを new でアロケートし、そこに src の ix 番目から n バイトをコピーして返しなさい。 ix が src 文字数より大きい場合は空文字列を返しなさい。
  48. ★★★★int my_atohex(const char *str) str の先頭が16進数文字列('0'~'9', 'A'~'F', 'a'~'f')であれば、それを16進数に変換した値を返す関数を実装しなさい(例:"1f" の場合は 31 を返す)。 str の先頭が16進数文字列で無い場合は -1 を返しなさい。
  49. ★★★★void my_memmove(char *dst, const char *src, size_t n) src から始まる n バイトを dst が指しているところにコピーしなさい。 ※ 通常の文字列の様に、データの途中にヌル文字があっても、そこで終了とみなさなくてよい。 n が 0 の場合は何もしなくてよい。 dst と src の領域が重なっていても正しく動作するようにしなさい。
  50. ★★★★★void my_replace(char *buf, const char *before, const char *after) 文字列 buf 中の文字列 before を全て after に置換する関数を実装しなさい。buf には充分な容量があると仮定して良い。

 


前: |上:C/C++ ポインタ入門 |次:

Copyright (C) 2013 by N.Tsuda, All Rights Reserved.