2017-10-04 19 views
-4

は私が書いた:私はそれをコンパイルするとき文字列をcharに代入するとどうなりますか?

char ch = "ABC"; 

は今、私はすべてのエラーを取得していませんよ。しかし、これらの文字を個別に表示するか、文字列全体を一度に表示しようとすると、そのようにしようとするたびにプログラムがクラッシュするため、できません。

このプログラムでは何が起こっていますか?

+1

どのコンパイラを使用しますか?あなたのプラットフォームは何ですか? –

+0

これは、どのコンパイラでも少なくとも警告でなければなりません。あなたはどんな旗を使っていますか?あなたはプログラムのクラッシュでどんな出力を得ますか? –

+2

コードが間違っていることが分かっている場合は、コンパイラが何をしているか心配する必要はありません。コードを修正してください!そして、警告をオンにしてください。 –

答えて

3

通常、少なくとも現実的なコンパイラでは、明示的なキャストなしに変換が行われないため、エラーメッセージが表示されます。

しかし、私たちがコンパイラに汚れた行為を強制する場合、どういうことが起こるかを考えてみましょう。変換を強制するキャストを含むプログラムを考えてみましょう。は、実際にはもっとはっきりとしたことを実現するいくつかのことを行います(私は思っています)。

#include <stdio.h> 

int main() { 
    char const *s = "ABC"; 

    int i = (int)s; 
    unsigned char c = (unsigned char)s; 

    printf("%p\n%8x\n%8x\n", s, i, c); 
} 

(Iは、ビット7ポインタを設定する発生した場合、単純に符号拡張されてから値を防ぐためにunsigned char代わりにcharを使用しました)。

私はここから取得する出力は次のようになります。

0x4005f4 
    4005f4 
     f4 

それでは、ここで起こっていることは"ABC"は、我々は(他の可能性の中)(定数)へのポインタを初期化するために使用できる文字列リテラル、ということですchar。これをvoidへのポインタに変換すると、文字列リテラルが格納されているアドレスを見ることができます(注:コンパイルすると、取得するアドレスは異なる可能性があります)。

このアドレスを符号なし整数に変換すると、同じ値が得られます。これは標準によって保証されているわけではありませんが、ほとんどの典型的なケースではあなたが目にしそうなものです。

最後に、ポインタをcharに変換します。これを16進数で表示すると、アドレスの最下位8ビットを保持していることがわかります。再び、正確に8ビットであることは標準では保証されていませんが、それはかなり典型的なサイズのcharです。

免責事項:私が示したような結果が期待できますが、ほとんど保証されていません。 voidへのポインタの出力はサポートされていますが、使用される正確なフォーマットはコンパイラ/ライブラリに依存します。同様に、整数型に変換された結果は完全には保証されていませんが、最も一般的なコンピュータ/コンパイラの実装では、上に示したものと同様の結果が得られます。

ボトムライン:charに割り当てられた値は、通常、文字列リテラルを格納するために割り当てられたアドレスの最下位8ビットになります(本質的に役に立たない)。

+0

@ 4386427:フェアポイント。修正されました。 –

関連する問題