当前位置:网站首页>L'étape avancée du pointeur de langage C (haut de gamme) pour l'enroulement des cocons
L'étape avancée du pointeur de langage C (haut de gamme) pour l'enroulement des cocons
2022-07-07 07:17:00 【ℓ blanc ℓ noir ℓ】
L'avancement du pointeur
1. Pointeur de caractères
Parmi les types de pointeurs, nous connaissons un type de pointeur qui est un pointeur de caractère char*
Utilisation générale:
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
Une autre utilisation est la suivante::
int main()
{
const char* pstr = "hello baiye.";//Voici une chaîne de caractères à mettre danspstrEst - ce que la variable pointeur est dans?
printf("%s\n", pstr);
return 0;
}
Code const char* pstr = “hello baiye.”;
Il est particulièrement facile de penser que c'est une chaîne hello bit Placez le pointeur de caractères pstr C'est parti.,Mais/L'essence est de mettre une chaîne hello baiye. L'adresse du premier caractère est placée danspstrMoyenne.
Le code ci - dessus signifie mettre le premier caractère d'une chaîne constante h L'adresse est stockée dans la variable pointeur pstr Moyenne.
2. Tableau de pointeurs
Nous vous avons déjà présenté ,Il n'y a pas grand - chose à dire ici.
int* arr1[10]; //Tableau des pointeurs de forme
char *arr2[4]; //Tableau des pointeurs de caractères L1
char **arr3[5];//Tableau des pointeurs de caractères L2
3. Pointeur de tableau
3.1 Définition du pointeur de tableau
Un pointeur de tableau est un pointeur?Ou un tableau?
La réponse est::Pointeur.
Nous connaissons déjà:
Pointeur de forme: int * pint; Pointeur capable de pointer vers les données de façonnage.
Pointeur flottant: float * pf; Pointeur capable de pointer vers des données flottantes.
Ce pointeur de tableau devrait être:Pointeur capable de pointer vers un tableau.
Lequel des codes suivants est un pointeur de tableau?
int *p1[10];
int (*p2)[10];
//p1, p2Quelle est la différence??
P1:Est un tableau de pointeurs.
P2:
//Explication:pD'abord.*Union,DescriptionpEst une variable pointeur,Puis pointez vers une taille de10Un tableau entier.Alors...pEst un pointeur,Pointez vers un tableau,Appelle un pointeur de tableau.
//Attention ici.:[ ]Priorité supérieure à*No.,Il faut donc ajouter()Pour garantirpD'abord.*Union.
3.2 &Nom du tableauVSNom du tableau
Regardons un code:
#include <stdio.h>
int main()
{
int arr[10] = {
0};
printf("%p\n", arr);
printf("%p\n", &arr);
return 0;
}
arr Et &arr Qu'est - ce que?
Nous savons quearrEst le nom du tableau,Le tableau des noms de tableaux indique l'adresse du premier élément du tableau.
C'est...&arrQuel est exactement le nom du tableau?
Commençons par courir et voir les résultats :
Nom du tableau visible et&L'adresse imprimée du nom du tableau est la même.
Les deux sont - ils pareils??
Regardons un autre morceau de code.:
#include <stdio.h>
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ésultats des opérations:
D'après le code ci - dessus, nous avons trouvé,En fait...&arrEtarr,Bien que la valeur soit la même,Mais le sens devrait être différent.
En fait,: &arr Indique l'adresse du tableau,Au lieu de l'adresse du premier élément du tableau.(Faites l'expérience)
Dans ce cas, &arr Le type de: int(*)[10] ,Est un type de pointeur de tableau
Adresse du tableau+1,Sauter la taille du tableau entier,Alors... &arr+1 Par rapport à &arr La différence est40.
3.3 Utilisation de pointeurs de tableau
Comment les pointeurs de tableau sont - ils utilisés??
Puisque le pointeur du tableau pointe vers le tableau,Ce pointeur de tableau devrait contenir l'adresse du tableau.
Regarde le Code.:
#include <stdio.h>
int main()
{
int arr[10] = {
1,2,3,4,5,6,7,8,9,0 };
int(*p)[10] = &arr;//ArrayarrL'adresse de est assignée à la variable de pointeur de tableaup
//Mais nous écrivons rarement le Code comme ça
return 0;
}
Utilisation d'un pointeur de tableau:
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print_arr2(int(*arr)[5], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {
1,2,3,4,5,6,7,8,9,10 };
print_arr1(arr, 3, 5);
//Nom du tableauarr,Indique l'adresse du premier élément
//Mais le premier élément d'un tableau bidimensionnel est la première ligne d'un tableau bidimensionnel
//Donc ce qui est passé iciarr,En fait, c'est l'adresse de la première ligne,C'est l'adresse d'un tableau unidimensionnel
//Peut recevoir un pointeur de tableau
print_arr2(arr, 3, 5);
return 0;
}
Regardons les résultats de l'opération :
Alors,Que signifie ce code??
int (*parr3[10])[5];
Tout d'abord,parr3Et[10]Union, Ça veut dire un tableau , Le tableau manque encore un type ,Le reste.int(*)[5]C'est le genre.,Dans l'ensembleparr3 Est un tableau qui contient un pointeur de tableau .
4. Paramètres du tableau、Paramètres du pointeur
Il est difficile d'écrire un code avec【Tableau】Ou【Pointeur】Passer à la fonction,Comment concevoir les paramètres de la fonction?
4.1 Paramètre de transfert de tableau unidimensionnel
#include <stdio.h>
void test(int arr[])//ok?
{
}
void test(int arr[10])//ok?
{
}
void test(int* arr)//ok?
{
}
void test2(int* arr[20])//ok?
{
}
void test2(int** arr)//ok?
{
}
int main()
{
int arr[10] = {
0 };
int* arr2[20] = {
0 };
test(arr);
test2(arr2);
}
C'est tout ce qui est juste .
Le premier est l'écriture du tableau ,Deuxième[] Il n'y a pas de chiffres dedans .
Le troisième est l'adresse , J'ai déjà dit que le nom du tableau est l'adresse du premier élément ,C'est aussi un type.,Donc, oui..
Le quatrième paramètre est le même que l'argument .
Le cinquième est acceptable avec un pointeur secondaire ,Parce que l'argument est un tableau de pointeurs,Le nom du tableau est l'adresse du premier élément, Et les éléments sont des pointeurs , Nous savons aussi que le pointeur secondaire est l'adresse où le pointeur primaire est stocké , C'est un genre de .
4.2 Paramètres de transfert du tableau 2D
void test(int arr[3][5])//ok?
{
}
void test(int arr[][])//ok?
{
}
void test(int arr[][5])//ok?
{
}
//Résumé:Paramètres de transfert du tableau 2D,La conception d'un paramètre de fonction ne peut omettre que le premier[]Nombre de.
//Parce que pour un tableau bidimensionnel,Je ne sais pas combien de lignes.,Mais il faut savoir combien d'éléments sur une ligne.
//C'est pour faciliter les calculs..
void test(int* arr)//ok?
{
}
void test(int* arr[5])//ok?
{
}
void test(int(*arr)[5])//ok?
{
}
void test(int** arr)//ok?
{
}
int main()
{
int arr[3][5] = {
0 };
test(arr);
}
Le premier peut, Parce que le passé est un tableau bidimensionnel , Accepter avec un tableau bidimensionnel ,Donc, oui..
Le second ne peut pas, Parce qu'un tableau bidimensionnel peut omettre des lignes ,Impossible d'omettre les colonnes.
Le troisième peut .
Le quatrième ne peut pas ,Parce quearr Est l'adresse du premier élément représentant un tableau bidimensionnel , Représente également la première ligne du tableau ,C'est un tableau unidimensionnel., Donc vous ne pouvez pas recevoir avec un pointeur entier .
Le cinquième non plus , Parce que c'est un tableau de pointeurs ,Pas un type.
Le sixième pourrait , Parce que c'est un pointeur de tableau qui reçoit un tableau unidimensionnel .
Le septième ne peut pas , L'adresse d'un tableau unidimensionnel ne peut pas être placée dans un pointeur secondaire .
4.3 Paramètre de transfert du pointeur primaire
#include <stdio.h>
void print(int* p, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d\n", *(p + i));
}
}
int main()
{
int arr[10] = {
1,2,3,4,5,6,7,8,9 };
int* p = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
//Pointeur primairep,Passer à la fonction
print(p, sz);
return 0;
}
Résultats des opérations:
4.4 Paramètre de transfert du pointeur secondaire
#include <stdio.h>
void test(int** ptr) {
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0; }
Le résultat de l'opération est:
5. Pointeur de fonction
Alors, La fonction doit aussi avoir une adresse , Il y a aussi un pointeur correspondant pour recevoir l'adresse de la fonction .
Regardez d'abord un morceau de code:
#include <stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
Résultats de l'exécution du Code:
La sortie est deux adresses,Ces deux adresses sont test L'adresse de la fonction.
Cela signifie que le nom de la fonction est l'adresse de la fonction .
Donc l'adresse de notre fonction doit être sauvegardée,Comment conserver?
Voyons le Code.:
void test()
{
printf("hehe\n");
}
//En baspfun1Etpfun2Qui a la capacité de stockertestL'adresse de la fonction?
void (*pfun1)();
void* pfun2();
Tout d'abord,,Peut donner l'adresse de stockage,Juste une demande.pfun1Oupfun2C'est un pointeur.,Lequel est le pointeur?
La réponse est::
pfun1Peut être stocké.pfun1D'abord.*Union,Descriptionpfun1C'est un pointeur.,Le pointeur pointe vers une fonction,La fonction pointée n'a pas de paramètres
Nombre,Le type de valeur de retour estvoid.
6. Tableau des pointeurs de fonction
Un tableau est un espace de stockage pour le même type de données,Alors nous avons appris le tableau des pointeurs,
Par exemple,:
int *arr[10];
//Chaque élément du tableau estint*
Il faut enregistrer l'adresse de la fonction dans un tableau,Ce tableau s'appelle un tableau de pointeurs de fonction,Comment définir un tableau de pointeurs de fonction?
int (*parr1[10])();
int *parr2[10]();
int (*)() parr3[10];
La réponse est::parr1
parr1 D'abord. [] Union,Description parr1Est un tableau,Quel est le contenu du tableau?
- Oui. int (*)() Pointeur de fonction de type.
Quant à l'utilisation du pointeur de fonction :
Écrire une calculatrice
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
int mul(int a, int b) {
return a * b;
}
int div(int a, int b) {
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = {
0, add, sub, mul, div }; //Tableau des transferts
while (input)
{
printf("*************************\n");
printf(" 1:add2:sub \n");
printf(" 3:mul4:div \n");
printf("*************************\n");
printf("Veuillez sélectionner:");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("Saisissez un opérande:");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf("Erreur d'entrée\n");
printf("ret = %d\n", ret);
}
return 0;
}
Ici, nous voyons, Après avoir sélectionné l'algorithme , Cela équivaut à sélectionner un pointeur de fonction dans le tableau , Directement dans la fonction d'opération ci - dessus .
C'est plus pratique.
7. Pointeur vers un tableau de pointeurs de fonctions
Un pointeur vers un tableau de pointeurs de fonction est un pointeur,
Pointeur vers un Tableau ,Les éléments du tableau sont tous des pointeurs de fonctions ;
Comment définir?
#include <stdio.h>
void test(const char* str)
{
printf("%s\n", str);
}
int main()
{
//Pointeur de fonctionpfun
void (*pfun)(const char*) = test;
//Tableau des pointeurs de fonctionspfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
//Pointer vers un tableau de pointeurs de fonctionpfunArrPointeur versppfunArr
void (*(*ppfunArr)[5])(const char*) = &pfunArr;
return 0;
}
Ha Ha!, C'est le costume.
8. Fonction de rappel
Une fonction de rappel est une fonction appelée par un pointeur de fonction.Si vous pointez une fonction(Adresse)Passer comme paramètre à un autre
Fonctions,Quand ce pointeur est utilisé pour appeler la fonction qu'il pointe,Disons que c'est une fonction de rappel.La fonction de rappel n'est pas générée par cette fonction
Appelé directement par l'implémentateur de,Mais appelé par l'autre partie au moment où un événement ou une condition particulier se produit,Utilisé pour entrer dans l'événement ou la condition
Réponse en ligne.
Montre - moi d'abordqsort( Cliquez ici pour plus de détails qsortFonctions)Utilisation des fonctions:
#include <stdio.h>
#include <stdlib.h>
//qosrtL'utilisateur de la fonction doit implémenter une fonction de comparaison
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
int main()
{
int arr[] = {
1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
int i = 0;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
Résultat de l'exécution du Code:
Ici, nous pouvons simuler avec des fonctions de tri et de rappel des bulles qsortFonctions.
En bas.void* N'a pas de pointeur de type spécifique , Le but est de pouvoir recevoir n'importe quel type de pointeur , Peut également être assigné à n'importe quel type de pointeur .
#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);//Avecchar Pointeur de type parce que la longueur est 1Octets, Peu importe ce qu'on va faire intType ouling Les types sont tous un octet et un octet plus .
*((char*)p2 + i) = tmp;
}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))// Voici la fonction de rappel .
{
int i = 0;
int j = 0;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
int main()
{
int arr[] = {
1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
int i = 0;
bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
Le code fonctionne comme suit:
Conclusion
Ici, nousC Le pointeur de la langue est terminé , Parce qu'il y avait un chapitre de base sur les pointeurs , Le nombre de mots dans ce chapitre est donc insuffisant .
S'il vous plaît, pointez les erreurs et les lacunes , Si vous pensez que l'article est bon, demandez à votre famille de faire un compliment !!!
边栏推荐
- Precise space-time travel flow regulation system - ultra-high precision positioning system based on UWB
- 弹性布局(一)
- Software acceptance test
- 关于二进制无法精确表示小数
- Mysql---- import and export & View & Index & execution plan
- FPGA course: application scenario of jesd204b (dry goods sharing)
- Flexible layout (I)
- 点亮显示屏的几个重要步骤
- Tool class: object to map hump to underline underline hump
- $refs:组件中获取元素对象或者子组件实例:
猜你喜欢
"Xiaodeng in operation and maintenance" meets the compliance requirements of gdpr
Bus message bus
Fast quantitative, abbkine protein quantitative kit BCA method is coming!
组件的嵌套和拆分
Communication between non parent and child components
LC 面试题 02.07. 链表相交 & LC142. 环形链表II
Kuboard can't send email and nail alarm problem is solved
.net core 访问不常见的静态文件类型(MIME 类型)
AVL树的实现
Unity3d learning notes
随机推荐
About binary cannot express decimals accurately
linux系统rpm方式安装的mysql启动失败
父组件传递给子组件:Props
Freeswitch dials extension number source code tracking
The currently released SKU (sales specification) information contains words that are suspected to have nothing to do with baby
请教一个问题,flink oracle cdc,读取一个没有更新操作的表,隔十几秒就重复读取全量数据
Brand · consultation standardization
Pass parent component to child component: props
Kuboard无法发送邮件和钉钉告警问题解决
OOM(内存溢出)造成原因及解决方案
Modify the jupyter notebook file path
Détailler le bleu dans les tâches de traduction automatique
点亮显示屏的几个重要步骤
AVL树的实现
Abnova circulating tumor DNA whole blood isolation, genomic DNA extraction and analysis
Matlab tips (30) nonlinear fitting lsqcurefit
計算機服務中缺失MySQL服務
Sqlserver multithreaded query problem
Graduation design game mall
Role of virtual machine