81 votes

Quelle est la particularité des structs ?

Je sais qu'en C, on ne peut pas retourner un tableau à partir d'une fonction, mais un pointeur vers un tableau. Mais je veux savoir ce qu'il y a de particulier dans le cas de structs qui les rend retournables par les fonctions, même s'ils contiennent des tableaux.

Pourquoi le struct L'emballage rend le programme suivant valide ?

#include <stdio.h>

struct data {
    char buf[256];
};

struct data Foo(const char *buf);

int main(void)
{
    struct data obj;
    obj = Foo("This is a sentence.");
    printf("%s\n", obj.buf);
    return 0;
}

struct data Foo(const char *buf)
{
    struct data X;
    strcpy(X.buf, buf);
    return X;
}

100voto

dasblinkenlight Points 264350

Une meilleure façon de poser la même question serait "qu'est-ce que les tableaux ont de spécial", car ce sont les tableaux qui ont un traitement spécial qui leur est attaché, et non pas les struct s.

Le comportement consistant à transmettre et à retourner des tableaux par pointeur remonte à l'implémentation originale du langage C. Les tableaux "se décomposent" en pointeurs, ce qui entraîne une grande confusion, en particulier chez les novices du langage. Les structures, en revanche, se comportent exactement comme les types intégrés, tels que int s, double s, etc. Cela inclut tous les tableaux intégrés dans le struct sauf pour membres du réseau flexible qui ne sont pas copiés.

38voto

Sourav Ghosh Points 54713

Tout d'abord, pour citer C11 , chapitre §6.8.6.4, return déclaration, ( c'est moi qui souligne )

Si un return avec une expression est exécutée, l'instruction la valeur de l'expression est retournée à l'appelant en tant que valeur de l'expression d'appel de fonction.

Renvoyer une variable de structure est possible (et correct), car la structure valeur est renvoyé. Ceci est similaire au retour de n'importe quel type de données primitives (retour de int par exemple).

D'autre part, si vous renvoyez un tableau en utilisant le return <array_name> il renvoie essentiellement le adresse du premier élément du tableau NOTE ce qui devient invalide pour l'appelant si le tableau était local aux fonctions appelées. Donc, retourner un tableau de cette manière n'est pas possible.

Donc, TL;DR il n'y a rien spécial avec struct la spécialité est dans tableaux .


NOTE :

Citation : C11 à nouveau, chapitre §6.3.2.1, ( mon accent )

Sauf lorsqu'il s'agit de l'opérande de la fonction sizeof l'opérateur, le _Alignof ou l'opérateur unaire & ou est une chaîne littérale utilisée pour initialiser un tableau, une expression qui a type ''tableau de type'' est converti en une expression de type ''pointeur vers le type'' qui pointe vers l'élément initial de l'objet tableau et n'est pas une lvalue. [...]

11voto

John Bode Points 33046

Il n'y a rien de spécial à propos struct c'est qu'il y a quelque chose de spécial à propos de tableau qui les empêche d'être renvoyés directement par une fonction.

A struct est traitée comme une expression de n'importe quel autre type hors tableau ; elle est évaluée à l'indice valeur de la struct . Vous pouvez donc faire des choses comme

struct foo { ... };

struct foo func( void )
{
  struct foo someFoo;
  ...
  return someFoo;
}

L'expression someFoo évalue à la valeur de la struct foo le contenu de l'objet est renvoyé par la fonction (même si ce contenu contient des tableaux).

Une expression de tableau est traitée différemment ; si elle n'est pas l'opérande de la fonction sizeof ou unaire & ou s'il ne s'agit pas d'un littéral de chaîne utilisé pour initialiser un autre tableau dans une déclaration, l'expression est convertie ("se désintègre") du type "tableau de T "en "pointeur vers T ", et la valeur de l'expression est l'adresse du premier élément.

Vous ne pouvez donc pas retourner un tableau par valeur à partir d'une fonction, car toute référence à une expression de tableau est automatiquement convertie en valeur de pointeur.

-5voto

hoh Points 1

Les structures ont des membres de données publiques par défaut, il est donc possible dans le cas d'une structure d'accéder aux données dans le main mais pas dans le cas d'une classe. Ainsi, le wrapping de struct est valide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X