[Langage C] Analyse approfondie de la relation entre les pointeurs et les tableaux


1. Nom du tableau et nom du tableau

Deuxièmement, le pointeur de caractère

1. Un pointeur de caractère vers le premier élément d'un tableau de caractères char* p=arr

2. Un pointeur de caractère vers une chaîne constante const char* p="abc"

3. Tableau de pointeurs int* p[3]={arr1,arr2,arr3}

4. Pointeur de tableau int(*p)[10]=&arr

Cinq, paramètres de tableau

1. Transfert de paramètres de tableau unidimensionnel

2. Transfert de paramètres de tableau bidimensionnel

Six, paramètre de pointeur

1. Transfert de paramètre de pointeur de premier niveau

2. Transfert de paramètre de pointeur de deuxième niveau

Sept, pointeur de fonction

1. Compréhension des deux codes

2. Renommer le pointeur de fonction

3, l'utilisation de pointeurs de fonction - fonction de rappel

Huit, tableau de pointeurs de fonction - objectif : table de transfert

Neuf, pointeur de tableau de pointeur de fonction


1. Nom du tableau et nom du tableau

Différence : le nom du tableau indique l'adresse du premier élément, et l'ajout de 1 à l'adresse indique que la taille d'un type de données est ignorée.

Le nom du tableau & signifie que l'adresse de l'ensemble du tableau est supprimée, et ajouter 1 à l'adresse signifie sauter la longueur d'un tableau.

Par exemple : arr[] doit être pointé par un pointeur d'entier (etc.) et &arr[] doit être pointé par un pointeur de tableau.

Le nom du tableau représente généralement l'adresse du premier élément, à deux exceptions près :

1. sizeof (nom du tableau), où le nom du tableau représente l'adresse du premier élément du tableau.

2. & nom du tableau, indiquant que ce tableau est supprimé.

Deuxièmement, le pointeur de caractère

1. Un pointeur de caractère vers le premier élément d'un tableau de caractères char* p=arr

#include <stdio.h>
int main()
{
	char arr[5] = "abc";
	char* p = arr;
	printf("%s", p);//打印abc
	return 0;
}

Le nom du tableau est l'adresse du premier élément, où le pointeur p pointe vers l'adresse du premier élément 'a' du tableau arr, et la chaîne peut être imprimée sous la forme %s via le pointeur p.

2. Un pointeur de caractère vers une chaîne constante const char* p="abc"

#include <stdio.h>
int main()
{
	const char* p = "abc";//字符串abc为常量字符串
	printf("%s", p);
	return 0;
}

Parce que "abc" est une chaîne constante et ne peut pas être modifié, le pointeur p doit être modifié avec const. S'il n'y a pas de const, le programme se bloquera directement lors de l'exécution du fichier .c, et le fichier .cpp sera plus strict, et une erreur sera signalée directement.

3. Tableau de pointeurs int* p[3]={arr1,arr2,arr3}

Un tableau de pointeurs est essentiellement un tableau, un tableau de pointeurs.

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,7,5,8,99 };
	int* p[3] = { arr1,arr2,arr3 };
	for (int i = 0;i < 3;i++)
	{
		for (int j = 0;j < 5;j++)
		{
			//printf("%d ", p[i][j]);
            //printf("%d ", *(*(p+i) + j));//p[i]可以写成*(p+i)
			printf("%d ",*(p[i]+j));//解释如下图
		}
		printf("\n");
	}
	return 0;
}

Les trois manières d'imprimer des tableaux de pointeurs sont possibles. Le code ici est similaire à un tableau à deux dimensions, et le premier élément du tableau est la première ligne. L'analyse détaillée est la suivante :

4. Pointeur de tableau int(*p)[10]=&arr

Un pointeur de tableau est un pointeur vers un tableau.

