c言語のポインタについて質問です。
c言語のポインタについて質問です。
この問題の解答を教えてください(できれば解説も)よろしくお願いします。
①文字列のポインタを引数とし、その文字列を最後の文字から初めまで逆順に表示する関数print_rev を作成せよ。
②2 個の文字列のポインタを引数として、それらを比較して、最初に異なる位置(0以上の整数)を返す関数str_diff_point を作成せよ。ただし、それらが、一致したときは-1 を返すこととする。
③2 個の文字列のポインタを引数とし、第2の文字列が第1のポインタの指す文字列に含まれているときは最初のポインタを返す関数strsearch を作成せよ。ただし、見つからないときはNULL を返すこととする。
①文字列のポインタを引数とし、その文字列を最後の文字から初めまで逆順に表示する関数print_rev を作成せよ。
②2 個の文字列のポインタを引数として、それらを比較して、最初に異なる位置(0以上の整数)を返す関数str_diff_point を作成せよ。ただし、それらが、一致したときは-1 を返すこととする。
③2 個の文字列のポインタを引数とし、第2の文字列が第1のポインタの指す文字列に含まれているときは最初のポインタを返す関数strsearch を作成せよ。ただし、見つからないときはNULL を返すこととする。
Re: c言語のポインタについて質問です。
①のみです!お役に立てば幸いです←
l;print_rev(char*s){s+=l=strlen(s);while(l--)putchar(*--s);}
l;print_rev(char*s){s+=l=strlen(s);while(l--)putchar(*--s);}
最後に編集したユーザー ookami on 2011年5月27日(金) 12:44 [ 編集 1 回目 ]
Re: c言語のポインタについて質問です。
一応ライブラリ等を使わない形で
// ①文字列のポインタを引数とし、その文字列を最後の文字から初めまで逆順に表示する関数print_rev を作成せよ。
void print_rev(char* str)
{
// 最終地点の検索
int i;
for(i = 0 ; i < 99 ; i++){
if(*(str+i) == '\0')break;
}
// 逆に表示
for(int n = i ; n >= 0 ; n--){
printf("%c", *(str+n));
}
printf("\n");
}
//②2 個の文字列のポインタを引数として、それらを比較して、最初に異なる位置(0以上の整数を返す
//関数str_diff_point を作成せよ。ただし、それらが、一致したときは-1 を返すこととする。
int str_diff_point(char* s1, char* s2)
{
int ret = 0;
for(;;){
if(*(s1+ret) == '\0' && *(s2+ret) == '\0')break;
if(*(s1+ret) == '\0' || *(s2+ret) == '\0')return ret;
if(*(s1+ret) == *(s2+ret))ret++;
else return ret;
}
return -1;
}
//③2 個の文字列のポインタを引数とし、第2の文字列が第1のポインタの指す文字列に含まれているときは最初のポインタを返す
//関数strsearch を作成せよ。ただし、見つからないときはNULL を返すこととする。
char* strsearch(char* s1, char* s2)
{
// s1の中にs2があるか検索
for(int i = 0 ; *(s1+i) != '\0' ; i++){
if(*(s1+i) == *(s2+0)){
int j;
for(j = 0 ; *(s1+i+j) == *(s2+j) ; j++){
if(*(s1+i+j) == '\0')return NULL;
}
if(*(s2+j) == '\0')return (s1+i);
}
}
return NULL;
}
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: c言語のポインタについて質問です。
よく見ていなくて、すみませんでした。calloc で余分に領域を確保しているんですね。かずま さんが書きました:先頭文字のひとつ前を参照してはいけませんし、そこに '\0' があるとも限りません。
Re: c言語のポインタについて質問です。
正しいご指摘だと思いますよ。関数の仕様にはそんな前提条件は書かれていませんからね。かずま さんが書きました:よく見ていなくて、すみませんでした。calloc で余分に領域を確保しているんですね。かずま さんが書きました:先頭文字のひとつ前を参照してはいけませんし、そこに '\0' があるとも限りません。
いくら使用例でcalloc で余分に領域を確保していても、仕様は満足しません。
print_rev関数の型はintでしょうか?省略せずに書いた方がよいと思います。
Re: c言語のポインタについて質問です。
l;print_rev(char*s){s+=l=strlen(s);while(l--)putchar(*--s);} // ookami 60byte
print_rev(char*s){for(s+=strlen(s);*--s;putchar(*s));} // bitter_foxさん 54byte (難あり)
print_rev(char*s){*s?print_rev(s+1),putchar(*s):0;} // かずまさん 51byte
今のところ、かずまさんのコードが一番短いですね!
再帰や三項演算子をフツーに使ってきてるあたり、手馴れた感が...w
print_rev(char*s){for(s+=strlen(s);*--s;putchar(*s));} // bitter_foxさん 54byte (難あり)
print_rev(char*s){*s?print_rev(s+1),putchar(*s):0;} // かずまさん 51byte
今のところ、かずまさんのコードが一番短いですね!
再帰や三項演算子をフツーに使ってきてるあたり、手馴れた感が...w
Re: c言語のポインタについて質問です。
短けりゃいいってもんではないでしょう。可読性のほうが重要です。ookami さんが書きました:l;print_rev(char*s){s+=l=strlen(s);while(l--)putchar(*--s);} // ookami 60byte
print_rev(char*s){for(s+=strlen(s);*--s;putchar(*s));} // bitter_foxさん 54byte (難あり)
print_rev(char*s){*s?print_rev(s+1),putchar(*s):0;} // かずまさん 51byte
今のところ、かずまさんのコードが一番短いですね!
再帰や三項演算子をフツーに使ってきてるあたり、手馴れた感が...w
その点ではookamiさんのコードのほうが好ましいと考えます。(変数 l が関数ローカルでないのがいただけませんが。)
文字列処理で1文字につき1回再帰呼び出しを使うのはどうなんでしょうか。再帰構造は確かにスマートですが、コストがかかります。そのことをわかって使うのならばいいでしょうが、知らずに使うと痛い目にあいます。
Re: c言語のポインタについて質問です。
難読コードは丸投げ連投をこらしめるためじゃないんですかね。
#この投稿も無粋だと思いましたが。
#この投稿も無粋だと思いましたが。
Re: c言語のポインタについて質問です。
私もそんなところだろうと思っているんですが、そのコードがいかにも優れているかのようなコメントには賛成いたしかねます。初心者がこれを見てこんなコードがいいんだと思われても困りますからね。ISLe さんが書きました:難読コードは丸投げ連投をこらしめるためじゃないんですかね。
Re: c言語のポインタについて質問です。
> その点ではookamiさんのコードのほうが好ましいと考えます。
maruさんはookamiさんのコードの可読性が良いとお考えなのですね。
初心者がこれを見てこんなコードがいいんだと思っても構わないと。
maruさんはookamiさんのコードの可読性が良いとお考えなのですね。
初心者がこれを見てこんなコードがいいんだと思っても構わないと。
Re: c言語のポインタについて質問です。
No.4 の jaken さんのプログラムについては誰も何も言わないのでしょうか?
(1) なぜか文字数に 99 の制限がある。
逆順文字列の前後に勝手に '\0' と '\n' をつける。
(2) とりあえず仕様どおりには動きそうですが、無駄が多い。
(3) strsearch("abc", "bc") が NULL を返す。
真面目に書けばこんなところでしょうか。
(1) なぜか文字数に 99 の制限がある。
逆順文字列の前後に勝手に '\0' と '\n' をつける。
(2) とりあえず仕様どおりには動きそうですが、無駄が多い。
(3) strsearch("abc", "bc") が NULL を返す。
真面目に書けばこんなところでしょうか。
void print_rev(const char *s)
{
int i = 0;
while (s[i] != '\0') i++;
while (--i >= 0) putchar(s[i]);
}
int str_diff_point(const char *s1, const char *s2)
{
int i;
for (i = 0; s1[i] == s2[i]; i++)
if (s1[i] == '\0') return -1;
return i;
}
char *strsearch(const char *s1, const char*s2)
{
do {
const char *p1 = s1, *p2 = s2;
do {
if (*p2 == '\0') return (char *)s1;
} while (*p1++ == *p2++);
} while (*s1++);
return NULL;
}
Re: c言語のポインタについて質問です。
どうもすいません、ookamiです。
コードゴルフを演出して余計な刺激を生んでしまい、申し訳ないです。
「こらしめる」というほど立派なことは考えていませんでしたが、
フォーラムルールにも「丸投げはNG」とあるので、
「直球で模範解答を返しちゃいけないだろうなぁ」くらいには思っていました。
それで、思いつき的にコードゴルフを始めてしまいました。すいません。
「可読性の方が重要」かどうかは、場合によりけりかと思いますし、
もちろん、最初に私が投稿したコードも「読みやすい」とは思っていません。
バグさん・bitter_foxさん・jakenさん・かずまさんのコードについても、特に批評を書くつもりはないです。
質問者のakatukiさんからの返事がまだですが、
丸投げが公然と認められている掲示板もありますから、
もうそちらで解決しているかもしれませんし、
私は、このトピックは「この辺でおひらき」でもいいかなぁと思っています。
ただ、「真面目に書くなら」といった流れもありますので、
そこは続けてもいいかもしれませんね?
コードゴルフを演出して余計な刺激を生んでしまい、申し訳ないです。
「こらしめる」というほど立派なことは考えていませんでしたが、
フォーラムルールにも「丸投げはNG」とあるので、
「直球で模範解答を返しちゃいけないだろうなぁ」くらいには思っていました。
それで、思いつき的にコードゴルフを始めてしまいました。すいません。
「可読性の方が重要」かどうかは、場合によりけりかと思いますし、
もちろん、最初に私が投稿したコードも「読みやすい」とは思っていません。
バグさん・bitter_foxさん・jakenさん・かずまさんのコードについても、特に批評を書くつもりはないです。
質問者のakatukiさんからの返事がまだですが、
丸投げが公然と認められている掲示板もありますから、
もうそちらで解決しているかもしれませんし、
私は、このトピックは「この辺でおひらき」でもいいかなぁと思っています。
ただ、「真面目に書くなら」といった流れもありますので、
そこは続けてもいいかもしれませんね?