2017-03-04 11 views
4

私は相対的にコーディングが新しく、配列との組み合わせでポインタがどのように機能するかを理解するのに問題があります。C++でのchar配列へのポインタの使用

私はそれは次のようにポインタの配列を作成することが可能だということを理解:

#include <iostream> 
using namespace std; 

int main() { 
    char *names[4] = { 
     "name A", 
     "name B", 
     "name C", 
     "name D" 
}; 

for (int i = 0; i < 4; i++) { 
    cout << names[i] << endl; 
} 
return 0; 
} 

なぜそれは私が複数割り当てることができるということ、である:私は、次のコードを見つけ

チュートリアルで
#include <iostream> 
using namespace std; 

int main() { 
    int i; 
    int *pArr[10]; 
    pArr[0]=&i; 
    return 0; 
} 

charを指すポインタに "name A"のような文字列を指定することができます。

は私ではないはずです。

は、私だけが作成されたもの4つのポインタのそれぞれに文字のアドレスを割り当てることができます。

そしてB:のみ

各々に、一つの文字(CHAR)に、ポインタを割り当てることができます。

誰かが私の混乱をある程度解消してくれることを願っています。

+1

''名前A "'の型は実際には 'const char *'です。 –

+1

1. 'const' 2を読んでください。' 'std is bad'' - googleも同様です。 –

+0

ここで便利なコンパイラの警告を見てください:http://coliru.stacked-crooked.com/a/f67971a42cebd76f –

答えて

1

各char *は、文字列の最初の文字を指します。リテラル文字列 "mystring"が埋め込まれているのを見ると、char *は "mystring"の "m"を指しています。

coutコマンドは、char *変数を渡すと、0バイト(2進値0、書き込み文字 "0"ではなく)になるまで、そのメモリアドレスから始まるすべての文字を出力するように構築されています。

この結果、実際にchar *ポインタをインクリメントして短い文字列を得ることができます。例えば"mystring"を指すポインタに1を加えると、 "ystring"を指すようになります。あなたの前提は基本的には正しかったので、char *は単語全体ではなく1文字を指しています。

3

C(およびC++)では、文字列リテラル("name A"などの式)は、タイプconst char*です。フードの下では、これらの文字列はバイナリのデータセクションのどこかに格納されます。文字列リテラルは、これらの文字の最初のものへのポインタで置き換えられます。だから、次の文

char *names[4] = { 
    "name A", 
    "name B", 
    "name C", 
    "name D" 
}; 

は、データセクションの4つの文字列を割り当てるために、その後、ポインタ配列namesに4つのポインタを割り当てるために、コンパイラに指示します。

+5

C++では、文字列リテラルは' const char * 'に代入できますが、Cでは' char * 'に代入することもできます。しかし、これは文字列リテラルの型ではありません。文字列リテラルは文字ポインタではなく、文字配列です。 – dasblinkenlight

+0

2番目に... 'std :: cout << typeid(" foo ").name()'はchar const [4]を出力します。正しい説明は文字配列であり、コンパイラは配列を最初の文字へのポインタで置き換えます。 – zett42

+0

文字列型は 'const char [7]'ではなく 'const char * 'です。配列からポインタのprvalueへの変換はいくつかのコンテキストでのみ発生します –

2

charへの4ポインタの配列を作成しました。

"文字列litteral"はcharの配列です。この配列のアドレスはcharへのポインタです。だからあなたの配列の配列に入れても問題はありません。

コードはコンパイルされますか?あるいは、char *とconst char *の混在について文句を言っていますか?これは、すでにたくさんの答えがある別の質問です。

+0

C++ 11より前では、文字列リテラルから 'char *' –

6

これはプログラマがコードに文字列を簡単に含めるためにコンパイラが提供するショートカットです。

あなたは"name A"リテラル文字列を書くとき、コンパイラはあなたのための7文字の配列を用意:

const char hidden0[] = {110, 97, 109, 101, 32, 65, 0}; // "name A" 

最初の6つの数字が文字列内のシンボルの文字コードに対応しています。最後の文字はゼロです。いわゆるヌルターミネータです。

コンパイラは、すべての4つの文字列リテラルについて同じことなので、あなたの配列初期化子は、次のようになります。

const char *names[4] = { 
    &hidden0[0], 
    &hidden1[0], 
    &hidden2[0], 
    &hidden3[0] 
}; 

hiddenKはリテラル文字列に対応するために作成された配列です。名前はありませんが、コンパイラはアドレスを知っていて、配列name[]に配置します。

関連する問題