int(*p)[10]=&arr, le type du pointeur de tableau p est int(*)[10] (supprimez p, c'est-à-dire le type). Ici, le pointeur +1 saute une taille de tableau.

#include <stdio.h>
print(int(*p)[5], int r, int c)//接收的是指向一维数组的数组指针
{
	for (int i = 0; i < r;i++)
	{
		for (int j = 0; j < c; j++)
		{
			//printf("%d ", p[i][j]);
			//printf("%d ", *(p[i]+j));
			printf("%d ", *(*(p+i)+j));
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { 1,5,4,6,7,9,8,4,2,5,4,5,4,5,6 };
	print(arr, 3, 5);//传过去的是二维数组
	return 0;
}

La compréhension de la méthode d'impression est la même que dans l'exemple précédent. Notez que le premier élément du tableau à deux dimensions est la première ligne.

Regardons un autre exemple : int(*p[10])[5], qui est un tableau qui stocke des pointeurs de tableau, et le type des éléments du tableau est int(*)[5].

Cinq, paramètres de tableau

1. Transfert de paramètres de tableau unidimensionnel

void test(int arr[])//一维数组传参,数组接收
{}
void test(int arr[10])//一维数组传参,数组接收,10可有可无
{}
void test(int* arr)//一维数组传参,指针接收
{}
int main()
{
	int arr[10] = { 0 };
	test(arr);
}
void test2(int* arr[20])//指针数组传参,指针数组接收,20可有可无
{}
void test2(int** arr)//传过来的是一级指针的指针,当然可以用二级指针接收
{}
int main()
{
	int* arr2[20] = { 0 };
	test2(arr2);
}

2. Transfert de paramètres de tableau bidimensionnel

void test(int arr[3][5])//二维数组传参,二维数组接收
{}
void test(int arr[][])//错误,行不能省略
{}
void test(int arr[][5])//二维数组传参,二维数组接收
{}
void test(int *arr)//错误,传过来的是第一行的地址,相当于一维数组的地址,不能用一级指针接收
{}
void test(int* arr[5])//错误,不能用指针数组接收
{}
void test(int (*arr)[5])//可以用数组指针接收
{}
void test(int **arr)//错误,传过来的是一维数组的指针,不能用二级指针接收,二级指针是指向一级指针的指针
{}
int main()
{
 int arr[3][5] = {0};
 test(arr);//传过来的相当于第一行的地址
}

Six, paramètre de pointeur

1. Transfert de paramètre de pointeur de premier niveau

void text(int* p)
{}
int main()
{
	int a = 0;
	int* pa = &a;
	int arr[10] = { 0 };
	text(&a);//可以传整型变量的地址
	text(pa);//可以传一级指针的地址
	text(arr);//可以传整型数组的地址
	return 0;
}

Tant que l'essence transmise est un pointeur de premier niveau, elle peut être reçue avec un pointeur de premier niveau.

2. Transfert de paramètre de pointeur de deuxième niveau

void text(int** p)
{}
int main()
{
	int* p1 = NULL;
	int** p2 = NULL;
	int* arr[10];
	text(&p1);//可以传一级指针的地址
	text(p2);//可以传二级指针
	text(arr);//可以传指针数组
	return 0;
}

Sept, pointeur de fonction

Pour les noms de fonction et les noms de fonction &, leurs adresses sont les mêmes et il n'y a pratiquement aucune différence.

Lors de l'appel d'une fonction à l'aide d'un pointeur de valeur de fonction, vous pouvez appeler p comme nom de fonction et le déréférencement n'a aucun sens.

1. Compréhension des deux codes

( *( void (*)() )0 )();

Le code ci-dessus est un appel de fonction, convertissez d'abord 0 en type de pointeur de fonction, le pointeur de fonction n'a pas de paramètres et la valeur de retour est vide. Puisque le déréférencement du pointeur de fonction n'a pas de sens, ce * est facultatif ici. Le code entier signifie un appel de fonction à la fonction à l'adresse 0.

void ( *signal( int , void(*)(int) ) )(int);

Le code ci-dessus est une déclaration de fonction.

signal est le nom de la fonction, ses paramètres sont int et le pointeur de fonction void(*)(int), et le type de retour est le pointeur de fonction void(*)(int).

2. Renommer le pointeur de fonction

typedef void(*pf_t)(int);
pf_t signal(int,pf_t);

Renommez le type void(*)(int) en pf_t.

La fonction ci-dessus peut utiliser pf_t au lieu de void(*)(int).

3, l'utilisation de pointeurs de fonction - fonction de rappel

int Add(int a, int b)
{}
int Sub(int a,int b)
{}
int Mul(int a, int b)
{}
int Div(int a, int b)
{}
int calc(int(*p)(int,int))
{
	return p(1, 2);
}
int main()
{
	calc(Add);
	return 0;
}

Lorsqu'il existe plusieurs fonctions avec le même paramètre et le même type de retour, des pointeurs de fonction peuvent être utilisés pour appeler ces fonctions à la demande afin de réduire la redondance du code.

Huit, tableau de pointeurs de fonction - objectif : table de transfert

Un tableau de pointeurs de fonction est un tableau de pointeurs de fonction.

int Add(int a, int b)
{}
int Sub(int a,int b)
{}
int Mul(int a, int b)
{}
int Div(int a, int b)
{}
int main()
{
	int input,x,y;
    scanf("%d%d%d",&input,&x,&y);
    //int(*p)(int, int) = Add;
	int(*arr[4])(int,int) = {Add,Sub,Mul,Div};//数组arr的类型直接将函数指针的p替换即可
    int ret=arr[input](x,y);//使用函数指针数组对函数进行调用——转移表
	for (int i = 0; i < 4; i++)//函数指针数组的遍历调用
	{
		int ret = arr[i](8, 4);
    }
	return 0;
}

Le tableau de pointeurs de fonction peut être utilisé pour appeler des fonctions avec les mêmes paramètres formels et les mêmes types de retour, et la fonction de saut de la fonction peut être réalisée en utilisation réelle, elle s'appelle donc une table de transfert et a une grande valeur d'utilisation.

Neuf, pointeur de tableau de pointeur de fonction

int main()
{
    int(*p)(int, int) = Add;//p是函数指针
	int(*arr[4])(int,int) = {Add,Sub,Mul,Div};//arr是函数指针数组
    int(*(*parr))(int,int)=&arr//parr是函数指针数组指针
	return 0;
}

Le procédé d'écriture peut imiter l'écriture selon le type de pointeur/tableau de niveau supérieur.

Je suppose que tu aimes

Origine blog.csdn.net/gfdxx/article/details/125128344
conseillé
Classement