私は、それをもう学びました:
char ar[]
と同じです
char *ar
これらの 3 つの式:
char ar[][] //1
char *ar[] //2
char **ar //3
コンパイラにとっても同じことですか?
これらの 2 つの式:
char ar[]
char ar[][]
配列をスタックに割り当てますが、他のすべてはヒープに割り当てますか?
私は、それをもう学びました:
char ar[]
と同じです
char *ar
これらの 3 つの式:
char ar[][] //1
char *ar[] //2
char **ar //3
コンパイラにとっても同じことですか?
これらの 2 つの式:
char ar[]
char ar[][]
配列をスタックに割り当てますが、他のすべてはヒープに割り当てますか?
char ar[]; creates an array of characters when size is specified.
char * ar; creates a character pointer. Might point to even a single or more characters.
char ar[][]; when size is specified, creates a 2 dimensional array.
char *ar[]; creates an array of character pointers
char **ar; a pointer to pointer to character.
次のように静的にメモリを割り当てる場合
char a[10]; // this goes on stack
一方
char *a = malloc(10); // this goes on heap and needs to be freed by the programmer
おそらくよくあることは、char **a を使用して配列の配列を割り当てたことです。つまり、a の各要素も文字配列です。次に、構文 a[x][y] を使用して、この要素のいずれか 1 つにアクセスできます。
さらに別の違いは、char *a がポインター変数であることです。つまり、a を別のアドレスに再割り当てできますが、char a[] はポインター定数を返し、再割り当てできません。
char ar[]
とchar *ar
同じではありません。1 つは配列、もう 1 つはポインターです。あなたが言っている場合:
char ar[10] = {0};
ar[0] == *ar
はい、両方とも逆参照でき、同じ結果が得られます。ヒープとスタックに関しては、あなたが話していることとは何の関係もありません...変数は、静的なときにスタックから割り当てられます。
char ar[10] = {0}; // this is allocated off the stack.
変数が動的である場合、変数はヒープから割り当てられます。
char *a = malloc(10); //this is from the heap
1)どちらも同じではありませんが、配列を関数に渡す間、ポインターと見なされます。
2)
int ar[10][10]
ar は、10 行 10 列の 2 次元配列です。
char *ar[]
ar は、タイプ「char」のポインターを含む配列です。
char **ar
ar は、「char」型のポインターへのポイントです。
3)
char ar[20]
char ar[10][10]
どちらもスタックからメモリを割り当てます。ヒープからメモリを割り当てるには、動的メモリ割り当ての概念を使用する必要があります。すなわち: malloc。
お役に立てれば。:)
char ar[]
が関数パラメータのchar *ar
場合と同じです。ar
それ以外の場合は、それぞれ配列とポインターです。
char ar[][]
ar
が関数パラメータでない場合は 2 次元配列です。それ以外の場合は、1 次元配列へのポインターです。
char *ar[]
ar
が関数パラメーターでない場合、ポインターの 1 次元配列です。それ以外の場合は、ポインターへのポインターです。
char **ar
ポインタへのポインタです。
基本的に、それが関数パラメーターで、配列のように見える場合、実際には配列の最初の要素へのポインターです。配列全体が関数パラメーターとして渡されるわけではありません。しようとすると、配列自体ではなく、配列の最初の要素へのポインターを渡します。
関数の外部で定義されたすべての変数は、ヒープにもスタックにもありません。それらはグローバル変数です。
関数内で定義されたすべての変数 (変数を除くstatic
) はスタック上にあります。static
変数はグローバル風で、ヒープにもスタックにもありません。static
関数またはモジュールスコープへのグローバル変数の可視性を減らします。それだけです。
Only those variables allocated explicitly via malloc()
, calloc()
, ralloc()
live in the heap. Some standard library functions may create variables/objects in the heap, e.g. fopen()
.
問題は、配列にはポインターよりも多くの情報が含まれていることです。配列のサイズを決定することができ、コンパイラーはそれを認識します。たとえば、型"Hello"
はconst char[6]です。サイズに注意してください。次のスニペットは、次のことを示しています。
#include <stdio.h>
int main()
{
const char array[] = "Hello";
char* pointer = "Hello";
printf("Array: %d - Pointer: %d", sizeof(array), sizeof(pointer))
return 0;
}
私のシステムでは、スニペットは次の出力を提供します:
Array: 6 - Pointer: 4
配列の場合、サイズはコンパイル時に常に認識されるため、コンパイラがサイズを認識しても問題ありません。ただし、ポインターは実行時に決定されることが多いため、通常は動的に割り当てられたメモリに関連付けられます。
それについての非常に単純な考え方は、配列が「全体」であるのに対し、ポインターは最初の要素への単なる参照であるということです。