C/C++ ポインターと配列で記述されたテスト問題の分析

個人ホームページ:クリックしてホームページに入ります

コラム分類: C言語初級      C言語プログラミング——KTV        C言語ミニゲーム     C言語上級

C言語の試験問題

誰でも「いいね!」、コメント、収集を歓迎します。

一緒に頑張って大きな工場へ一緒に行きましょう。

目次

 

1 はじめに 

2. 1次元配列

2.1 演習 1

2.2 演習 2

2.3 演習 3

3. 2次元配列

4. まとめ


 

1 はじめに 

前に、ポインターの基礎と高度なポインターを学習しました。もう一度学習したい場合は、 [ポインターの上級]  、[ポインターの上級]、および[ポインターの初心者]        をクリックします今回は主にポインタに関する筆記試験問題を一緒に勉強していきます この筆記問題はsizeof関数とstrlen関数を使った非常に面白い問題です 次にこの問題の面白さを感じてみましょう 質問をするときに知る必要がある

  • ここでの sizeof (配列名) は、配列全体のサイズ、つまり占有バイト数を計算します。
  • &array name は配列全体のアドレスを取得します
  • 残りの配列名は最初の要素のアドレスです。

2. 1次元配列

2.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;
}

        sizeof(a) では、a は配列名であり、配列のサイズが計算されるため、16 バイトになりますが、sizeof(a+0) では、配列名 a は単独では存在しないため、配列のアドレスになります。最初の要素はアドレスなので、4/8 バイトを占めます、sizeof(*a)、配列名は単独では存在しません、*a は最初の要素で、4 バイトを占めます、sizeof(a+1)、配列名は単独では存在せず、a は最初の要素のアドレス、a+1 は 2 番目の要素のアドレス (アドレスで 4/8 バイトを占めます。sizeof(a[1]) は 2 番目の要素です)。要素は int で 4 バイトを占めます。sizeof(&a)、配列のアドレスであり、アドレスに属し、4/8 バイトを占めます。sizeof(*&a)、* と & は次の場合にオフセットできることがわかります。まとめると、sizeof(a) と同等になるため、16 バイトを占有します。sizeof(&a +1)、&a は配列のアドレスです。1 を追加すると 16 バイト追加することになりますが、これはアドレスなので、占有します。 4/8 バイト、sizeof(&a[0]) は最初の要素のアドレスで、4 /8 バイトを占め、sizeof(&a[0]+1) は 2 番目の要素のアドレスで、4/8 バイトを占めます。

2.2 演習 2

#include<stdio.h>
#include <string.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	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;
}

         sizeof(arr)、arr は単独で存在するため 6 バイト、sizeof(arr+0)、配列名は単独で存在しないため、最初の要素アドレスに属し、アドレスに属し、4/8 バイトを占有します.sizeof(*arr)、配列名は単独では存在しません。*arr は最初の要素で、文字型で 1 バイトを占めます。sizeof(arr[1]) は 2 番目の要素で、1 バイトを占めます。sizeof (&arr)、配列のアドレス、アドレスに属し、4/8 バイトを占有、sizeof(&arr+1)、&arr は配列のアドレス、&arr+1 はこの配列をスキップしますが、それでもアドレスです、アドレスに属します。4/8 バイトを占めます。sizeof(&arr[0]+1)、&arr[0] は最初の要素のアドレス、&arr[0]+1 は 2 番目の要素のアドレスです。はアドレスであり、4/8 ワードを占めます。strlen(arr)は配列名が単独で存在するが、いつ\0が出現するか分からないのでランダムな値 strlen(arr+0)は最初のアドレスが分かるが分からない\0= が表示される場合、ランダムな値です。strlen(*a) と strlen(arr[1]) の *a と arr[1] は両方とも文字です。変換に ASCLL を使用すると、整数昇格とゼロ パディングが実行されます。コンピュータはそれをアドレスとして認識するためですが、このアドレスは初期化されていないため、つまりワイルド ポインタであり、コンピュータ エラーやプログラムのクラッシュを引き起こす可能性があります。最後の 3 つのゲームでは、それらはすべてランダムな値です。 \0がないからです。

2.3 演習 3

