Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

utilisation des opérateurs [] en C


Sujet :

C

  1. #1
    Membre habitué
    utilisation des opérateurs [] en C
    Bonjour à tous,

    Cela fait un petit moment que je n'ai pas touché au C au profit du C++, et, par simple curiosité, je me demandais comment il était possible d'appliquer l'opérateur '[]' à une structure ou autre dans ce langage.
    Par exemple, admettons que j'essaie de réaliser une structure de type vecteur comme suivant :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct vector {
     
    	float[] data;
    	size_t size;
     
    } vector;
     
     
    void setup(vector *src, size_t sz);

    **la syntaxe est probablement mauvaise mais l'idée reste la même

    Dans ce cas, si je créé un 'objet' de type vector, je serais obligé d'accéder aux valeurs par obj.data[x]... Quelle est alors la manière plus simple à l'utilisation pour réaliser de tels objets (vecteurs, tenseurs etc...) ?

    Au passage, cette question n'est pas anodine dans le sens où, j'ai cru comprendre a et là, que le C eut été (si ce n'est toujours le cas) un langage fort utilisé dans la communauté scientifique. J'imagine donc qu'il propose une certaine agilité dans le cadre de la réalisation de calculs tensoriels / matriciels, me trompe-je ?

    Merci d'avance.

  2. #2
    Expert éminent
    Ce n'est pas parce que que tu es en C, que tu ne peux pas avoir une approche objet

    Non testé et à l'arrache :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    typedef struct s_vector {
        float* data;
        size_t size;
    } t_vector;
     
     
    // vector->data is 0-indexed
    unsigned char vector_add(t_vector* vector, size_t index, float value) {
        unsigned char ret;
     
        if ((vector != NULL) && (vector->size > 0) && (index < vector->size)) {
            value->data[index] = value;
     
            ret = 1;
        } else {
            ret = 0;
        }
     
        return ret;
    }
     
     
    // vector->data is 0-indexed
    unsigned char vector_at(t_vector* vector, size_t index, float* value) {
        unsigned char ret;
     
        if ((vector != NULL) && (vector->size > 0) && (index < vector->size)) {
            (*value) = (value->data + index);
     
            ret = 1;
        } else {
            ret = 0;
        }
     
        return ret;
    }
     
     
    unsigned char vector_create(t_vector* vector, size_t size) {
        unsigned char ret;
     
        if ((vector != NULL) && (size > 0) && (vector->data  != NULL)) { // maybe destroy vector here
            vector->data = malloc(size * sizeof(float));
     
            if (vector->data != NULL) {
                vector->size = size;
                ret = 1;
            } else {
                ret = 0;
            }
        } else {
            ret = 0;
        }
     
        return ret;
    }
     
     
    void vector_destroy(t_vector* vector) {
        if (vector != NULL) {
            if (vector ->data != NULL) { free(vector ->data); }
     
            vector_init(vector);
        }
    }
     
     
    unsigned char vector_get_size(t_vector* vector, size_t* size) {
        unsigned char ret;
     
        if ((vector != NULL) && (size  != NULL)) {
            (*size) = vector->size;
     
            ret = 1;
        } else {
            ret = 0;
        }
     
        return ret;
    }
     
     
    void vector_init(t_vector* vector) {
        if (vector != NULL) {
            vector->data = NULL;
            vector->size = 0;
        }
    }
     
     
     
    // example
     
    #define TEST_AND_ADD(INDEX, VALUE, MESG) \
        if (has_no_error ) { \
            has_no_error = vector_add(&vector, INDEX, VALUE)); \
        } else { \
            /* error - MESG */ \
        }
     
        t_vector vector;
     
        vector_init(&vector);
     
        if ( vector_create(&vector, 4) ) {
            size_t index, vector_size;
            unsigned char has_no_error;
     
            has_no_error = vector_add(&vector, 0, 1.2));
     
            TEST_AND_ADD(1,  2.5, "vector_add index 0");
            TEST_AND_ADD(2, 15.8, "vector_add index 1");
            TEST_AND_ADD(3, 75.0, "vector_add index 2");
     
            if (has_no_error ) {
                has_no_error = vector_get_size(&vector, &vector_size);
            } else {
                /* error - vector_add index 3 */
            }
     
            if ((has_no_error ) && (vector_size > 0)) {
                float value;
     
                for(index=0; index < vector_size; ++index) {
                    if (vector_at(&vector, index, &float value) {
                        printf("%02d: %f", (index + 1), value);
                    } else {
                        printf("%02d: error", (index + 1));
                    }
                }
           } else {
                /* error - get_size or size == 0 */ \
           }
     
           vector_destroy(&vector);
        } else {
            /* error - vector_create */ \
        }

  3. #3
    Membre habitué
    Merci pour ces quelques rappels de C
    Par contre, j'entends bien cette fameuse approche "objet" mais je me demandais juste s'il y avait un moyen d'accéder aux valeurs de mon objet via des opérateurs de type '[]' plutôt que via get(...) ou obj.data[].

    Néanmoins, compte tenu du retour que tu me fais et compte tenu des différents sujets que j'ai pu voir sur le net autour de cette question, je craint que cela ne soit pas possible...

    Mais, ce n'est pas nécessairement une mauvaise chose, et je perçois déjà comment interpréter certaines de mes classes C++ vers le C (si cela s'avérait nécessaire un jour).

  4. #4
    Rédacteur/Modérateur

    Il n'y a pas de surcharge d'opérateur en C.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre habitué
    C'est bien ce que je pensais, mais j'imaginais qu'il existait potentiellement quelques tricks permettant de répondre à cette "problématique".

    Merci pour ces retours.

  6. #6
    Expert confirmé
    Bonjour.

    Je vais peut-être répondre un peu à côté mais regarde du côté de Gtk+ et plus particulièrement les GObject. C'est une implémentation de programmation orientée objet en C.

    Lorsque tu "dérives" un objet d'un GObject tu peux créer des propriétés qui te donnent accès aux données internes avec les fonctions g_object_get_property () / g_object_set_property ();.

    Cette manière de procéder t'évite les fonctions get/set si de nombreux paramètres existent.

    Ca pourrait-être une source d'inspiration...
    Utilisation de Glade avec Gtk+ - N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk

  7. #7
    Rédacteur/Modérateur

    Le trick est simple, tu crées et utilises des fonctions.
    Les opérateurs se sont juste des raccourcis syntaxiques.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

###raw>template_hook.ano_emploi###