C言語実践のポインタと配列の解析(1.1)

序文

友達の皆さん、今日の内容を一緒に学び始めましょう! 今日も素晴らしい内容です!早速、学習を始めましょう。

1. 1次元配列

始める前に、関連する知識ポイントをいくつか思い出す必要があります。sizeof は、型が占める領域のサイズを計算するために使用されるオペランドであり、\0 は計算に含まれません。配列名は最初の要素のアドレスを示しますが、2 つの例外があります。sizeof (配列名) は配列全体の長さを計算し、配列名は配列全体のアドレスを取得します。暗記が終わったら、直接コードに進みましょう。

1.1 整数配列

#include<stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a+0));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a+1));
	printf("%d\n", sizeof(a[1]));
	printf("%d\n", sizeof(&a));
	printf("%d\n", sizeof(*&a));
	printf("%d\n", sizeof(&a+1));
	printf("%d\n", sizeof(&a[0]));
	printf("%d\n", sizeof(&a[0]+1));
	return 0;
}

 変数はメモリ内のスペースを割り当てます

 上記のように、コードを 1 つずつ分析してみましょう。

int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));

まず探すのはsizeof(a)のサイズですが、おお、これはsizeofに単独で上記の例外配列名を入れて配列全体のアドレスを計算する場合にはちょうどいいですね!整数配列、1 つの要素のサイズは 4 バイト、合計 4 つの要素があるため、この時点で配列全体のサイズは 16 バイトです。

printf("%d\n", sizeof(a+0));

もう一度解析してみましょう、ここではsizeof内に配列名が単独で配置されていないので、この時点では配列名が先頭要素のアドレスを表しているということになります!a+0 アドレスは変更されておらず、依然として最初の要素のアドレスです。アドレスのサイズは4/8バイトです!

printf("%d\n", sizeof(*a));

ここでは、配列名は依然として sizeof 内に単独で配置されておらず、配列の最初の要素のアドレスを表しており、これは &a[0] に相当します。*(&a[0]) を逆参照すると、a[0] が得られ、これは 1 です。このとき、計算サイズは sizeof(int) に相当し、結果は 4 バイトになります。

printf("%d\n", sizeof(a+1));

sizeof は内部の別個の配列名ではなく、 a は依然として最初の配列名のアドレスを表します。a+1 は配列の 2 番目の要素のアドレス &a[0]+1 になります。アドレスのサイズは 4/8 バイトのままです。

printf("%d\n", sizeof(a[1]));

a[1] は配列の 2 番目の要素 (2) であり、この時点で 4 バイトが取得されます。

printf("%d\n", sizeof(&a));

 &Array name は配列全体のアドレスを取得することを意味し、このとき sizeof はアドレスのサイズを計算します。アドレスは 4/8 バイトのままです

printf("%d\n", sizeof(*&a));

& と * は打ち消し合い、*&a は a を残します。このとき、配列全体のサイズを計算する sizeof(a) が計算され、結果は 16 バイトになります。

printf("%d\n", sizeof(&a+1));

&a は配列全体のアドレスを取り出し、1 を追加すると配列のサイズがスキップされます。この時点でも sizeof はアドレスを計算し、結果は 4/8 バイトになります。

printf("%d\n", sizeof(&a[0]));

&a[0] は最初の要素のアドレスを取り出しますが、sizeof は引き続きアドレスのサイズを計算します。結果は依然として 4/8 バイトです。

printf("%d\n", sizeof(&a[0]+1));

&a[0]+1 は配列の 2 番目の要素のアドレスを取り出しますが、sizeof は引き続きアドレスのサイズを計算し、結果は 4/8 バイトになります。

コードを実行して結果を確認します。vs では x86 が使用されているため、アドレスのサイズは 4 バイトです。

 1.2 文字配列

sizeof と strlen の違いを覚えていますか? sizeof は、型によって占有されるスペースを計算するために使用されるオペランドであり、\0 は含まれません。strlen は、ヘッダー ファイル string.h を使用する前に参照する必要があるライブラリ関数であり、具体的には文字列のサイズを計算し、\0 に遭遇すると停止します。文字配列の初期化には char arr[]={'a','b'} と char arr[ ]="ab" の 2 種類があります。この 2 つの違いは、2 番目の初期化では \0 が隠されているのに対し、最初の初期化では \0 が隠されていないことです。

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr));
	return 0;

}

 分析しましょう

printf("%d\n", sizeof(arr));

sizeof (配列名) は配列全体のアドレスをシークします。char 型のサイズは 1 バイト、文字配列の要素は 6 つあり、配列全体のサイズは 6 バイトになります。

printf("%d\n", sizeof(arr+0));

 arr は、sizeof に単独で配置された場合の配列の最初の要素のアドレスを表し、arr+0 は依然として配列の最初の要素のアドレスです。アドレスのサイズは4/8バイトです

printf("%d\n", sizeof(*arr));

arr は引き続き配列の最初の要素のアドレスを表します。これは *(&arr[0])-->arr[0] を逆参照する &arr[0] と同等です。つまり、sizeof は配列の最初の要素のサイズ、つまり 1 バイトを計算します。

printf("%d\n", sizeof(arr[1]));

    ここでの直接計算は配列の 2 番目の要素のサイズであり、結果は 1 バイトになります。

printf("%d\n", sizeof(&arr));

 &Array name、配列全体のアドレスを取得するため、sizeof でアドレスのサイズが計算され、結果は 4/8 になります。

printf("%d\n", sizeof(&arr+1));

