2011-07-16 8 views
0

Le code donné ici lorsqu'il est compilé par g ++ s'exécute correctement mais donne une erreur lors de la compilation avec gcc. De toute évidence, cela est correct pour C++, mais pas pour C. S'il vous plaît aidez-moi à corriger la syntaxe C.Différence entre C et C++

# include <stdio.h> 
typedef struct demo 
{ 
    int arr[20], i; 
    void setvalue(int num) 
    {for(i=0;i<20;i++)arr[i]=num;} 

    void printvalue() 
    {for(i=0;i<20;i++)printf("%d ",arr[i]);} 
} example; 

int main() 
{ 
    example e; 
    e.setvalue(100); 
    e.printvalue(); 
    return 0; 
} 

journal d'erreur:

stov.c:7:2: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘{’ token 
stov.c: In function ‘main’: 
stov.c:18:3: error: ‘example’ has no member named ‘setvalue’ 
stov.c:19:3: error: ‘example’ has no member named ‘printvalue’ 
+1

Ce serait bien quand poser de telles questions pour nous dire ce que l'erreur est. – Bart

+7

Votre barre d'espace est-elle brisée? Et votre clé d'entrée un peu douteuse? –

+4

Je ne l'ai pas downvote, mais je compris ceux qui ont fait: C et C++ sont fondamentalement différents, et votre question n'a pas de sens; vous demandez essentiellement "J'ai fait X, pourquoi Y n'est pas lié?" Souhaitez-vous que votre code fonctionne sur un compilateur Pascal? En JavaScript? En Haskell? Certainement pas. Alors pourquoi devrait-il fonctionner en C? La confusion commune et déraisonnable de C et C++ est vraiment assez fastidieuse. –

Répondre

10

Vous ne pouvez pas avoir des méthodes en C (cette fonction dans la structure). Il y a plus d'une façon de résoudre ce problème, mais je voudrais simplement passer l'objet comme premier argument à la fonction:

void setvalue(struct demo *d, int num) 
{ 
    int i; 
    for(i = 0; i < 20; i++) 
     d->arr[i] = num; 
} 


/* ... */ 
setvalue(&e, 100); 
+1

vous ne pouvez pas avoir de méthodes en C++ non plus. (fonctions membres) –

+5

@Cory, bien sûr que vous pouvez? Les fonctions membres sont l'une des plus grandes différences entre C et C++ ... – bdonlan

+6

@bdonlan: Je pense que Cory est très pointilleux et fait remarquer qu'en C++, les méthodes sont appelées * fonctions membres, ce qui est un point valide, mais pas réellement utile. :) –

2

Voici votre problème: Votre struct contient des méthodes. Ce n'est pas bon dans C.

En C++ un struct est la plupart du temps comme un class (ou plutôt, un class est la plupart du temps comme un struct), et peut avoir des méthodes, etc.

En C, cela ne concerne pas .

1

Vous pouvez utiliser des pointeurs de fonction dans struct pour émuler OOP.

typedef struct demo 
{ 
    int arr[20], i; 
    void (*setvalue)(int num); 

    void (*printvalue)(); 
} example; 

Ensuite, vous pouvez affecter une fonction au pointeur de fonction.

void set_val(int num) {for(i=0;i<20;i++)arr[i]=num;} 
example_struct.setvalue = set_val; 
0

Je voudrais souligner que C ont une fonction pointeurs et fonction des pointeurs peuvent être utilisés comme des fonctions membres C++, en quelque sorte. La syntaxe maladroite peut être évitée avec certains macros et modèles de préprocesseur C (vous pouvez utiliser le préprocesseur C pour la programmation générique, il est plus puissant et plus polyvalent que les templates C++, donne un meilleur contrôle de type et (sur les compilateurs modernes) truc utilisé pour être appelé livres de code par les programmeurs Algol et COBOL (je l'ai appris pendant un cours COBOL dans ma jeunesse), mais ont été évités par les programmeurs C pour une raison stupide).

code non testé, juste bricolé à partir du code dans la question:

# include <stdio.h> 
static void _setvalue(example *obj, int num) 
{ int i; 
    for(i=0;i<20;i++) 
     obj->arr[i]=num; 
} 

static void _printvalue(example *obj) 
{ int i; 
    for(i=0;i<20;i++) 
     printf("%d ", obj->arr[i]); 
} 


typedef struct demo 
{ int arr[20], i; 
    void (*const setvalue)(example *, int) = _setvalue; 
    void (*const printvalue)(example *) = _printvalue; 
} example; 

int main() 
{ example e; 
    e.setvalue(&e, 100); 
    e.printvalue(&e); 
    return 0; 
}