2017-04-23 7 views
0
#include <stdio.h> 

const int MAX = 4 

int main() { 

    char *names[] = { 
     "Zara Ali", 
     "Hina Ali", 
     "Nuha Ali", 
     "Sara Ali" 
    }; 

    int i = 0; 

    for (i = 0; i < MAX; i++) { 
     printf("Value of names[%d] = %s\n", i, names[i]); 
    } 

    return 0; 
} 

なぜ一つがちょうどnames[i]代わりの*names[i]を印刷することができますか?誰かが説明のためにメモリダイアグラムを提供できますか?のChar *配列の混乱

+2

[コードまたはエラーメッセージの画像を投稿しないでください](http://meta.stackoverflow.com/q/303812/1679849) –

答えて

2

フォーマット指定子%sは、タイプ(char*)のパラメータ、つまり文字の配列へのポインタを必要とします。

char* names[]では、各要素はchar型の配列へのポインタです。あなたの初期化の後、names[0]は文字列リテラル"Zara Ali"の先頭を指すメモリアドレスを保持します。したがって、引数としてこのようなポインタをprintf("%s", ...)に渡すのは正しいです。

ただし、*names[0]と書くと、実際にこのポインタが参照解除され、char値(この場合は)が生成されます。これは、という予想されるデータ型と実際のデータ型がcharと一致しないため、コンパイラの警告が表示され、それらを完全に無視すると、printf("%s", 'Z')と同じ結果になります。

0

メモリダイアグラムが必要ないと思います。

*が付いているものは、メモリ内のポインタです。

ので、

int *a = 3; 

a = 3; 
*a = memory address 

printf("result = %d, result 2 =%d\n", a, *a); 

出力:

result = 3, result 2 = 9023923 (this is a random memory address) 

あなたはこれを暗記しなければなりません!

+0

これはintの仕組みを理解していますが、私はちょうど混乱していますchar *配列 – user7518095

-1

*[]に含まれているためです。 Array subscriptingを見てください :

添字演算子[]の定義は、E1 [E2]が(*((E1)+(E2)))

0

charがあると同一であることです単一8ビット文字、我々は単一の文字列のために、我々は

char * name 

は名前がmに含ま意味使用して、最初の文字のアドレスを使用している未知の長さのchar型の配列を持つことにより、C言語で文字列を表します最初の文字のemoryアドレス(ポインタ)、メモリアドレス、+ 1を単にインクリメントすることによって、2番目のcharに到達することができます。 私たちが望む場合は、文字列の配列が、私たちが実際に行うことはそう

char * names[] = ... 

は、文字列の最初の文字へのポインタの配列である、あなたがする必要がある、複数の文字列を持っており、メモリアドレス(ポインタ)の配列でありますc配列の要素数を指定しますが、値を指定しているため、コンパイラは要素数を推測できます。

あなたがメモリ内のどこにでも配置することができる名の各要素とを指し示す各​​ストリングは、メモリアドレスのそのわずかアレイ、名[0] 10000と名に等しいとすることができる[1]可能性10の場合、文字列0がアドレス10000で開始し、文字列1がアドレス10で始まることを意味しますが、宣言した方法でコンパイラーがメモリ内に順番に並べ替える可能性が高いため、後で割り当てることができますいずれかの値とは異なるメモリアドレス。

names[2] = "New Values"; 

名の値[2]は次に、「新しい値」が存在し、元の​​文字列、「Nuhaアリ」は、まだその時にメモリに配置されたメモリ内の別の場所であろう元の場所は手つかず。

あなたがそう

char  names[] = "Zara Ali\0Hina Ali\0... 

その後、は、文字列全体を含むように十分な長さに作成され、文字列ではなく、最初の文字の配列にコピーされますようにchar型の配列を作成した可能性が望んでいた場合配列にコピーされる各文字列のメモリアドレス。 名前は、文字列と名前の1つの配列を指し示します。[1]は2番目の文字を返します。文字列の終わりを特定することができず、str関数は文字列が最初の ' \ 0 'となります。

(注意:あなたのコンパイラは実際に文字列ターミネータ '\ 0'を中間文字列に置くことはできませんが、試していませんが、それが合法でなければならないと思いますが、メモリはレイアウトすることができます)。

+0

文字列が最初の '\ 0 'で終了するという仮定はありません。これは_definition_([C11§7.7.7/ 1](http://port70.net/~nsz/c/c11/n1570.html#7.1.1p1))によって真実です。また、 '' Zara Ali \ 0Hina Ali \ 0 "'は文字列ではなく文字列リテラルです。文字列リテラルは文字列である必要はありません([C11§6.4.5](http://port70.net/~nsz/c/c11/n1570.html#note78))。しかし、埋め込まれた '\ 0'文字は合法です。 –

+0

printf( "%s \ n"、 "abc \ 0def")はabcとstrcmp( "abc \ 0def"、 "abc")== 0を出力します。 –