掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.29762

「*p++」の読み方について
投稿者---あきき(2007/02/12 16:45:01)


「*p」と「++」の優先順位の捉えかたの問題と考えています。
例えば、次のようなプログラム(図1)の場合ですが、「++」の方が「*p」より
優先順位が高いとすれば、
 1 pをインクリメントする
 2 pのさすメモリ上の値を表示する
と考えていますが、結果は「abcde」と表示します。予想としては「bcde」でしたが。ところが、図2の場合ならば、予想通りの結果を得られます。
図1ではどのようにして「abcde」を導いかれたのでしょうか。

// 図1
#include <stdio.h>

int main( void )
{
    char *p = "abcde";

    while ( *p ) putchar( *p++ ); // ここが問題の部分
    putchar( '\n' );

    return 0;
}

// 図2
#include <stdio.h>

int main( void )
{
    char *p = "abcde";

    while ( *p++ ) putchar( *p ); // ここが問題の部分
    putchar( '\n' );

    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:「*p++」の読み方について 29763 jazz 2007/02/12 17:18:01
<子記事> Re:「*p++」の読み方について 29764 しっぽ 2007/02/12 17:20:10
<子記事> Re:「*p++」の読み方について 29777 病みつき面貌 2007/02/14 18:14:11


No.29763

Re:「*p++」の読み方について
投稿者---jazz(2007/02/12 17:18:01)


>「++」の方が「*p」より優先順位が高いとすれば、

この前提が正しくありません。
*p++は、pが指す領域を参照してからpをインクリメントする、という意味です。

【図1の場合】
*p == 'a'で、'\0'でないため、'a'を出力する。
pをインクリメントする。
*p == 'b'で、'\0'でないため、'b'を出力する。
pをインクリメントする。
(中略)
*p == 'e'で、'\0'でないため、'e'を出力する。
pをインクリメントする。
*p == '\0'になったので、ループから抜ける。

【図2の場合】
*p == 'a'で、'\0'でないため、pをインクリメントする。
pが指している'b'を出力する。
(中略)
*p == 'd'で、'\0'でないため、pをインクリメントする。
pが指している'e'を出力する。
*p == 'e'で、'\0'でないため、pをインクリメントする。
pが指している'\0'を出力する(目には見えない)。
*p == '\0'になったので、ループから抜ける。





この投稿にコメントする

削除パスワード

No.29764

Re:「*p++」の読み方について
投稿者---しっぽ(2007/02/12 17:20:10)


p++ と ++p の区別はできてますか?


#include <stdio.h>

#include <stdio.h>

int main( void )
{
    char *p = "abcde";

    while ( *p ){ 
        putchar( *++p ); // ここが問題の部分
    }
    putchar( '\n' );

    return 0;
}




この投稿にコメントする

削除パスワード

No.29765

Re:「*p++」の読み方について(解決)
投稿者---あきき(2007/02/12 17:51:49)


>p++ と ++p の区別はできてますか?
>
結合規則の勉強不足でした。てっきり、優先順位の問題とばかり考えていたんで。お蔭様で解決しました。
jazzさん、しっぽさん有難うございました。



この投稿にコメントする

削除パスワード

No.29767

Re:「*p++」の読み方について(解決)
投稿者---yoh2(2007/02/14 00:25:34)


>>「++」の方が「*p」より優先順位が高いとすれば、
>
>この前提が正しくありません。

前提、合ってると思います。
後置++と単項*では、後置++の方が優先度が高いです。( *p++ は *(p++) と同じ意味)
仮に逆だとすると、(*p)++と同じ意味になり、pではなく、pが指すもの('a'等)を
インクリメントしてしまいます。

>結合規則の勉強不足でした。てっきり、優先順位の問題とばかり考えていたんで。お蔭様で解決しました。

結合規則の問題でもないのですけれど。
演算子を適用した「結果(*)」と「副作用」とは独立した概念だという話です。
(*)式の一要素として持つ値のことです。JIS X 3010で「結果」と表現されていたので、
それに合わせました。

副作用を持つ演算子は「結果」と、副作用として新たにオブジェクトに格納される値が
一致している場合が多いのですが、後置の++と--は異なっているので、一風変わった
挙動になるわけです。

いくつかの演算子と並べて比較してみると、どういったことか見えてきませんか?

・a + b
結果:aとbの和
副作用:なし

・a = b
結果:aの型に変換したbの値
副作用:aの内容を、aの型に変換したbの値(「結果」と同じ)に書き換える

・++a
結果:aを1増やした値
副作用:aの内容を、aを1増やした値(「結果」と同じ)に書き換える

・a++
結果:aの持つ値(「副作用」適用前の値)
副作用:aの内容を、aを1増やした値(「結果」と異なる)に書き換える


この投稿にコメントする

削除パスワード

No.29768

Re:「*p++」の読み方について(解決)
投稿者---YuO(2007/02/14 01:08:59)


>>>「++」の方が「*p」より優先順位が高いとすれば、
>>この前提が正しくありません。
>前提、合ってると思います。
>後置++と単項*では、後置++の方が優先度が高いです。( *p++ は *(p++) と同じ意味)

ん?
*pがそもそもひとまとまりではないから,++と*pの優先順位を比べること自体が間違い,という話では?
# *と++を比べるべきであって,*pと++を比べるべきではない。


この投稿にコメントする

削除パスワード

No.29780

Re:「*p++」の読み方について(解決)
投稿者---yoh2(2007/02/14 21:59:00)


>*pがそもそもひとまとまりではないから,++と*pの優先順位を比べること自体が間違い,という話では?

単に「*」と書こうとして、「*p」としたのかな、と思ったのですが、そうすると、
「++」も、「p++」と書いていそうですね。

いやはや、変なことを言い出して申しわけない>jazzさん


この投稿にコメントする

削除パスワード

No.29777

Re:「*p++」の読み方について
投稿者---病みつき面貌(2007/02/14 18:14:11)


例えば・・・

    printf("%d", i++);

これは、
    printf("%d", i);
    i++; 

と同じことです。

次に、

    printf("%d", ++i);
これは、
    i++;
    printf("%d", i);

と同じことです。




この投稿にコメントする

削除パスワード

No.29841

Re:「*p++」の読み方について
投稿者---金魚ちゃん(2007/02/24 03:20:54)


まず『++』や『--』には前置後置の2つの動作があります。
前置…『*(++p)』は『*p』を参照する前にインクリメントをします。
後置…『*(p++)』は『*p』を参照した後にインクリメントをします。
また、『*p++』という記述は『*(p++)』です。⇒よって後置動作になります。

図1では『*p』を参照した後に『p++』を処理します。
よって『abcde』という表示結果になるのです。

図2では『p++』を処理した後に『*p』を処理します。
よって『bcd』という表示結果になるのです。⇒『bcde』ではないよ。

図3
#include <stdio.h>

int main( void )
{
    char *p = "abcde";
    
    while ( *p ) putchar( *(++p) );
    putchar( '\n' );
    return 0;
}

上記の方法ならば『bcde』という表示結果になります。
よって、前置後置のタイミングに注意して下さい。
以上。



この投稿にコメントする

削除パスワード

No.29850

Re:「*p++」の読み方について
投稿者---isshi(2007/02/26 21:52:59)


>後置…『*(p++)』は『*p』を参照した後にインクリメントをします。
インクリメントするのはあくまでも参照する前です。
p++はpをインクリメントし、その結果はインクリメントする前の値となります。(yoh2さんがすでに説明済みですが。)



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