0
#include<stdio.h>
void main()
{
 char ***p="hello";
 printf("%c",++*p++);
}

(*)間接演算子がここで3回使用された理由がわかりません。

このプログラムをコンパイルすると、出力は「j」でした。しかし、実際には、pが文字の配列へのポインタへのポインタであると聞きます。次に、なぜ出力をjとして取得するのですか。私はこれの背後にある論理が何であるかを理解していませんでした。この背後にある実際のロジックを理解するのを手伝ってください。

そして、間接演算子を1つだけ使用してプログラムをコンパイルすると、混乱がさらに増します。その場合、出力はi.meansになります。

void main()
{
 char *p="hello";
 printf("%c",++*p++);
}
4

3 に答える 3

2

このコードには、Cコードとして意味のある出力はありません。コードは単に無効です。

まず、Cの関数void mainの有効な宣言ではありません。を返すものとして宣言する必要があります。mainmainint

第二に、char ***p="hello"初期化は無効です。char *文字列リテラルはCの型に減衰します。型の値をchar *使用して型のオブジェクトを初期化することはできませんchar ***

第3に、ポインターを逆参照するchar ***と、タイプがポインター値が生成されます。これは、フォーマット指定子を使用して-edするchar **ことはできません。printf%c

于 2012-07-23T18:49:38.613 に答える
1

まず、これは未定義の動作です。

第二に、それは正しいC(またはC ++)コードでもありません。非constcharポインターが原因で、この警告が生成されます。

3.c: In function 'main':
3.c:5:12: warning: initialization from incompatible pointer type [enabled by default]
  char ***p="hello";
            ^

この方法で行う方がよい:

#include <stdio.h>

int main()
{
    const char ***p="hello";
    printf("%c",++*p++);

    return 0;
}

そして、それが何を出力するかに関して:プログラムはランタイムに異常な方法でそれを終了するように要求しました。ただし、これは未定義の動作です。結果は異なる場合があります。

于 2012-07-23T17:05:34.490 に答える
1

複数の間接参照が使用された理由がわからないのは、ここでは複数の間接参照が意味をなさないためです。これは、このコードの多くの問題の1つにすぎません。

"hello"文字列リテラルであり、これは配列式でもあります。具体的には、「の6要素配列」であり、このコンテキストでは、 ;charへのポインタに変換(「減衰」)されます。として宣言する必要がありますcharp

char *p = "hello";

式は、物が指すもの(この場合は文字)++*p++をインクリメントしようとし、副作用として次の文字を指すように進みます。文字列リテラルを変更する動作は未定義です。プラットフォームによっては、文字列リテラルが書き込めない場合があり、式がアクセス違反につながる可能性があります。 php++*p++

以下は、上記のプログラムの修正バージョンであり、意図した結果が得られます。

#include <stdio.h>

int main(void)
{
  char h[] = "hello";
  char *p = h;
  printf("%c\n", ++*p++);
  return 0;
}

p文字列リテラルを指す代わりに、文字列リテラルの内容で初期化されたローカルバッファを指すようにします。

于 2012-07-23T18:27:13.827 に答える