質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • C

    3455questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • 配列

    490questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

  • ポインタ

    99questions

    ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

*s とs の使い分け

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 244

lawson.aic

score 8

*s++,s++,それぞれの使い分けてる意味を知りたいです。

下記は、とある書籍の問題です

これは文字列sに含まれている数文字'0'~'9'の個数を、cnt[0]~cnt[9]に格納する関数です。

void cnt_digit(const char *s, int cnt[])
{
int i;
for (i = 0; i < 10; i++)
*(cnt + i) = 0;

while (*s) {
if (*s >= '0' && *s <= '9')
cnt[*s - '0']++;
s++;
}
}

s++でs[0]からs[1]へずらしていくのは分かりますが、*s++ではいけないのでしょうか?

*s++ = *sの値に1を加える。
s++ = 配列sの要素を1個後方を指すように更新。
・・・?

*s++としても正常に動作しています。

他の例題で、*s++としているケースもあり、それぞれどのような意味で使い分けているのかわからなくなりました。

//文字列sに含まれる文字chを探索
int str _char(const char *s, int ch)
{
int idx = 0;

while (*s) {
if(*s++ == ch)
return idx;
idx++;
}
return -1;
}

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+2

*s++ = *sの値に1を加える。

これは、よく勘違いしますv^^;中身をインクリメントするには(*s)++;ですね。
>*s++としても正常に動作しています。
・・・単体(左辺値がない)では*sは意味がないのでsを次のアドレスに進めるだけです。
*s++ == chは意味があって、sの中身(*s)とchを比較した後sを次のアドレスに進めます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/17 09:04

    返信ありがとうございます。

    つまり、*s = str[0] = 0の時、

    if(*s++ == ch)における*sは値で0を取り出して評価後インクリメント(次のアドレスへ)。

    s++にすると、sはアドレス値で、評価後インクリメント(次のアドレスへ)


    つまり評価される値が違う。ということでしょうか?

    キャンセル

  • 2017/09/17 09:26 編集

    概ねそういう解釈でいいと思います。
    >評価される値が違う
    *sを意味がないと書いたのは、sのさす値を*sとして取り出すのですが、格納先(左辺値)がない(ch= *s++;と書いた場合は、左辺値がある)のでただ捨てられるだけなので評価されない(何か語弊がでそうですがw)で、s++だけが実行される。 

    キャンセル

  • 2017/09/17 13:46

    噛み砕いた説明で分かりやすかったです。ありがとうございました!

    キャンセル

+2

こんにちは。

*s++ = *sの値に1を加える。

この理解が間違いです。これは*sの値を取り出してから、sをインクリメントします。

例えば、

int t[]={1, 2, 3};
int* s=t;


の時、*sはt[0]なので1ですね。
*s++の値は1で、*s++の式の処理後、sはt[1]を指します。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/16 17:28

    というように純粋なポインタ演算は可読性がないので、シンタックスシュガーである[]演算子を使うべきだという思い。

    キャンセル

  • 2017/09/17 09:10

    返信ありがとうございます。

    ・ポインタの指す要素を、単純に1個後方の要素に更新したい時。

    →値を取り出す必要がないのでs++; (*s++でも問題はないが、意味がない)

    という理解であっていますか?

    キャンセル

  • 2017/09/17 12:34

    その通りです。

    キャンセル

  • 2017/09/17 13:47

    的確な説明で理解が深まりました。
    ありがとうございました。

    キャンセル

0

なぜ*s++にしていないかというと、そうしても良い *sがないから。

whileループを1回まわるごとにsを一回インクリメントする必要があります。
if()の括弧の中には2回*sが出てくるのでここに++は入れられません。どっちにしても次の行のcnt[*s・・でsを使うのでまだインクリメントしてはいけない。

cnt[*s - '0']++; はif文の中なので「1周ごとに1回++」になりません。

なので、独立したs++となっています。

これを
s--;
while(*++s){...}
としても動きますが、トリッキーで読みにくいし、一旦はsが文字列外を指すタイミングが出来てしまうんでNG。

僕は、whileループ最後のs++をforの第3項に移す方が好みですが…・
for(;*s;s++){...}

どうしても*s++をつかいたければ
int c=*s++;
if ( isdigit(c)) cnt[c - '0']++;
}
としたらできるかな。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    C++ エラーがたくさんでて困っています。。デバッグを助けてください。。

    以下のコードを書いたのですが思い通りに動きません。。 デバッグを教えてほしいです。。 #include <iostream> #include <string.h> usin

  • 解決済

    C言語で指定文字列でポインタ配列を分割したい

    ポインタ配列内の文字列を改行2回が来たならば、そこを境にbuf2に入れたいのですがうまくいきません なぜか、buf2にbuf1の2行目だけ入ってしまっています どうしたらいいのでし

  • 解決済

    英文ファイルを表示

    ある英文が与えられたファイルがあり,それを所有格や空白記号類を削除し単語一つ一つを改行して表示していくプログラムを考えています. 実行結果の例としては This is a pen.

  • 解決済

    ポインタ渡しと文字列比較

    C言語初心者です。 文字列rawcがリストlistの中に入っていない(登録されていない)とき、 その文字列をリストの登録されている最後に格納する関数regを作成しました。 既に登

  • 受付中

    整数の繰り返し入力

    整数を繰り返し入力し、0 を入力したら、それまでに入力した整数の合計と個数を出力(表示)するプログラムを改造し、 t を入力したら、それまでに入力した数値の合計を出力(表示)して終

  • 解決済

    エラーメッセージの意味が分からない

    発生している問題・エラーメッセージ 文字列配列を辞書順にソートしてから表示するプログラムです。エラーメッセージは恐らく、無効な引数(型がint) のような内容が書いてあると思うの

  • 解決済

    c言語学習中の学生です。

    前提・実現したいこと c言語を学んでいる学生です。 非常に低レベルな質問ですがお願いします。 Windows10でmingwを使っています。 発生している問題・エラーメッセージ

  • 解決済

    C言語の線型散策(逐次散策)

    C言語の線型散策(逐次散策)の質問です。 以下の演習がうまく行きません。 ご教授ください。 【要素数nの配列v内のkeyと等しい全要素の添字を配列idxに格納する関数searc

同じタグがついた質問を見る

  • C

    3455questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • 配列

    490questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

  • ポインタ

    99questions

    ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。