Langage C - pointeur avancé 3 - pointeur de tableau

Définition du pointeur de tableau

analogie:

Pointeur entier --pointeur vers un entier

int a = 10;
int* pa = &a;

Pointeur de caractère --pointeur vers un personnage

char ch = 'a';
char* pc = &ch;

Pointeur de tableau : pointeur vers un tableau

int arr[10] = { 0 };
int(*p)[10] = &arr; // 数组指针

Différence : tableau de pointeurs et pointeur de tableau

int(*p1)[10]; // 数组指针
int* p2[10];  // 指针数组

p1 est d'abord combiné avec *, indiquant que p est une variable de pointeur, pointant vers un tableau d'entiers de taille 10, tout p1 est un pointeur, pointant vers un tableau, p1 est un pointeur de tableau.

p2 est un tableau de 10 éléments, stockant le type int*, et p2 est un tableau de pointeurs.

Remarque : [ ] a une priorité plus élevée que * et () doit être utilisé pour combiner p1 et * en premier.

nom du tableau et & nom du tableau

Dans la plupart des cas, le nom du tableau est l'adresse du premier élément du tableau, à deux exceptions près :

1 & nom du tableau, le nom du tableau représente l'ensemble du tableau

2 sizeof (nom du tableau), le nom du tableau représente l'ensemble du tableau et la taille de l'ensemble du tableau est calculée.

int arr[10];

Pour le tableau ci-dessus, que signifient arr et &arr ?

Nous savons que arr est un nom de tableau et que le nom du tableau représente l'adresse du premier élément. Si &arr est identique à arr, regardez d'abord le code suivant.

int main()
{
	int arr[10] = { 0 };
	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);

	return 0;
}

résultat de l'opération :

On peut voir que &arr et arr affichent la même adresse, cela représente-t-il donc l'adresse du premier élément du tableau comme arr ? Regardez le code suivant :

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

	return 0;
}

résultat de l'opération :

On peut constater que même si &arr et arr ont la même valeur, leurs significations devraient être différentes. En fait, &arr représente l'adresse de l'ensemble du tableau . Dans cet exemple, le type de &arr est int(*)[10], qui est le type de pointeur de tableau. &arr+1 décale la taille de l'ensemble du tableau de 40 (l'adresse imprimée est en hexadécimal) et arr+1 la compense d'une taille entière.

Par conséquent, bien que les valeurs du nom du tableau et du nom du tableau soient les mêmes, leurs significations ne sont pas les mêmes. On peut comprendre que l'un est l'adresse du premier élément du tableau et l'autre est le première adresse du tableau. L'essentiel est que leurs types sont différents, et l'un est le même type de pointeur. L'autre est un pointeur de tableau.

Maintenant que vous comprenez les concepts de pointeurs de tableau et de noms de tableaux, voyons à quoi ressemble le type de pointeur de tableau (pointeur) :

int* arr[10]; // (整型)指针数组
int* (*p)[10] = &arr; // (整型指针)数组指针

Utilisation de pointeurs de tableau

Introduction - accès par pointeur aux tableaux unidimensionnels

Nous savons que les tableaux sont accessibles via des indices ou des pointeurs, comme suit :

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	// 下标访问数组
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	// 指针访问数组
	int* p = arr;
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));//*(p+i)与p[i]等价
	}

	return 0;
}

résultat de l'opération :

Accès du pointeur de tableau à un tableau bidimensionnel

    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };

Accédez aux tableaux bidimensionnels via des indices :

int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}

	return 0;
}

résultat de l'opération :

arr[i] est en fait l'adresse du premier élément de chaque ligne du tableau, arr[i][j] est équivalent à *(arr[i]+j). Pour un tableau à deux dimensions, son premier élément est la première ligne du tableau et son nom de tableau est l'adresse de la première ligne du tableau, qui est un pointeur de tableau. Semblable à l'utilisation d'un pointeur pour accéder à un tableau unidimensionnel, nous pouvons définir un pointeur de tableau pour accéder à un tableau à deux dimensions, mais ce n'est pas la véritable utilisation du pointeur de tableau.

L'une des principales utilisations des pointeurs de tableau est de recevoir un tableau à deux dimensions en paramètre, par exemple :

void print_arr(int(*arr)[3], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	print_arr(arr, 3, 3);

    return 0;
}

résultat de l'opération :

Comprendre les noms de tableaux bidimensionnels :

En fait, l'essence de la transmission de paramètres de tableau à deux dimensions (int arr[][3]) est de transmettre un pointeur de tableau, qui est le nom de tableau d'un tableau à deux dimensions. Le passage des paramètres de tableau et le passage des paramètres de pointeur seront expliqués en détail dans le prochain article.

Continuez à découvrir le contenu avancé du pointeur, consultez l'article suivant : Paramètres de tableau/Paramètres de pointeur

Je suppose que tu aimes

Origine blog.csdn.net/2301_79391308/article/details/132995096
conseillé
Classement