MotionScript et MotionInspector intègre un langage script très proche du langage C.
Il n’est pas question ici de définir complètement le langage C, mais plutôt de donner les limitations et les différences entre notre implémentation et le langage C ISO/CEI 9899:1990 (C90).
C preprocessor
Il n’existe pas réellement de pré processeur dans cet interpréteur et les différente directives ci-dessous sont implémentées avec certaines limitations :
- #define (doit retourner une valeur – comme une fonction)
- #if/#ifdef/#else/#endif (« defined() » non implémenté)
- #include
Limitations
La déclaration de fonction doit explicitement donner les types des arguments. L’ancienne notation « K&R » n’est pas implémentée.
Les pointeurs sur les fonctions ne sont pas implémentés dans la version actuelle.
Les mots clés représentatifs de type de stockage propre à un compilateur ne sont pas supportés : static, extern, volatile, register et auto.
Les « struct » et « union » ne peuvent être définis que globalement
« goto » ne peut référer qu’à des étiquettes suivant l’appel (forward)
Extensions
Un certain nombre d’extensions (sous forme de dll ou de codes sources) sont disponibles ou en cours de développement. Il est aussi possible d’ajouter des bibliothèques en code sources à un script « C ». Le script suivant utilise une bibliothèque compilée (référencée par <miAPI.h>) et un autre fichier source (« file.h« ). Les extensions (dll) sont automatiquement chargées lorsque l’interpréteur rencontre la ligne #include <miAPI.h>. Par contre, ll sera nécessaire d’utiliser la commande « Ajouter un fichier C Script » pour que le fichier « file.c » soit aussi compilé et lié au fichier principal (qui contient la fonction « main »).
#include <stdio.h> #include <stdlib.h> #include <miAPI.h> #include "file.h" // Liste des constantes à redéfinir si besoin #define EV1 "DVIS" #define EV2 "DTOU" #define FORMAT MAT_FORMAT #define PATH "C:\\Users\\Gilles\\Desktop" #define TITLE "Sélectionner les fichiers" #define FILTER "Fichier C3D|*.c3d" int main() { int count = 0; // nombre de fichiers dans la liste // sélection d'une liste de fichiers char** files = miGetFileList(FILTER, TITLE, PATH, &count); if (files != NULL) // si la liste est non NULL { int i; for(i = 0; i < count; i++) // boucle sur la liste des fichiers { if (miOpenDataFile(files[i])) // ouvre le fichier { fi_export(files[i], EV1, EV2, FORMAT); // exportation entre EV1 et EV2 miCloseData(); // ferme le fichier de données } } for(i = 0; i < count; i++) // libération de la mémoire (liste) free(files[i]); free(files); } return 0; }
Exemple de script « C »
// // calcul des centiles // #include <stdio.h> #include <math.h> #define SIZE 1000 int seed = 123456789; double rand() { int a = 16807; int m = 2147483647; seed = (a * seed) % m; double random = (double) seed / (double) m; return random; } void tri_insertion(double* tab, int taille) { int i, j; for (i = 1; i < taille; ++i) { double elem = tab[i]; for (j = i; j > 0 && tab[j-1] > elem; j--) tab[j] = tab[j-1]; tab[j] = elem; } } double sd(double* tab, int taille) { int i; double s = 0; double s2 = 0; double n = (double) taille; for(i = 0; i < taille; i++) { s+=tab[i]; s2+=(tab[i]*tab[i]); } s = sqrt(((n*s2)-(s*s))/(n*(n-1))); return s; } double mean(double* tab, int taille) { double m = 0; int i; for(i = 0; i < taille; i++) { m+=tab[i]; } m/=(double) taille; return m; } double centile(double* tab_tri, int taille, int cent) { if (cent < 1 || cent > 99) cent = 50; double c = 0; double p = (double) cent / 100.0; p*=(double) taille; int pc = floor(p+0.5); return tab_tri[pc]; } int main(void) { int i; double tableau[SIZE]; for(i = 0; i < SIZE; i++) { double value = rand()*100; tableau[i] = value; } tri_insertion(tableau, SIZE); // tri du tableau double m = mean(tableau, SIZE); // calcul de la moyenne double s = sd(tableau, SIZE); double c = centile(tableau, SIZE, 50); // calcul de P50 (médiane) printf("moyenne = %g (%g) ; P50 = %g \n", m, s, c); return 0; }