-3

私はこの質問に来て、この行を見ます

printf(&c[i]);  

知りたいのですが、これは有効な構文ですか? 書式指定子なしで文字列/文字列リテラルを出力しても、未定義の動作制約違反%sは発生しませんか? そして、これが有効な構文である場合、どのような目的で使用されますか?

このコードをコンパイルしました

#include <stdio.h>

int main()
{
    char *c = "Hello World";

    printf(c);
    printf("\n\n");
    printf(&c[0]);

    return 0;
}  

そして、出力で警告/エラーを出さずにコンパイルします

Hello World

Hello World
4

5 に答える 5

3

これは賢明ではありませんが (特に、文字列がユーザーからのものである場合)、違法ではありません。

問題の条項は、セクション 7.19.6.1、パラグラフ 3 (強調は私のもの) です。

フォーマットは、初期シフト状態で開始および終了するマルチバイト文字シーケンスでなければなりません。形式は、0 個以上のディレクティブで構成されます。通常のマルチバイト文字 (% ではない)。変更されずに出力ストリームにコピーされます。それぞれの結果として、後続の 0 個以上の引数がフェッチされ、該当する場合は、対応する変換指定子に従って変換され、結果が出力ストリームに書き込まれます。

fputs(c);またはを使用fprintf("%s", c);して、文字列が誤ってディレクティブを含むと解釈されないようにする必要があります。

于 2013-12-05T12:45:06.000 に答える
1

動作しますが、お勧めしません。あなたが持っていたとしましょう

char *c = "We have a 30%sale!";

次に、printfステートメントは、を解決しようとしてガベージメモリにアクセスします%s

于 2013-12-05T12:46:24.940 に答える
0

c文字列の先頭へのポインタであるため機能します(つまり、文字列の最初の記号へのポインタです)。c[0]char を許可しWます。そして&、これを指してみましょうchar。コードで使用したような構造は、ポインターによって値を取得し、すぐにこの値のポインターを返します。たとえば、c[i]に等しい*(c+i)です。

なぜそれが機能するのですか?printf()関数は文字列へのポインタを引数として受け取るためです。そして、ポインターから'\0'符号までのすべての符号を出力します。

C言語のポインターと、C配列とC文字列の実装方法について詳しく学んでください。

于 2013-12-05T14:05:54.870 に答える