配列ポインターとオフセット
最初のコードを見てください
int a[5] = {0, 1, 2, 3, 4};
printf("a:\t%p\n", a);
printf("&a:\t%p\n", &a);
printf("a+1:\t%p\n", a+1);
printf("&a+1:\t%p\n", &a+1);
- 配列の識別子aである配列の名前を出力します。結果は0133FD80で、配列の最初のアドレスを示します
- 配列名の前にアドレス文字&を追加すると、結果は0133FD80になり、これは配列の最初のアドレスも示します
- 印刷配列名に1を追加すると、結果は0133FD80になります。intは4バイトを占めるため、配列の最初のアドレスに1を追加しても、アドレス値が直接1増加するわけではありませんが、アドレスオフセットは4バイトであり、配列の次の要素の最初のアドレスを指します
。4 。配列名はアドレスシンボル&を取り、次に1を追加します。結果は0133FD94で、20の増加です。これは、配列内の5つの要素が占めるスペースのサイズであり、配列全体が最初に使用され、次に1が追加されて配列全体をオフセットすることを示します。広いアドレス空間
文字配列
2番目のコードを見てください。
char *cp;
char *cp1;
cp =(char *) malloc(strlen("hello") + 1);
if(NULL == cp)
{
exit(1);
}
strcpy(cp, "hello");
cp1 = cp;
printf("%s\n", &cp[0]);
printf("%s\n", cp1);
free(cp);
- strlen()関数は文字列の有効な長さを返し、sizeof()関数は文字列が占める実際のスペース(末尾の\ 0文字を含む)を返すため、アドレスを文字ポインターに割り当てるときのサイズになります追加する必要があります1
- strcpy()を使用して文字ポインタースペースに値を割り当てる場合、文字列のサイズは以前に開いたスペースを超えることはできません。そうでない場合、コンパイルは成功しますが、実行時にエラーが発生します
- 文字ポインタを別の文字ポインタに直接割り当てて、2つのポインタが同じメモリ領域を指すようにすることができます。
- 文字ポインター、文字ポインタープラス&、文字ポインタープラス&プラス[0]を使用して、完全な文字列helloを出力します。
- mallocを使用してメモリを割り当てた後、解放することを忘れないでください。同時に、割り当てが失敗した場合を判断してください1
関数パラメーターとしての配列ポインター
3番目のコードを見てください。
void dealArr(int num, int* pArr)
{
int i = 0;
for(i = 0; i < num; i++)
{
*(pArr+i) = (*(pArr+i))++;
}
}
int a[5] = {0, 1, 2, 3, 4};
int j = 0;
dealArr(5, a);
for(j = 0; j < 5; j++)
{
printf("%d,", a[j]);
}
- 定義された関数パラメーターの型はint *であり、整数へのポインターを示します
- 配列名aを直接渡すことも、配列&a全体を渡すこともできますが、&aの型がint(*)[5]であるため、実際のパラメーターの型に互換性がないことを示すプロンプトが表示されます。[0]を渡してコンパイルすることもできます。合格しますが、操作は間違っています
- 関数に渡されたポインタは、アドレスが指す値を変更できます。印刷結果は1、2、3、4、5です。
「Cトラップと欠陥」↩︎