2017-06-11 10 views
-1

私はちょうどCの学習を始め、ポインタのコンセプトの周りを頭で覆うのはかなり難しいと思っています。Cポインタの概念

私はこのコードサンプルを見つけました。

以下の声明は何を意味していますか? Char * s_item [20];

char * s_itemは文字ポインタを意味するので、文字列を割り当てたり文字列をコピーしたりする前にメモリを割り当てる必要があります。文字列の先頭アドレスを格納するだけです。

次に、このステートメントは何を意味しますか。 s_item =(char(*)20)calloc(30,20);

最後に、誰かが私にchar **値の概念を説明することができます 私はそれがポインタへのポインタであることを知っています。しかし、どのような価値が私たちはそれに正確に保存することができます。それは文字列のコレクションですか?

+1

'(char(*)20)'は実際に何も意味しません。あなたは '(char(*)[20])'を意味しましたか? – Ruslan

+0

@Ruslanはい、それは私が意味するものです。タイプミスで申し訳ありません。 – redsoxlost

+1

@Olafそれはchar(* s_item)[20]です。私が言ったように、私はすでに本を読んできました。時には少しの助けが必要な場合もあります。 "私たち"はなく、あなたはstackoverflowではありません。 – redsoxlost

答えて

0
char *s_item[20]; 

上記の文は、「s_item」は配列であり、その要素は文字へのポインタであることを意味します。

s_item=(char(*)20)calloc (30,20); 

コードに問題があるようです。まず、(char(*)20)は強制的なキャストですが、私はそれが(char*)であるべきだと思います。第2に、char **にchar *を代入したいので、これは無効な代入です。

"calloc"は、動的メモリ割り当てのためのC関数です。この関数はa(void *)を返します。これは未知数へのポインタを意味します。ポインタはchar *へのポインタにキャストされます。ただし、s_itemは文字へのポインタへのポインタなので、s_itemに割り当てることはできません。第三の問題として

、可変ppのタイプがCHARである場合**、我々はppがポインタであることを意味する、ppのアドレスを格納することができます。 ppに格納されているアドレスは、文字を指す別のポインタのアドレスでなければなりません。したがって、ppは文字へのポインタへのポインタです。

+0

ありがとう。私は正しいように質問を編集しました。 – redsoxlost

3

the spiral/clockwise ruleについて知りたければ、charという20個のポインタの配列として解読できます。私。文字列の配列

(それはグローバル変数の場合)または各要素が初期化されていないことと、(s_itemがローカル変数の場合)不定値を持つことになります定義これは、各要素がnullポインタのどちらかになります場所に応じて。いずれにしても、既存の文字列をポイントするか、または初期化したメモリを動的に割り当てることによって、実際に使用する前に、配列ポイントの各ポインタを有効なデータにする必要があります。ポインタへのポインタについては


は、それだけで、他のポインタと同じだ:それは別のポインタを指しています。この場合には、何かを指すポインタです。

例:

char *p = malloc(12); // Allocate 12 bytes and make the variable p point to it 
strcpy(p, "hello world"); // Initialize the memory we just allocated with a string 

char **pp = &p; // Make the variable pp a pointer, and make it point to the variable p 

メモリではそれがある。この

 
+----+  +---+  +---------------+ 
| pp | --> | p | --> | "hello world" | 
+----+  +---+  +---------------+ 

ようになり、ppは変数pを指している、とpは、文字列"hello world"を含むメモリを指しています。

ppを持つことがほとんど役に立たないですが、ポインタへのポインタを使用すると、関数の引数を参照でパスをエミュレートすることができ、例えば、このような何かを、上に示した:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void function(char **pp) 
{ 
    *pp = malloc(12); // Allocate memory 
    strcpy(*pp, "hello world"); 
} 

int main(void) 
{ 
    char *p; // Define variable, but don't initialize it 

    function(&p); // Pass a pointer to the variable p 

    printf("p = \"%s\"\n", p); // Will print p = "hello world" 
} 

渡すこと変数pへのポインタ(&pを使用)を関数に渡すと、関数はポインタ(つまり、pの値)を変更できます。

もう1つのポインタへのポインタの使用は、配列の動的配列です。例:

char **pp = malloc(5 * sizeof(char *)); // Allocate space for five pointers to char 
for (size_t i = 0; i < 5; ++i) 
{ 
    pp[i] = malloc(12); // Allocate space for a string 
    strcpy(pp[i], "hello world"); // Initialize the memory 
} 

ここでは動的に割り当てられた5つの動的に割り当てられた12個の配列の配列があります。

ポインターへのポインターの使用は、もちろんchar以外のデータ型でも使用できます。

なお、配列は、天然に、その最初の要素(例えばchar x[20][20]等)配列の配列へのポインタに減衰ないポインタへのポインタ(例えばchar **)と同じであっても。このことの説明については、例えば下記を参照されたい。 this old answer of mine

+2

+1しかし、いくつかのニンピク: '私は。文字列の配列 'は完全には正しくありません。単なる 'charポインタの配列'です。これらのポインタが文字列に使用されるかどうかは別の話です。 – 4386427

+1

事実の後、OPが投稿を編集したようです。 'char(* s_item)[20]'は20文字の配列の配列ではなく、20文字の配列へのポインタです。あなたの答えには –