&arr は配列全体のアドレスを取り出し、1 を加えた後に配列をスキップし、sizeof でアドレスのサイズを計算すると、結果は 4/8 になります

printf("%d\n", sizeof(&arr[0]+1));

&arr[0] は配列の最初の要素のアドレスを取り出し、&arr[0]+1-->&arr[1] は配列の 2 番目の要素のアドレスを取り出します。sizeof はアドレスのサイズを計算します。結果は 4/8 です。

printf("%d\n", strlen(arr));

strlen は \0 に遭遇するまでの文字数をカウントしますが、arr には \0 がありません。したがって、計算結果はランダムな値になります

printf("%d\n", strlen(arr+0));

arr+0 は依然として配列の最初の要素のアドレスを表しますが、\0 がないため、結果はランダムな値になります。

printf("%d\n", strlen(*arr));

arr は、配列の最初の要素が &arr[0],*&arr[0]-->arr[0] であることを意味するため、strlen(arr[0]) となる可能性があります。 cplusplus によれば、strlen のパラメータは char* のポインタであることがわかり、このときの計算結果はエラーになります

printf("%d\n", strlen(arr[1]));

 説明は上記と同じですが、結果はエラーになります

printf("%d\n", strlen(&arr));

 &arr は配列全体のアドレスを取得します。このとき strlen はアドレスのサイズを計算しますが、arr には \0 がないため、結果はランダムな値のままです。

printf("%d\n", strlen(&arr+1));

&arr は配列全体のアドレスを取得します。&arr+1 は配列のアドレスをスキップします。\0 がまだ存在しないため、結果は依然としてランダムな値です。

printf("%d\n", strlen(&arr[0]+1));

&arr[0]+1 は配列の 2 番目の要素のアドレスを取得しますが、arr には \0 がないため、結果は依然としてランダムな値になります。

実行して結果を確認してください

 別の別のセット

int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr+0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr+1));
	printf("%d\n", sizeof(&arr[0]+1));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr+0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr+1));
	printf("%d\n", strlen(&arr[0]+1));
	
	return 0;
}

何が違うのか見てみましょう。文字配列が異なるだけで、すべて同じであるようです。

printf("%d\n", sizeof(arr));

sizeof (配列名) は配列全体のサイズを計算し、sizeof は \0 を含む占有メモリのサイズを計算するために使用されます。したがって、計算結果は 7 になります

printf("%d\n", sizeof(arr+0));

arr+0 は依然として配列の最初の要素のアドレスを表し、アドレスのサイズは 4/8 です。

printf("%d\n", sizeof(*arr));

*arr-->*(&arr[0])-->arr[0]、sizeof は配列の最初の要素のサイズを計算し、結果は 1 バイトになります

printf("%d\n", sizeof(arr[1]));

sizeof は配列の最初の要素のサイズを計算します。結果は 1 バイトです

printf("%d\n", sizeof(&arr));

&arr は配列全体のアドレスを取得するため、sizeof はアドレスのサイズを計算し、結果は 4/8 になります。

printf("%d\n", sizeof(&arr+1));

&arr は配列全体のアドレスを取り出し、&arr+1 は配列全体のアドレスをスキップします。sizeof は引き続きアドレスのサイズを計算します。結果は 4/8 です。

printf("%d\n", sizeof(&arr[0]+1));

&arr[0]+1-->&arr[1]、配列の 2 番目の要素のアドレスを取得します。sizeof は引き続きアドレスのサイズを計算します。結果は 4/8 です。

printf("%d\n", strlen(arr));

\0 は char arr[]="abcdef" に隠されており、strlen は \0 に遭遇するまでの文字数を計算するため、結果は 6 になります。

printf("%d\n", strlen(arr+0));

arr+0 は配列の最初の要素のアドレスを表し、strlen は \0 に遭遇するまでの文字数を計算するため、結果は 6 になります。

printf("%d\n", strlen(*arr));

strlen のパラメータには char* ポインタ *arr-->*&arr[0]-->arr[0] が必要ですが、特定の数値は必要ないため、結果はエラーになります

printf("%d\n", strlen(arr[1]));

上と同じ説明

printf("%d\n", strlen(&arr));

&arr は配列全体のアドレスを取り出しますが、&arr と &arr[0] のアドレスは配列の最初の要素のアドレスと同じです。

 &arr と &arr[0] の違いは何ですか。コードを使用して見てみましょう。

int main()
	{
		char arr[] = "abcdef";
		printf("%p\n", &arr[0]);
		printf("%p\n", &arr[0] + 1);

		printf("%p\n", &arr);
		printf("%p\n", &arr + 1);
		return 0;
		
	}

&arr[0]+1 は 1 バイトスキップし、&arr+1 は 7 バイトスキップしていることがわかります。なぜ 7 バイトなのでしょうか? これは、sizeof が配列のサイズを 7 バイトとして計算しているためです。

この質問に戻ると、strlen(&arr) は依然として配列の最初の要素のアドレスから計算を開始し、\0 に遭遇すると停止します。結果は 6 です。

printf("%d\n", strlen(&arr+1));

&arr+1 (笑) 上記の状況で、strlen(&arr+1) の結果はどうなるでしょうか? そうです、またランダムな値です

printf("%d\n", strlen(&arr[0]+1));

&arr[0]+1-->&arr[1] は配列の 2 番目の要素のアドレスを取得するため、strlen は計算時に 2 番目の要素のアドレスから逆方向に計算するため、結果は 5 になります。


さて、以上が今日の勉強で、以下の内容は明日書きます

おすすめ

転載: blog.csdn.net/2301_77886098/article/details/131829922