#include<stdio.h>
#include <string.h>
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;
}

        sizeof(arr)の場合は配列名が単独で存在するので6バイト、sizeof(arr+0)の場合は配列名が単独で存在しないので、アドレスに属する最初の要素のアドレスとなり、4バイトを占めます。 /8 bytes. sizeof( *arr), 配列名は単独では存在せず、最初の要素です。最初の要素は char 型で、1 バイトを占めます。sizeof(arr[1]) は配列の 2 番目の要素で、char 型で 1 バイトを占めます。sizeof(&arr) と sizeof(&arr+1)、&arr は配列のアドレス、&arr+1 は配列の後ろのアドレスで、アドレスに属し、4/8 バイトを占めます、sizeof(&arr[0]+1 )、&arr[0] は最初の要素のアドレス、&arr[0]+1 は 2 番目の要素のアドレスで、アドレスは 4/8 バイトを占めます。strlen(arr)の場合、配列名が単独で存在するので6バイトになります。strlen(arr+0)の場合、arrは単独で存在せず、先頭要素のアドレスに属するので6バイトになります。strlen(*a) と strlen(arr[1]) の *a と arr[1] は両方とも文字です。変換に ASCLL を使用すると、コンピュータはそれをアドレスとして認識するため、整数リフティングとゼロ埋め込みが実行されますが、このアドレスは初期化されていないため、ワイルド ポインタであり、コンピュータ エラーやプログラムのクラッシュを引き起こす可能性があります。最後の 3 つについては、&arr は配列のアドレスを取得し、&arr[0]+1 は 2 番目の要素のアドレスを取得し、&arr+1 は配列の後ろのアドレスからランダムな値を取得します。

3. 2次元配列

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

        sizeof(a)の場合は配列名が単独で存在し、配列のアドレスとなるので4*3*4=48バイトになりますが、sizeof(a[0])の場合は特殊です。 2 次元配列は 1 次元配列の配列と考えることができます。a[0] は最初の行のアドレスなので、4/8 バイトになります。sizeof(a[0]+1) の場合, a[0] は 1 次元です。sizeof() には a[0] だけが存在しないため、配列の配列名は 4/8 バイトを占める 1 次元配列の最初の要素のアドレスになります。 sizeof(*(a[0]+1)) は 2 番目の要素が 4 バイトを占めます。 a は 2 次元配列の配列名です。 sizeof(a+1) には a だけが存在しないので、 2 次元配列の最初の要素。これは最初の行のアドレスです。+1 は 2 行目のアドレスで、4/8 バイトを占めます (2 次元配列の場合、2 次元配列と考えることができます) arr[3][4] などの 1 次元配列の配列、arr という名前の 2 次元配列の配列、1 次元配列の配列の名前は arr[3])。 )), a は 2 次元配列の配列名です。単独では存在しませんので、2 次元配列の最初の要素です。つまり 1 行目のアドレス、a+1 がアドレスです2 行目の * (a+1) は 2 行目のすべての要素で、16 バイトを占めます。sizeof(&a[0]+1)、a[0] は 1 次元配列の配列名、&a[0] は最初の行のアドレス、&a[0]+1 は 2 番目の行のアドレスrow. 、アドレスは 4/8 バイトを占め、*逆参照すると 16 バイトを占めます。sizeof(a[3]) の場合、配列はオーバーフローしましたが、関数が実際に入力しないため、まだ 16 バイトです。 a[0]と同じです。

4. まとめ

        これらの質問を読んだ後、次のように要約できます。

  • sizeof(配列名)、配列名は配列全体です。
  • & 配列名プラスおよびマイナスの整数。ここで、& 配列名は配列全体のアドレスです。sizeof() であっても配列全体のアドレスです
  • 2 次元配列の場合、2 次元配列を arr[3][4] などの 1 次元配列の配列とみなすことができます。2 次元配列の配列の名前は arr で、配列の名前は arr です。 1 次元配列の名前は arr[3],&arr です。arr は 2 次元配列のアドレスですが、sizeof では、arr に整数を加えたものが行のアドレスを示します。arr[integer] と arr[integer] は両方とも行のアドレスを示します。

今日の内容は以上です。ワンクリックで3回接続していただければ幸いです。

 

おすすめ

転載: blog.csdn.net/Infernal_Puppet/article/details/133020826