Explication détaillée de sizeof et strlen (plateforme 64 bits)
Comparaison de sizeof et strlen
sizeof()
Calculer la taille de l'espace mémoire occupé par les variables,L'unité est l'octet, si l'opérande est de type, le calcul estLa taille de l'espace mémoire occupé par les variables créées à l'aide du type。
sizeof ()
Faites uniquement attention à la taille de l'espace mémoire occupé, et non aux données stockées dans la mémoire.。strlen()
Il s'agit d'une fonction de bibliothèque en langage C dont la fonction est de trouver la longueur d'une chaîne. Prototype de fonction :
size_t strlen ( const char * str );
Les statistiques sont le nombre de caractères de la chaîne précédente à partir de l'adresse en strlen()
paramètre de la fonction . La fonction continuera à rechercher des caractères jusqu'à ce qu'ils soient trouvés, il peut donc y avoir une recherche hors limites.str
\0
strlen()
\0
Pensons ensuite à strlen()
ce qui se passera si nous passons un personnage à? Veuillez voir ci-dessous pour plus de détails strlen(*arr)
, nous parlerons de cas réels à ce moment-là ! ! !
Pensons ensuite à strlen()
ce qui se passe si nous transmettons une adresse de tableau à? Veuillez voir ci-dessous pour plus de détails strlen(&arr)
, nous parlerons de cas réels à ce moment-là ! ! !
Il y a un autre point très important avant de commencer l'introduction suivante,La signification des noms de tableaux :
3.taille de (nom du tableau), le nom du tableau représente ici l'ensemble du tableau,Calcule la taille de l'ensemble du tableau。
4.&nom du tableau, le nom du tableau représente ici l'ensemble du tableau,Ce qui est supprimé, c'est l'adresse de l'ensemble du tableau。5
.De plus, tous les noms de tableaux représentent l’adresse du premier élément.。
Calculer un tableau unidimensionnel
tableau d'entiers
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));
Jetons d'abord un coup d'œil aux résultats de sortie :
1. sizeof(a);
//sizeof(array name) calcule la taille totale du tableau -= unité octets-16
2. sizeof(a+0);
//Quelqu'un doit vouloir demander si le précédent faisait encore 16 octets, pourquoi devient-il 8 ici ? En fait, c'est a+0
une expression qui ne satisfait pas la forme de sizeof (nom du tableau), donc voici a
toujours l'adresse du premier élément, a+0
et l'adresse du premier élément, et la taille de l'adresse est4 / 8Octet
3. sizeof(*a);
//Voici a
l'adresse du premier élément, *a
c'est donc la taille du type ( int
) du premier élément, qui est4
4. sizeof(a+1);
//Voici a
l'adresse du premier élément, qui a+1
est l'adresse du deuxième élément. Analogue à 2., c'est4 / 8Octets
5. sizeof(a[1]);
//La taille du deuxième élément,4
6. sizeof(&a);
// &a
Ce qui est supprimé est l'adresse du tableau, toutes les adresses sont4 / 8
7. sizeof(*&a);
// C'est l'adresse du &a
tableau . Après déréférencement, c'est le tableau . La taille du tableau est calculée ici.a
*
a
16Octet
8... sizeof(&a+1);
//Sur la base de ce qui précède, il n'est pas difficile d'imaginer que cela &a+1
équivaut à &a
sauter un tableau, mais c'est toujours une adresse.4 / 8Octet
9... sizeof(&a[0]);
//Adresse du premier élément,4 / 8Octet
10... sizeof(&a[0]+1);
//L'adresse du deuxième élément,4 / 8octet
tableau de caractères
L’utilisation des tableaux de caractères et des tableaux d’entiers sizeof()
est très similaire, je ne les présenterai donc pas en détail ici !
char arr[] = {
'a','b','c','d','e','f' };
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));
Résultats d'exécution :
1. strlen(arr);
2.strlen(arr+0);
On voit que ce tableau de caractères ne se '\0'
termine pas par, donc strlen()
lors du calcul de l'adresse du premier élément, une valeur aléatoire est générée ! Donc la première et la seconde sont des valeurs aléatoires !
3. strlen(*arr);
4. strlen(arr[1]);
Au début, nous avons introduit que strlen()
la fonction reçoit une adresse. Voici *arr
le premier élément du tableau et arr[1]
le deuxième élément du tableau. Le compilateur signalera donc une erreur. On peut aussi entrer plus en détail : puisque ce qui strlen()
est reçu est une adresse, *arr
mais un caractère a
, ASCII
la valeur de la table est 97. A ce moment, strlen()
97 sera considéré comme une adresse pour accéder à l'espace, mais cette adresse n'est pas la l'espace que nous possédons, ce qui constitue un accès illégal.
Il 0x0000000000000061
s’agit en réalité de 97, ce qui confirme notre affirmation.
5. strlen(&arr);
6. strlen(&arr+1);
7. strlen(&arr[0]+1);
&arr
, &arr+1
, &arr[0]+1
sont en fait des adresses. Bien que la première soit l'adresse d'un tableau, son adresse est la même que l'adresse du premier élément, elle est doncvaleur aléatoire, le second saute un tableau, tout commeValeur aléatoire -6, 6 est la taille du tableau, et le troisième pense qu'un élément du tableau a été ignoré, c'est doncValeur aléatoire -1.
On peut voir que bien &arr
qu'il s'agisse d'une adresse de tableau et que le type soit un pointeur de tableau char(*p)[6]
, en fait, il est simplement traité comme une adresse et n'affecte pas vraiment le résultat.
chaîne
char arr[]="abcdef";
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[0]+1));
Quand on voit ça, on pense vraiment à ça, n'est-ce pas char arr[] = { 'a','b','c','d','e','f' ,'\0'};
? C'est exact! La méthode de calcul ici sizeof()
est toujours la même que ci-dessus, mais strlen()
il faut quand même le préciser.
1. strlen(arr);
2. strlen(arr+0);
Puisqu’il y a '\0'
la fin, le résultat doit être la longueur de la chaîne, qui est6
3. strlen(&arr);
// Ceci renverra '\0'
le nombre de caractères précédent, qui est6
4. strlen(&arr+1);
//Mais &arr+1
le tableau est ignoré ici arr
, donc unvaleur aléatoire
5. strlen(&arr[0]+1);
//Cela pointe vers 'b'
l'adresse de , alors retournez5
Calculer une chaîne constante
char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
Est-ce qu'il est mis "abcdef"
à l'intérieur p
ici ? En fait, voici p
juste 'a'
l'adresse
1. sizeof(p);
//Voici p
l'adresse de la variable pointeur calculée.4 / 8Octet
2. sizeof(p+1);
// p+1
Ce qui est obtenu est 'b'
l'adresse du caractère,4 / 8Octet
3. sizeof(*p);
// *p
En fait, c'est le premier caractère de la chaîne 'a'
.1Octet
4. sizeof(p[0]);
//En fait, cela p[0]
équivaut *(p+0)
au premier élément,1Octet
5. sizeof(&p);
// L'adresse du &p
pointeur est p
extraite ici.4 / 8octet
char *p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
1. strlen(p);
//Comme analysé ci-dessus, l'adresse p
stockée est 'a'
l'adresse, et la fin strlen()
est trouvée '\0'
, donc c'est62. 3. // C'est l'adresse du pointeur. Ici, j'ai fait un dessin pour illustrer : Donc
ce que l'on trouve ici est en fait une valeur aléatoire !strlen(&p);
strlen(&p+1);
&p
p
Calculer un tableau bidimensionnel
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]));
Jetons un coup d'œil aux résultats générés par le compilateur ! ! ! Expliquons pourquoi.
1. sizeof(a);
//Le nom du tableau a
représente ici l'intégralité du tableau bidimensionnel, la taille est 12 4,36Octet
2. sizeof(a[0][0]);
//C'est le premier élément du tableau,4Octet
3. sizeof(a[0]);
// a[0]
C'est la première ligne du tableau bidimensionnel comme nom du tableau unidimensionnel, donc sizeof()
ce qui est recherché est la taille de la première ligne du tableau, la taille est 4 4,16Octet
4. sizeof(a[0]+1);
// Ceci a[0]
représente le nom du tableau de la première ligne, qui représente l'adresse du premier élément. En fait, c'est l'adresse du premier élément de la première ligne, donc il représente l'adresse a[0]+1
du deuxième élément de la première rangée.4 / 8Octet
5. sizeof(*(a[0]+1));
//Ce qui précède *a[0]+1
est le deuxième élément de la première ligne,4Octet
6. sizeof(a+1);
//Réfléchissons à l'adresse à qui appartient cette adresse ? a
est le nom du tableau à deux dimensions et est l'adresse du premier élément. Le premier élément du tableau à deux dimensions est sa première ligne, c'est donc l'adresse de la a
première ligne. Puis, après en avoir ajouté un, il est l'adresse de la deuxième ligne.4 / 8Octets
À partir de là, nous pouvons également voir que la différence entre les deux adresses est de 16, ce qui correspond exactement à la taille de 4 entiers, donc cela vérifie également ce qui précède. Après en avoir ajouté une, une ligne est sautée.
7. sizeof(*(a+1));
//Comme en 6., après déréférencement, il représente la deuxième ligne.16Octet
8. sizeof(&a[0]+1);
// &a[0]
Supprimez l'adresse de la première ligne, ajoutez-en une à l'adresse de la deuxième ligne,4 / 8Octet
9. sizeof(*(&a[0]+1));
//Déréférencement pour obtenir la deuxième ligne du tableau,16Octet
10. sizeof(*a);
// a
C'est l'adresse du premier élément, l'adresse de la première ligne, et c'est la première ligne après déréférencement.16Octet
11. sizeof(a[3]);
// a[3]
Il s'agit de la quatrième ligne du tableau. Bien qu'il n'y ait pas de quatrième ligne, selon le type de tableau, la taille calculée du tableau est de quatre entiers sur une ligne, elle est donc toujours16