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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C

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

ポインタ

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

配列

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

Q&A

解決済

3回答

855閲覧

*s とs の使い分け

lawson.aic

総合スコア18

C

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

ポインタ

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

配列

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

0グッド

0クリップ

投稿2017/09/16 05:17

*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;
}

よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

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

これは、よく勘違いしますv^^;中身をインクリメントするには(*s)++;ですね。

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

・・・単体(左辺値がない)では*sは意味がないのでsを次のアドレスに進めるだけです。
*s++ == chは意味があって、sの中身(*s)とchを比較した後sを次のアドレスに進めます。

投稿2017/09/16 10:26

編集2017/09/16 10:27
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lawson.aic

2017/09/17 00:04

返信ありがとうございます。 つまり、*s = str[0] = 0の時、 if(*s++ == ch)における*sは値で0を取り出して評価後インクリメント(次のアドレスへ)。 s++にすると、sはアドレス値で、評価後インクリメント(次のアドレスへ) 。 つまり評価される値が違う。ということでしょうか?
cateye

2017/09/17 00:28 編集

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

2017/09/17 04:46

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

0

こんにちは。

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

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

例えば、

C

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

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

投稿2017/09/16 05:22

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2017/09/16 08:28

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

2017/09/17 00:10

返信ありがとうございます。 ・ポインタの指す要素を、単純に1個後方の要素に更新したい時。 →値を取り出す必要がないのでs++; (*s++でも問題はないが、意味がない) という理解であっていますか?
Chironian

2017/09/17 03:34

その通りです。
lawson.aic

2017/09/17 04:47

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

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']++;
}
としたらできるかな。

投稿2017/09/17 09:08

a_saitoh

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問