C 言語における文字配列と文字ポインタの違いについて、まず次の例を見てみましょう。
void test()
{
//arr is array of characters
char arr[12] = "Aticleworld";
//ptr is pointer to char
char *ptr = "Aticleworld";
}
ここで、arr (文字の配列) と ptr (文字へのポインタ) を比較してみましょう。
違い1:
文字列リテラルは、二重引用符で囲まれた 0 個以上のマルチバイト文字のシーケンスです。ステートメント char arr[12] = "Articleworld" を記述すると、文字列リテラル内の文字が arr にコピーされます。
ステートメント char *ptr = "Articleworld" を記述すると、文字列リテラルの配列に配列からポインターへの変換が行われ、その最初の要素へのポインターが取得されます。ポインタ ptr は、文字列リテラル配列の最初の要素 ('A') を指します。
違い2:
arr は連続したメモリ位置に格納されている文字のコレクションであり、ptr は文字のアドレスを保持します。
arr には 12 個の要素が含まれており、それぞれが連続したメモリ位置に配置されます。一方、ptr は文字列リテラルの最初の文字のアドレスを保持します。
違い3:
char 配列 arr に対して sizeof 演算子を使用すると、文字の合計数が得られますが、char ポインター ptr はポインターのサイズを与えるだけです。次のように:
#include <stdio.h>
int main()
{
//arr is array of characters
char arr[] = "Aticleworld";
//ptr is pointer to char
char *ptr = "Aticleworld";
printf("Size of arr %ld\n", sizeof(arr));
// sizeof a pointer is printed which is same for all type
// of pointers (char *, void *, etc)
printf("Size of ptr %ld", sizeof(ptr));
return 0;
}
出力:
Size of arr 24
Size of ptr 4
違い4:
ポインターとポインターのもう 1 つの重要な違いは、ポインターをインクリメントすることはできますが、配列のインクリメントを作成することはできないことです。例:
arr++ =>非法语句。
ptr++ ==>正常语句。
違い5:
配列に値を再割り当てすることはできますが、文字列リテラルは変更できません。プログラムが文字列リテラルで構成される静的配列を変更しようとした場合、その動作は未定義です。例:
//arr is array of characters
char arr[] = "Aticleworld";
gets(arr);
fgets(arr,sizeof(arr),stdin); //有效表达式
scanf("%s", arr); //有效表达式
strcpy(arr, "aticle"); //有效表达式
arr[0] = 'a'; //有效表达式
arr[10] = 'M'; //有效表达式
arr[11] = 'M'; //有效表达式
char *ptr = "Aticleworld";
ptr[0] = 'P'; //无效表达式
*ptr = 'W'; //无效表达式
違い6:
初期化されていないポインターも、未定義の動作を引き起こす可能性があります。以下の例を参照してください。
char *ptr;
ptr[0] = 'A'; //未定义的行为
gets(ptr); //未定义的行为
scanf(“%s”, ptr); //未定义的行为
strcpy(ptr, “source”); //未定义的行为
strcat(ptr, “second string”); //未定义的行为
違い7:
Char 配列は本質的に静的です。つまり、配列のサイズを変更することはできませんが、ポインターを使用すると、割り当てられたメモリのサイズをいつでも変更できます。
違い8:
配列は完全にプログラムの制御下にあります。必要なメモリが適切に割り当てられ、範囲外になるとメモリが自動的に解放されます。ただし、動的メモリを割り当てる場合、char ポインタの場合は異なります。手動で割り当てを解除する必要があり、そうでないとメモリ リークが発生します。例:
void foo1()
{
//arr是字符数组
char arr[12] = "Aticleworld";
}
//Issue memory leak
void foo2()
{
char *ptr = (char*)malloc(12);
//忘记释放内存
}
上記は、C 言語における文字配列と文字ポインタのいくつかの違いと関連する例です。