-1
votes

Pourquoi les fonctions char nécessitent-elles de devenir un pointeur lors du retour d'une chaîne?

Je suis un programmeur C débutant et j'ai des difficultés à saisir le concept de pointeurs. Ma question est pourquoi le programme nécessite char *lowercase pour fonctionner normalement et pourquoi, si je supprime le * , il casse le programme?

char *lowercase(char a[]){
int c = 0;
char *lowercase_string = malloc(300);
strcpy(lowercase_string,a);
while (lowercase_string[c] != '\0') {
    if( lowercase_string[c] >= 'A' && lowercase_string[c] <= 'Z' ){
        lowercase_string[c] = lowercase_string[c]+32;
    }
    c++;
 }
 return lowercase_string;
 } 


3 commentaires

Si vous supprimez le * vous obtenez une fonction renvoyant un seul caractère. Comment retourneriez-vous une chaîne alors?


Je comprends ce que vous essayez de dire et maintenant je me rends compte que c'était une question stupide, mais merci beaucoup de m'avoir aidé. Bonne journée!


Ne t'inquiète pas. Cela fait partie de l'apprentissage. ;)


4 Réponses :


2
votes

En C, les chaînes ne sont que des morceaux contigus de caractères, se terminant par un octet nul (le caractère avec une valeur de 0, noté '\0' ou '\x00' ). Pour représenter une chaîne, un pointeur vers le premier élément est utilisé, ce que signifie l'étoile après char. Lorsque vous renvoyez un pointeur, vous retournez où se trouve la chaîne et les utilisateurs peuvent utiliser ces informations pour obtenir la chaîne entière simplement en l'itérant (en l'ajoutant au pointeur / en regardant au-delà) jusqu'à ce qu'ils trouvent un octet nul. Si vous renvoyez simplement char , vous ne pouvez renvoyer qu'un seul caractère de la chaîne, qui n'est nulle part proche de la chaîne complète.


2 commentaires

Je pense que vous pouvez souligner que le pointeur renvoie l'adresse mémoire (de la séquence de caractères), tandis que char est en fait une valeur.


Maintenant que vous l'avez expliqué, cela a beaucoup plus de sens. Merci beaucoup et bonne journée!



-2
votes

Votre programme renvoie un pointeur, vous devez donc appeler la fonction avec char *.

Et vous savez, dans ca char, le tableau est également traité comme un pointeur de char


1 commentaires

Non, les tableaux de caractères ne sont pas traités comme des pointeurs, c'est une simplification générale, ce qui est généralement faux.



0
votes

Comme indiqué dans les réponses précédentes, le pointeur char pointe vers la première lettre de la chaîne, ce qui vous permet de parcourir toute la chaîne (en déplaçant 1 caractère à la fois).

De plus, puisque votre chaîne est allouée sur le tas, elle doit être accédée via un pointeur, car le bloc de mémoire alloué est sans nom.


0 commentaires

0
votes

La racine du problème est de savoir comment C traite les tableaux (pas seulement les tableaux de type caractère, mais tout type).

Les tableaux ne sont pas des pointeurs - ce sont des séquences contiguës d'objets d'un certain type. Aucun pointeur ne fait partie de l'objet tableau lui-même. Lorsque vous déclarez un tableau comme int arr[5]; , vous obtenez quelque chose comme ceci en mémoire:

int (*foo( void ))[10];

Cependant, à moins qu'il ne s'agisse de l'opérande des opérateurs sizeof ou unaire & ou d'un littéral de chaîne utilisé pour initialiser un tableau de caractères dans une déclaration, une expression de type "Tableau à N éléments de T " sera convertie ("décroissance") en une expression de type "pointeur vers T " et la valeur de l'expression sera l'adresse du premier élément du tableau.

Lorsque vous passez un argument de tableau à une fonction, ce que la fonction reçoit réellement est un pointeur vers le premier élément. Lorsque vous tentez de renvoyer un tableau à partir d'une fonction, cette expression de tableau sera convertie en pointeur (nous en parlerons plus tard). En fait, vous ne pouvez pas déclarer une fonction pour renvoyer un type de tableau - quelque chose comme

int foo( void )[10];

n'est pas autorisé. Vous pouvez renvoyer des pointeurs vers des tableaux:

     +–––+
arr: |   | arr[0]
     +–––+
     |   | arr[1]
     +–––+
      ...
     +–––+
     |   | arr[4]
     +–––+

mais pas directement des tableaux. C'est pourquoi les fonctions *alloc renvoient des pointeurs au lieu de types de tableaux.

C'est aussi pourquoi retourner des tableaux locaux non static partir d'une fonction est un problème - vous ne renvoyez pas la valeur du tableau (c'est-à-dire une copie du contenu du tableau), vous renvoyez son adresse . Après le retour de la fonction, cependant, ce tableau n'existe plus et cette valeur de pointeur n'est pas valide . C'est pourquoi vous devez utiliser malloc pour allouer du stockage qui restera en place après le retour de la fonction.

Les chaînes sont des séquences de valeurs de caractères comprenant un terminateur de valeur zéro. La chaîne "hello" est représentée par la séquence {'h', 'e', 'l', 'l’, 'o', 0} . Les chaînes (y compris les chaînes littérales) sont stockées dans des tableaux de type caractère ( char pour les encodages ASCII, EBCDIC et UTF-8, wchar_t pour les encodages "larges" comme UTF-16).

Donc, c'est tout le fond. Dans votre cas spécifique, vous devez déclarer les lowercase comme char * car il renvoie une valeur de ce type ( lowercase_string ). Il s'arrête lorsque vous laissez le * désactivé parce que vous dites au reste du programme qu'il renvoie une valeur de caractère unique , pas un pointeur, et le reste du programme s'attend à ce qu'il renvoie un pointeur.


0 commentaires