さて、最初に覚えておくべきことは、「配列への」ポインタのようなものはないということですが、それはかなり頻繁に言われます。ずさんです。
(以下で指摘するように、「配列へのポインタ」という用語は厳密には意味がありますが、混乱していると思います。実際には、すべてのポインタにアドレスが含まれています。宣言によっては、コンパイラは、コンテキストで正しく使用されているかどうかを識別できます。これは、エラーメッセージが実際に示していることです。関数で宣言したのは、charの配列へのポインタです。つまり、char **
ではなく、と同じことです。 char *
、これが渡されます。ただし、、、、、char *
またはchar **
、char ******
重要な点は、複雑になりすぎていることです。必要なアドレスは、配列名で識別されています。)
ポインタはポインタであり、アドレスです。
Cの配列は、単に割り当てられたメモリのチャンクであり、その名前は最初の要素のアドレスを表します。それで
char a[42];
は42文字の長さのメモリのブロックであり、aはそのアドレスです。
2番目の関数を次のように書き直すことができます
void foo(char* a, int num){ // (3)
// notice that you don't need the word function and
// for lots of reasons I wouldn't use it as a function name.
a[num] = 'A'; // (4)
}
int main(){
// Sadly "00000" IS a string no matter what your comment
// says. Use an array initializer instead.
char arry[5] = {'0','0','0','0','0' } ; // (1)
foo(arry,3); // (2)
}
これは、あなたのコードが意味すると私が信じていることを実行します。ご了承ください
(1)「00000」は実際には文字列であるため、実際には、配列初期化子で初期化できた6要素の長さの配列を作成しています。
{'0','0','0','0','0', 0 }
(2)配列(「this」はCのような言語のキーワードであることが多いので、「this」の代わりに「arry」と名付けました。なぜ混乱のリスクがありますか?)はすでにアドレスです(ただし、ポインターではありません。ポインタへの割り当ての右側ですが、左側にはありません。)
だから私が電話するとき
foo(arry,3);
arryの最初の要素のアドレスと番号3で呼び出しfoo
ています(そのための変数を宣言する必要はありません)。
今、私はそれを次のように書くこともできたでしょう
foo(&arry[0],3);
「の0番目の要素を見つけて、arry
そのアドレスを取得する」と読みます。これは、CのIDであり、任意の配列に対応します。
char c[len];
式c
と&c[0]
同じアドレスを参照します。
(3)これは。として定義することもできますfoo(char arry[], int num)
。それらは同等です。
(4)参照するときは、配列の先頭のアドレスにある、が指すメモリの-番目の要素a[num]
を直接参照しています。すべての間接参照は必要ありません。num
a
arry
これを理解するのが少し難しいことを気にしないでください。Cを開始するときは誰にとっても難しいことです。