Bjarne Stroustrup

l'homme qui a conçu le langage C++
Bjarne Stroustrup's est l'homme qui a conçu et le réalisateur du langage C++ original

Bjarne Stroustrup : le père de C++, un langage qui a de la classe  

Bjarne Stroustrup est l'homme à qui l'on doit le célèbre langage de programmation C++. Celui-ci offre au développeur des outils très sophistiqués, mais dans le même temps permet de programmer « très près » de la machine. Il connaît un succès croissant non seulement pour le développement de logiciel système, conformément à l'objectif initial de son auteur, mais également dans d'autres secteurs où l'on tient à la fois à programmer « proprement » et efficacement : télécoms, interfaces homme-machine, applications graphiques, simulation…

L'homme qui a conçu le langage à succès C++ s'appelle Bjarne Stroustrup. Installé désormais à College Station, une petite ville du Texas, depuis qu'il enseigne à la Texas A&M University, Bjarne Stroustrup a passé l'essentiel de sa carrière aux Bell Labs.

Mais il a d'abord été petit. Bjarne Stroustrup est né en 1950 à Aarhus, la deuxième ville du Danemark (250 000 habitants aujourd'hui). Il fait ses études à l'Université d'Aarhus jusqu'à l'obtention en 1975 d'un master en informatique. Puis c'est à l'Université de Cambridge, en Angleterre qu'il obtient en 1979 son PhD, portant sur la conception des systèmes distribués. Il part alors pour les Etats-Unis, au New Jersey où l'attend un emploi au Computer Science Research Center des Bell Telephone Laboratories. Et ce n'est que 23 ans plus tard, en 2002, qu'il quittera ce qui est devenu les AT&T Labs pour accepter un poste de professeur à la Texas A&M University.

D'une frustration naît la vocation

Bjarne Stroustrup n'a pas toujours su qu'il serait l'inventeur d'un nouveau langage de programmation. Dans les années soixante-dix, ses centres d'intérêt tournaient autour des systèmes distribués, autrement dit les architectures informatiques impliquant plusieurs processeurs. Et en particulier, celles destinées à prendre en charge des systèmes d'exploitation.

Les systèmes d'exploitation sont un peu les sous-vêtements des ordinateurs. Sans eux, ces derniers sont tout nus et ne savent rien faire. Alors que, revêtu d'un système d'exploitation, un ordinateur peut enfiler toutes sortes de vêtements logiciels (les applications) qui lui permettent d'exercer autant de métiers. Plus formellement, un système d'exploitation rend un ordinateur « exploitable », capable d'écouter ses utilisateurs, d'accueillir et de lancer des applications, de prendre en charge pour leur compte toutes sortes de corvées, de procéder à diverses tâches d'intendance (comme dupliquer un fichier) et bien d'autres choses.

Le système d'exploitation et divers appendices (comme les systèmes de gestion de bases de données…) constituent ce que l'on appelle le « logiciel système », un genre de logiciel qui se caractérise par sa forte dépendance du matériel sur lequel il doit opérer ainsi que par de fortes exigences en matière d'efficacité. De ce fait, la production du logiciel système diffère quelque peu du développement de logiciels applicatifs et nécessite des outils, en particulier des langages de programmation, spécifiques.

Un peu par hasard, Bjarne Stroustrup allait devenir le créateur d'un langage de programmation merveilleusement adapté au développement du logiciel système. Comme pour bien des créateurs de langage, c'est une frustration qui est à l'origine de cette vocation. « Ce n'est pas tant que j'ai décidé de créer un nouveau langage que le fait que j'avais quelques problèmes pour lesquels les langages existants ne semblaient pas adaptés ».

Des langages de programmation, ce n'est pourtant pas cela qui manquait à l'époque. « Mais je trouvais qu'ils se partageaient en deux catégories : ceux que les gens utilisaient vraiment pour produire du logiciel, et les langages de recherche qui servaient à explorer des idées et argumenter sur les principes de la conception du logiciel ». Bjarne Stroustrup se retrouve face à un affreux dilemme. Il trouve que les « langages de production » sont assez mal fichus et que les « langages de recherche » ont tendance à être limités à quelques machines, à quelques secteurs d'applications et à quelques groupes d'utilisateurs. Et ces derniers langages, qui plus est, ont souvent de sérieux problèmes de performances et d'accès aux ressources matérielles.

Entre idéaux et contraintes

Car si le développeur système se laisse séduire par la possibilité que lui offre un langage de haut niveau de manier de puissantes abstractions, il ne peut oublier qu'il a également besoin de pouvoir accéder aux réalités bassement matérielles de l'architecture qui héberge son logiciel, puisque, précisément, ce dernier a pour objet de « l'exploiter » au mieux. Un langage en col blanc, pourquoi pas, mais à condition qu'il n'empêche pas de mettre les mains dans le cambouis, quitte à fournir les gants.

Lorsque Bjarne Stroustrup se pose ces questions, le paysage des langages de programmation qu'il contemple sans y trouver son bonheur est pourtant riche de Simula, Lisp, Pascal, Algol 68, Modula-2, PL/1… Par la suite, il se familiarisera avec des « langages de recherche » tels que Smalltalk et Trellis/Owl. Enfin, Ada était en gestation et faisait peur. Ada, supposait-on, allait devenir le langage pour le développement système… sérieux.

Mais en attendant, les logiciels système s'écrivaient au mieux à l'aide de langages « orientés machine ». « Il allait souvent de soi que si vous aviez l'intention de travailler sur une machine IBM, vous alliez utiliser un langage IBM, comme PL/S ou PL/360 ; ou dans le cas d'une machine DEC, un langage DEC tel que Bliss, etc. Il y avait des exceptions, bien sûr. La défense britannique avait un assez joli langage appelé Coral. Il existait des dialectes utiles d'Algol 68. Et BCPL était utilisé dans des endroits surprenants, comme le Xerox PARC. Mais je crois surtout que la plupart des gens à cette époque vous auraient dit que si vous étiez sérieux à propos de développement système, vous deviez écrire en assembleur ». C'est-à-dire le langage simplet fourni par le constructeur permettant d'engendrer des instructions élémentaires destinées à l'ordinateur.

Mais Bjarne Stroustrup ne veut décidément pas programmer en assembleur. « Je l'avais déjà assez fait dans le passé ». Il ne veut pas non plus se limiter à une seule famille de machines. « D'un coup d'oeil circulaire dans le labo, je pouvais voir plusieurs machines intéressantes que j'avais de bonnes raisons d'essayer ».

Pas question d'utiliser l'assembleur, ni un langage évolué marié à une machine, et aucun langage de haut niveau à l'horizon permettant d'écrire proprement du logiciel système efficace : Bjarne devra-t-il inventer ce langage idéal qui n'existe pas ? Il répond par oui. Mais devra-t-il le créer ex nihilo ? Non, car il trouve tout de même un point de départ sympathique.

À l'origine était le C

« En 1979, le langage C venait juste d'apparaître. Il n'était pas encore largement connu ». Inventé aux Bell Labs en même temps que le système Unix et d'ailleurs pour développer ce dernier, C est à mi-chemin entre l'assembleur et le langage de haut niveau. C'est une sorte d'assembleur sophistiqué indépendant de la machine.

« Je l'avais déjà utilisé une première fois en 1975 en Angleterre et j'y suis revenu lorsque j'ai rejoint les Bell Labs au printemps 1979. J'avais obtenu mon exemplaire du fameux « K & R book » (rédigé par les inventeurs de C, Brian W. Kernighan, Dennis M. Ritchie) peu après sa sortie en 1978. Une chose qui était importante pour moi, c'est que le langage C était utilisé pour la programmation système sérieuse, sur une variété de machines. Il était assez « bas niveau » pour que l'on puisse écrire le système Unix dans ce langage avec juste quelques lignes d'assembleur en plus, mais dans le même temps suffisamment de « haut niveau » pour que l'on puisse, en étant prudent, obtenir un code portable et raisonnablement élégant ». « Portable » : c'est-à-dire transposable d'une machine à l'autre. « En rejoignant le Computer Science Research Center des Bell Labs, je me retrouvais là où l'on pouvait bénéficier du meilleur support pour C au monde. Si j'avais un problème, je pouvais m'adresser à Dennis Ritchie, Brian Kernighan, Bob Morris, Steve Johnson, Doug McIlroy ou d'autres contributeurs majeurs de ce genre à C et Unix ».

C'est donc de C que s'inspire en premier lieu Bjarne Stroustrup. Dans un premier temps, il définit un langage qu'il appelle « C with classes » - soit « C avec des classes », la classe étant une notion qu'il emprunte au langage Simula.

Le langage C++

La révolution de la « classe »

Ce langage révolutionnaire vient du grand nord, plus précisément du Norwegian Computing Centre d'Oslo où Ole-Johan Dahl et Kristen Nygaard lui ont donné naissance en 1962. Mais c'est surtout la mouture Simula-67 qui a fait découvrir au monde le nouveau concept sur lequel est bâti le nouveau venu. Simula a introduit la « classe », qui fait le premier pas vers la notion moderne d'objet, ce fameux objet que l'on retrouve dans la formule « langage orienté objet ».

La programmation orientée objet permet de définir de nouvelles entités caractérisées à la fois comme une collection de données (les « attributs ») et de sous-programmes (les « méthodes »), définissant les actions dont elles sont capables. Une fois décrite une nouvelle « classe », des exemplaires ou « instances » de cette classe peuvent être créés : ce sont les objets. Ainsi dans un logiciel (imaginaire) permettant d'étudier l'agencement d'un appartement, une classe « meuble » pourra comporter des « attributs » tels que « hauteur », « largeur » et « profondeur » et des « méthodes » telles que « placer (coordonnées) ».

Bjarne Stroustrup apprécie dans Simula ce concept de classe, mais regrette bien des inconvénients pour l'activité qui lui importe : le développement de logiciel système efficace. C'est pourquoi, à partir de 1979, il entreprend d'introduire une notion de classe empruntée à Simula dans un langage C augmenté par ses soins.

En 1982, « C with classes » devient C++, avec l'introduction d'autres nouveautés qui ne relèvent pas toutes de la programmation orientée objet. Par la suite, Bjarne Stroustrup définira C++ comme un langage « multi paradigme », signifiant par là qu'il n'est pas seulement « orienté objet ». C++, insiste Bjarne Stroustrup, est un C amélioré qui supporte « l'abstraction de données », la programmation orientée objet et la « programmation générique ».

Du succès au standard

En 1985, Bjarne Stroustrup publie son livre « The C++ Programming Langage », qui connaîtra par la suite trois nouvelles éditions (en 1991, 1997 et 2000). Il racontera en 1990 la saga de C++, des idées qui l'ont influencé et des confrontations d'idéaux et de contraintes qui l'ont fait évoluer, dans « The C++ Programming Langage (Third Edition and Special Edition) » A History of C++: 1979-1991. Devant le succès de C++, la nécessité d'une normalisation du langage se fait sentir. Un long processus aboutira à sa standardisation par l'ISO en 1998. Bjarne Stroustrup s'implique dans cet effort et participe encore aux travaux de finalisation de la norme qui n'ont pas cessé.

La contribution de Bjarne Stroustrup à l'avancement de sa discipline lui a valu un certain nombre de nominations et récompenses. Ainsi il a entre autres été élu en 2004 à la National Academy of Engineering et a obtenu la même année le « Computer Entrepreneur Award » de la IEEE Computer Society. Déjà en 1990, Fortune Magazine l'avait désigné parmi les « douze meilleurs jeunes scientifiques d'Amérique ».

La notoriété inspire à Bjarne Stroustrup des sentiments contrastés. Avantage : les gens prennent mes opinions au sérieux. Du coup, je sens que j'ai le devoir d'utiliser cette influence pour améliorer l'univers de la programmation. Et je sens que cela rétrécit mon champ d'activité, m'empêche de me lancer dans des petits projets « juste pour le plaisir », qui auraient pu m'aider à grandir. La notoriété, regrette le chercheur, cela vous colle une étiquette. « Je suis devenu aux yeux de certains Monsieur C++, plutôt qu'un individu multidimensionnel. Ils pensent par exemple que j'aime tout dans C++ et que je déteste tout des autres langages. C'est absurde ! »

Bjarne Stroustrup et son épouse Marian sont les heureux parents d'une fille, Annemarie, née à Cambridge, et d'un fils, Nicholas, né aux États-Unis. Tous deux poursuivent aujourd'hui leurs études à l'université. Du coup le papa y est retourné lui aussi. « Il y avait quelque temps déjà que j'avais envie d'enseigner et je voyais mes enfants s'amuser comme des fous à l'université… » Bjarne Stroustrup est devenu il y a deux ans professeur à la Texas A&M University, mais il reste affilié à son laboratoire d'origine. Quand il se met en vacances de l'informatique, Bjarne Stroustrup lit, des ouvrages historiques ou plus littéraires, écoute de la musique. Il pratique la photographie, aime voyager. Et toujours, il marche, court.

Bjarne Stroustrup a même marché sur Mars. Enfin presque. Car Spirit et Opportunity, ces deux merveilleux robots du Jet Propulsion Laboratory qui ont arpenté pendant des mois la planète rouge, voient et décident par la grâce de logiciels écrits en C++.

 

Les langages

Les Instructions de Commande

Dans tous les langages de programmation : les instructions de commande. Elles permettent de contrôler le déroulement d'un programme, spécifiant quelles lignes doivent être ou non exécutées à un moment donné. Un certain nombre d'instructions sont réservées à cet effet en langage C : - la très classique exécution conditionnelle binaire ou multiple if... else ou if... else if... else qui est présente dans tout langage; - le choix multiple, beaucoup moins commun associant un bloc d'instruction à une valeur donnée d'une variable : Switch... case... default ;

- les différentes classes de traitements répétitifs ou boucles : while, do... while, et for...
- l'instruction de branchement direct goto, très mal considérée en programmation structurée, et qu'il faudra bannir de vos programmes;
- quelques instructions complémentaires mais très importantes : return, break, continue. Nous découvrirons au fil des lignes la syntaxe de ces différentes instructions, et des exemples de programmes nous dévoileront de nombreux traits particuliers au C.

Exécution conditionnelle if

Qui ne connaît pas cette inévitable instruction : Dans le cas où, faire ceci, sinon, faire cela. On peut traduire cette phrase en C par

 if (expression)
   instruction vraie
 else
   instruction faux

Ou : expression est valide au sens du langage C (pas de point-virgule à la fin). Le mot then (du BASIC et Pascal, par exemple) est inutile car les paramètres font office de délimiteurs.
"Vrai" et "faux" n'ont pas de sens en C, la première instruction est exécutée si l'expression possède une valeur non nulle, la seconde étant utilisée uniquement dans le cas ou le résultat de l'expression vaut zéro.

program(1)
#include <studio.h>

main()
{
  int a ;
  printf(" Valeur : ");
  scanf(%d, &a);
  if (a>10)
    printf(" Valeur grande ");
  else
    printf(" Valeur petite ");
}

Instruction peut naturellement être remplacée par un bloc contenant de multiples ordres.
Else est optionnel. Dans le cas ou il est absent, une valeur nulle déclenche l'exécution de l'instruction. Pour une valeur non nulle, rien ne se produit. Voir le programme 1

Dans ce cas, une seule instruction apparaît dans les deux branches du if. Notez la disposition adoptée pour les accolades et les tabulations utilisées à la mise en page. On peut enchaîner des if successifs : dans le programme(2), le second n'a pas de clause else.

program(2)
#include <stdio.h>
main()
{
    int a;
    printf (" Valeur : "
    scanf (" %d ",&a) ;
    if (a>10) {
       if (a>20)
         printf(" a > 20 ") ;
     }
     else printf(" a <= 10 ") ;
}
Choix multiple
monocondition Switch

La syntaxe générale est montrée dans le programme(3).
Après évaluation dé l'expression (le résultat doit être nécessairement entier), le groupe d'instructions suivant le case ayant la bonne constante comme argument est exécuté. Si aucune constante n'est égale au résultat de l'expression, on se sert du groupe suivant l'instruction default (qui est d'ailleurs optionnelle). La même structure pourrait être réalisée à l'aide d'un nombre suffisant d'instructions if. Mais plusieurs différences importantes doivent être mises en valeur :
- avec switch, une seule expression est évaluée. Avec une collection de if, autant de résultats doivent être calculés;
- un groupement de if.. else if.. est beaucoup plus riche qu'un switch, mais aussi nettement plus lent et volumineux en code généré.

program(4)
#include <studio.h>
main()
{
  char ch ;
  ch=toupper(getch());
  swich (ch){
   case 'A':
      printf("Premier de l'alphzbet");
      break;
   case 'B':
   case 'C':
      printf("B ou C …);
      brezak;
   default:
      if(ch<'M')
        printf("Premiere moitie");
      else 
        printf("Second moitie");
  }//ends swich 
}  

N'oubliez pas les " : " concluant chaque ligne case ou default! Dans le programme(4), on associe quelques cases avec des if, et l'instruction de rupture break apparaît. Elle a pour effet de provoquer la sortie du Switch en se branchant directement à l'accolade de fermeture.

(program(3))
Switch (expression)
 {
   Case consT1 :
	…
	…
   Case consT2 :
	…
	…
   default :
	…
	…
 }

Le caractère du test est lu au clavier et converti en majuscule. On voit que deux case peuvent être concernées par le même groupe d'instructions (B et C). Break a aussi être utilisé dans les boucles (paragraphe suivant), mais jamais dans le corps d'une fonction ou avec un if.

Boucle "tant que" : while

Pour traduire " tant que (condition est vraie), exécuter les ordres ", on utilise while.
while (expression)
Instruction

La syntaxe en est donc on ne peut plus simple. Mais, examinons le programme(5).

program(5)
#include <studio.h>

main()
{
  char ch ;
  int longueur ;
  printf(" Entrez une phrase \n) ;
  printf "et validez par ENTER \n) ;
  longueur=0 ;
  while ((ch=grtchar()) != " \n ") 
   {
     putch(ch) ;
     longueur++ ;
   }
  printf("\nVous avez tapez ");
  printf("%d caracteres\n",longueur);
}

Quelques commentaires s'imposent. En C, le " return " de validation, ou retour-chariot, est constitué des caractères / et n. La chaîne elle-même a pour terminateur le caractère de code ASCII nul. Notre exemple propose à l'utilisateur d'entrer une séquence de caractères qui se terminera par /n, imprimera chaque caractère (putch) et donnera finalement la longueur de la chaîne.

Boucle "faire...tant que"; do

Une boucle très similaire à la boucle précédente, est la boucle do... while :

do
Instruction
while (expression) ;

La différence majeure est constituée par le fait que "instruction" est forcément exécutée, car le test se fait en fin de passage. Dans le cas du while, l'instruction peut fort bien ne jamais être exécutée si au premier passage, l'expression est déjà fausse. Le même exemple que le précédent peut être réécrit tel que le montre le programme(6).

Naturellement, cette seconde manière de voir les choses ne fonctionne pas en cas de chaîne de longueur nulle. Et attention au point-virgule après l'expression condition suivant le while!

Une subtilité importante de l'opérateur ++ (ou - -) : suivant qu'il est placé à gauche ou à droite de son argument, l'incrémentation intervient toujours, mais la valeur retournée par l'expression vaut la valeur finale ou la valeur initiale du paramètre.

(program 6)
#include <studio.h>
main()
{
  char ch ;
  int nbr ;
  printf(" Entrez un phrase \n ") ;
  printf(" Et validez par ENTER \n ");
  nbr=0 ;
  do
    ch=grtchar() ;
    while(nbr++, putch(ch), ch != " \n ");
    printf(" \n Vous avez tap ");
	printf("%d caracteres \n, --nbr);
}
Boucle d'itération for

Cette, instruction est aussi connue que le if que nous avons vu en premier. Sa philosophie se décompose ainsi
- conditions initiales ;
- calcul d'évolution des paramètres de boucles ;
- conditions finales, atteintes ou non.

Instruction = while (exp2)
 {
   instruction 
   exp 3
 }

En C la syntaxe de l'instruction for en est directement inspirée : for (exp 1 - exp 2 ; exp 3) où : - exp 1 représente les conditions initiales; - exp 2 représente les conditions finales; - exp 3figure le calcul du paramètre.
Bien sûr, cette structure peut-être écrite de manière plus longue à l'aide d'une boucle white. On a stricte équivalence entre les deux blocs d'instructions. for(expl,exp2,exp3) exp1;

Un petit exemple dans le programme(7), une chaîne est entrée au clavier, imprimée à l'écran, puis inversée et réimprimée.

(program 7)
#include <stdio.h>
main()
{
  char s[20] ;
  int lon, c, i, j ;
  for(i=0; (s[i]=getchar())!= "\n"; ++i)
  putch(s[i]) ;
  lon=i ;
  for( i=0 ; j=lon-1 ; i<j ; i++,j--) 
   {
     c=s[i] ;
     s[i]=s[j] ;
     s[j]=c ;
   }
  s[lon]=0 ;
  puts(s) ;
}

On peut remarquer le groupement des conditions initiales dans la seconde boucle, ainsi que celui des formules de calcul (exp3). La récursivité du langage C, liée au domaine d'existence des variables nous permettra très prochainement d'écrire le même en deux ou trois lignes seulement!

Instructions complémentaires: break, continue, goto, return
Ces quelques instructions ne constituent pas en elles-mêmes de nouvelles structures récurrentes, mais permettent des branchements particuliers : break : déjà aperçue lors de l'étude de l'instruction switch. Break provoque la rupture de la boucle en cours d'exécution, et le branchement à l'accolade de sortie de la boucle.

continue : son utilisation provoque la reprise au début de la boucle, avec le test de continuité à exécuter. Dans le programme(8), pour chaque caractère entré au clavier :
- In provoque la fin de l'entrée (retour-chariot);
- It (Stabulation) provoque la rupture de la boucle;
- les caractères ASCII sont visualisés.

goto : cette instruction vedette du BASIC sur la programmation structurée, très nuisible à la compréhension et à la lisibilité d'un programme. Son emploi n'est jamais nécessaire, mais elle peut simplifier notablement un listing dans quelques rares cas. Elle existe donc aussi en C, provoquant le branchement à une étiquette (terminée par :)

Début :

goto début;

(program 9)
#include <stdio.h>
main(){
  char c ;
  while((c=getch()) != '\n') {
   if ( c='\t') break;
   else 
     Putch(c);
  }
}

return : on sort de toute fonction (même main) grâce à cette instruction return expression;
L'expression constituera la valeur de retour, et reste optionnelle.
On peut trouver plusieurs retum par fonction. Dans ce dernier programme, la fonction "fonction" a trois arguments en entrée, et en sortie : sa propre valeur.

Développement de   (a + b)m



//=======================================================//
// Triangle Arithmetique de Pascal                       //
// Programmation Turbo C++ Ver 3.0 Borland               //
// programmeur: A.ARA                                    //
// 64150 Mourenx - France                                //
// Copyright (s) 1976-2011                               //
// Licence d'utilisation accord dans un but demostratif  //
// Program Triangle.c + Unit: BOXREAD.c + Get_key.c      //
//=======================================================//

#include<conio.h>
#include"Get_Key.c"
#include"BOXREAD.c"

const  EE = 10+1;         /**puisance maximun **/
static long C[25][25];
static char Signe1[20];
static char Signe2[20];
static unsigned char Ch;
static unsigned char Signe;

char *formule;


void Inicialitation_Triangle()
{
    int i,j,k;

    /** Initialisation tables a 0 **/
    for (i=1; i<=EE; i++)
     for (j=1; j<=EE; j++)
      C[i][j] = 0;

    for (k=1; k<=EE; k++)
     {
       C[k][1]=1;
       C[k][2]=k;
     }

    /** Calcul de C3 Cee **/

    for (i=2; i<=EE; i++)
     {
      for (j=3; j<=EE;j++)
       C[i][j] = C[i-1][j-1]+C[i-1][j];
     }

    for (i=1; i<=20; i++)
     {
       Signe1[i]='+';
       if (i % 2 == 0) Signe2[i]='+';
       else  Signe2[i] = '-';
    }
} /**end Inicialitation_Triangle**/



void Developement(int xx,int yy,int MM, char Sig )
{
    int uu,r,aa,bb;
    char HH[10]="";

    if (Sig !='-') Signe=1;
    else Signe=2;

    if (MM<=10)
     {
       gotoxy(xx,yy);
       textattr(31);
       cprintf("a^%d",MM);//,mm);
       sprintf(HH,"a^%d",MM);
       strcpy(formule,HH);

       if (Signe==1)
        { cprintf(" %c ",Signe1[1]);
          sprintf(HH," %c ",Signe1[1]);
          strcat(formule,HH);
        }
       else
        { cprintf(" %c ",Signe2[1]);
          sprintf(HH," %c ",Signe2[1]);
          strcat(formule,HH);
        }

       for (r=1; r<=MM-1; r++)
        {
          textattr(29);
          cprintf("%d",C[MM][r+1]);
          sprintf(HH,"%d*",C[MM][r+1]);
          strcat(formule,HH);
          textattr(31);
          if (MM-r>1)
           { cprintf("a^%d",MM-r);
             sprintf(HH,"a^%d*",MM-r);
             strcat(formule,HH);
           }
          else
           { cprintf("a");
             strcat(formule,"a*");
           }

          textattr(30);
          if (r>1)
           {
             cprintf("b^%d",r);
             sprintf(HH,"b^%d",r);
             strcat(formule,HH);
           }
          else
           {
             cprintf("b");
             strcat(formule,"b");
           }
          if (Signe==1)
           {
             cprintf(" %c ",Signe1[r+1]);
             sprintf(HH," %c ",Signe1[r+1]);
             strcat(formule,HH);
           }
          else
           {
             cprintf(" %c ",Signe2[r+1]);
             sprintf(HH," %c ",Signe2[r+1]);
             strcat(formule,HH);
           }
        }
       textattr(30);
       cprintf("b^%d",MM);
       sprintf(HH,"b^%d",MM);
       strcat(formule,HH);
     } /**if MM**/
    if (MM>10) strcpy(formule,"");

}/**end Developement**/



void Triangle(int Lxx,int Lyy,int Nbr)
{
    int EEE=Nbr;
    int yy,xx,pp,ss=0;
    int j,k;

    textattr(112);/*blanc*/
    boxfill(1,Lyy,80,Lyy+Nbr+6,' ');
    gotoxy(23,Lyy);
    cprintf(" TRIANGLE  ARITHMETIQUE  DE  PASCAL ");
    textattr(31);
    boxfill(3,Lyy+1,78,Lyy+Nbr+5,' ');

    /** affichage du triangle **/

    gotoxy(Lxx,Lyy+1);
    for (j=1; j<=EEE; j++)
     {
       textattr(31);
       cprintf("    (a+b)^%2d  ->",j);
       textattr(30);
       for (k=1;k<=j+1;k++) cprintf("  %3d",C[j][k]);
       printf("\n");
       gotoxy(3,wherey());
     }

    xx=31;yy=Lyy+1;pp=1;
    textattr(26);
    writexy(65,Lyy+3,"Signe: '+'");
    highbox(6,yy,xx,yy,5);
    do {
         CSOFF();
         Ch=keyboard();
         if (Key_Code && Ch==80 && yy<Lyy+10)
          {
            highbox(6,yy,xx,yy,5);
            xx+=5;yy++;
            pp++;
            highbox(6,yy,xx,yy,5);
          }
         else
         if (Key_Code && Ch==72 && yy>Lyy+1)
          {
            highbox(6,yy,xx,yy,5);
            xx-=5;yy--;
            pp--;
            highbox(6,yy,xx,yy,5);
          }
         else
         if (!Key_Code && (int)Ch==13)
          {
            window(5,1,75,25); /**fenetre de affichage developement**/
            if (ss==0)
              Developement(1,Lyy+12,pp,'+');
            else
              Developement(1,Lyy+12,pp,'-');
            window(1,1,80,25); /**init fenetre**/

         CSOFF();
         Ch=keyboard();
         textattr(31);
         boxfill(3,Lyy+12,78,Lyy+15,' ');
       }
     else
     if (!Key_Code && Ch==45 && ss==0)
      {
        ss=1;
        textattr(26);
        writexy(65,Lyy+3,"Signe: '-'");
      }
     else
     if (!Key_Code && Ch==43 && ss==1)
      {
        ss=0;
        textattr(26);
        writexy(65,Lyy+3,"Signe: '+'");
      }
    } while (Ch !=27);

   textattr(7);
   clrscr();
}/*end triangle*/


void main()
{
    clrscr();
    Inicialitation_Triangle();
    window(1,1,80,25);
    Triangle(3,2,10);
    window(1,1,80,25);
    textattr(7);
    clrscr();
} /**end programme triangle Pascal**/

Unite foctions divers

//============================================================//
// Unite BoxRead.c utilitaire foctions divers                 //
// Programmation Turbo C++ Ver 3.0 Borland                    //
// programmeur: A.ARA                                         //
// 64150 Mourenx - France                                     //
// Copyright (s) 1976-2011                                    //
// Licence d'utilisation accord dans un but demostratif       //
// Unit BoxRead.c + Get_Key.c                                 //
//============================================================//

#if !defined(__BOXREAD_C)
#define __BOXREAD_C

#ifndef __DOS_H
#include<dos.h>
#endif

#ifndef __STDLIB_H
#include<stdlib.h>
#endif

#ifndef __MEM_H
#include<mem.h>
#endif

#ifndef __CONIO_H
#include<conio.h>
#endif

#ifndef __BIOS_H
#include<bios.h>
#endif

#ifndef __STRING_H
#include<string.h>
#endif

#ifndef __STDARG_H
#include<stdarg.h>
#endif


#ifndef __STDIO_H
#include<stdio.h>
#endif

#ifndef __ERRNO_H
#include<errno.h>
#endif

#include"Get_Key.c"

unsigned int shortcursor =0x0607;
unsigned int tallcursor = 0x0507;

/* ON curseur */
void CSON(int x, int y)
{  union REGS Register;
   Register.h.ah = 2;
   Register.h.bh = 0;
   Register.h.dh = (y-1);
   Register.h.dl = (x-1);
   int86(0x10,&Register,&Register);
}
/* OFF curseur */
void CSOFF()
{ union REGS Reg;
  Reg.h.ah = 2;
  Reg.h.bh = 0;
  Reg.h.dh = 56;
  Reg.h.dl = 0;
  int86(0x10,&Reg,&Reg);
}

/* Initialise les differentes types curseurs */
void initcursor(void)
{
    struct text_info ti;

    gettextinfo(&ti);
    if (ti.currmode == MONO)
     {
       shortcursor =0x0A0C;
       tallcursor =0x090C;
    }
   else
    {
      shortcursor =0x0607; //0x0607;
      tallcursor = 0x0601; //0x0507;
    }
}/*initcursor*/


/* Sets the shape of the cursor */
void typecursor(unsigned int shape)
{
     union REGS reg;

     reg.h.ah = 1;
     reg.x.cx = shape;
     int86(0X10, ®, ®);
}/*typecursor*/


//=========================================//
// Returns the shape of the current cursor //
//=========================================//
unsigned int getcursor(void)
{
    union REGS reg;

    reg.h.ah = 3;
    reg.h.bh = 0;
    int86(0X10, ®, ®);
    return(reg.x.cx);

} /*getcursor*/


//==========================================================//
// Changes the cursor shape based on the current insert mode//
//==========================================================//
void changecursor(int insmode)
{
    if (insmode) typecursor(tallcursor);
    else
    typecursor(shortcursor);
}/*changecursor*/



#ifndef __COLOR_FOND__
#define __COLOR_FOND__

void crt_setcolor(char Texte, char Fond)
{
   textattr((Fond << 4)+Texte);
}

char gettexte()
{   struct text_info ti;
    gettextinfo(&ti);
    return(ti.attribute-(((ti.attribute & 0x70) >> 4)*16));
}

char getfond()
{   struct text_info ti;
    gettextinfo(&ti);
    return((ti.attribute & 0x70) >> 4);
}

#endif



//===================================================================//
// Prints a string in video memory at a selected location in a color //
// void writexy = void Putxy(...)                                    //
//===================================================================//

void writexy(int col, int row, char *format, ...)
{
    va_list arg_ptr;
    char output[81];
    int len;
    int width;
    va_start(arg_ptr, format);
    vsprintf(output, format, arg_ptr);
    width=strlen(output);
    output[width] = 0;
    width=strlen(output);
    if ((len = strlen(output)) < width) setmem(&output[len], width - len, ' ');
    gotoxy(col, row);
    cputs(output);

}/*writexy*/



void boxfill(int x1,int y1,int x2,int y2,char ch)
{
     struct text_info ti;
     unsigned int BaseEcran =0xB800;
     char far *Video;
     register int y,x,A;
     int large,Delta;
     gettextinfo(&ti);
     A=ti.attribute;
     Video = (char far*) MK_FP(BaseEcran,((y1-1) * 160 + (x1-1) * 2));
     large = x2-x1+1;
     Delta = 160 - (x2-x1+1)*2;
     for (y=0; y <= y2-y1 ; ++y)
      {
        for (x=0; x < large; ++x)
         {
           *Video++ =ch;
           *Video++ =A;
         }
        Video +=Delta;
      }
}/*boxfill*/




void Crtrectangle(int x1,int y1,int x2,int y2,int Sty)
{ 
    unsigned int  BaseEcran =0xB800;
    char tab[6][2] = {{218,201},{191,187},{192,200},{217,188},{196,205},{179,186}};
    char far *Video;
    register int i;
    int Delta1,Delta2;

    Video = (char far*)MK_FP(BaseEcran,((y1-1) * 160 + (x1-1) * 2));
    Delta1 = (x2-x1) * 2;
    Delta2 = 160 - Delta1;
    *Video = tab[0][Sty];
    Video +=2;
    for (i=1; i <= x2-x1-1 ; ++i)
     {  
	    *Video =tab[4][Sty];
        Video +=2;
     }
    *Video = tab[1][Sty];
    Video +=Delta2;
    for (i=1; i < y2-y1; ++i)
     { 
	   *Video = tab[5][Sty];
       Video += Delta1;
       *Video = tab[5][Sty];
       Video +=Delta2;
     }
    *Video = tab[2][Sty];
    Video +=2;
    for (i=1; i <= x2-x1-1 ; ++i)
     { 
	   *Video =tab[4][Sty];
       Video +=2;
     }
    *Video = tab[3][Sty];          /**free(Video**/
}/*end Crtrectangle*/

#ifndef __HIGHBOX__
#define __HIGHBOX__


void highbox(int x1,int y1,int x2,int y2,int attC )
{
    unsigned int  BaseEcran =0xB800;
    char far *Video;
    int i,y,Delta;
    Video =(char far*) MK_FP(BaseEcran,((y1-1) * 160 + (x1-1) * 2)+1);
    Delta = 160 - (x2-x1+1)*2;
    for (y=1; y<=y2-y1+1; ++y)
     {
      for ( i=1; i<=x2-x1+1; ++i)
       {
         *Video = *Video ^ (attC*17);
         Video +=2 ;
       }
      Video +=Delta;
     }
}/*highbox*/

#endif


#ifndef __GOTOPTR__
#define __GOTOPTR__

void setcursor(int x, int y)
{
    union REGS Register;
    Register.h.ah = 2;
    Register.h.bh = 0;
    Register.h.dh = (y-1);
    Register.h.dl = (x-1);
    int86(0x10,&Register,&Register);
}/*setcursor*/

#endif

void writechar(int x,int y,int count, char ch)
{
    int i;
    gotoxy(x,y);
    for (i=1; i<=count; i++ ) cprintf("%c",ch);

}/*writechar*/



//=============================================//
// function demande par ReadBox                       //
//=============================================//
char *copibox(int Deb,int Nb,char *mot)
{
    char p[80]="";
    int  ii = 0;
    while ( (ii< Nb) && (*mot+ii+Deb !='\0') )
     {
       p[ii] = *(mot+Deb+ii);
       ii++;
     }
    p[ii] = '\0';
    return(p);
}/**copibox*/

//=========================================================//
// Entre: x,y :  codonees,  SS: Chaine de caracteres       //
// longeur : place dans la boite                           //
// MaxCh   : nombre de caracteres dans la chaine Max       //
// cadre: X1= x-2, X2 = x+longeur+1                        //
// Sortie: renvoit False si operation anule par ESC        //  
//         sino renvoit True                               //
// readbox(x,y,Chaine,longeurBox,nombre de caracteres)     // 
//=========================================================//

int readbox(int x,int y,char *SS,int longeur,int MaxCh)
{  
   struct text_info ti;
   unsigned char ch=0;
   char Bg;
   char *chaine;
   int x1,x2,pose,i;
   int debut = 0;
   int finbuf;
   int XXX;       /*utile pour savoir ou et le curseur*/
   x1 = x;
   x2 = x1+longeur;

   gettextinfo(&ti);
   XXX=ti.attribute;
   if (ti.attribute >> 4 == 0) Bg = 7;
   else Bg = ti.attribute >> 4;

   if (SS[0] != '\0')
    {
      finbuf =  strlen(SS);
      SS[finbuf] = '\0';
      if ( finbuf > longeur )
       { 
         debut = (finbuf-longeur);
         if ( finbuf >= MaxCh )
          { 
            pose = finbuf;
            x = (x1+longeur)-1;
          }
         else
          { pose = finbuf;
            x = (x1+longeur)-1;
          }
         writexy(x1,y,"%s",copibox(debut,longeur,SS));
         if ( debut > 1 ) writechar(x1-1,y,1,0x11);
       }
      else
       { debut = 0;
         writexy(x1,y,"%s",copibox(debut,finbuf,SS));
         x = finbuf + x1;
         pose = finbuf ;
       }

      highbox(x1,y,x,y,Bg);
/*2*/  cprintf("%c",7);
      changecursor(1);
      gotoxy(x,y);
      ch= keyboard();
      changecursor(0);
      if ( (! Key_Code) && (ch != 13) && (ch !=27) && (ch >=32) )
       { writechar(x1,y,longeur+1,' ');
         gotoxy(x1,y);
         x = x1;
         SS[0]='\0';
         finbuf = 0;
         debut = 0;
         pose = 0;
       }
      else
      if ((ch != 13) && (ch != 27))
       { highbox(x1,y,x,y,Bg);
         if (debut > 0) ++debut;
         writexy(x1,y,"%s",copibox(debut,longeur,SS));
       }
    }/**end SS != '\0'**/
   else
    {  x = x1;
       SS[0] = '\0';
       finbuf = 0;
       debut = 0;
       pose = 0;
    }
   gotoxy(x,y);

   /** DEBUT REPEAT **/

   while ((ch!=13) && (ch !=27))
    {
      /** DEL DROITE ***/
      if ((Key_Code) && (ch == 83) && (pose<finbuf))
       {  for ( i=pose; i<=finbuf ; i++) SS[i]=SS[i+1];
          --finbuf;
          XXX=wherex();
          if (debut > 0)
           { --debut;
             writechar(x1,y,longeur+1,' ');
             writexy(x1,y,"%s",copibox(debut,longeur,SS));
             --pose;
             gotoxy(XXX,y);
           }
          else
           {  writechar(x1,y,longeur+1,' ');
              writexy(x1,y,"%s",copibox(debut,longeur,SS));
              gotoxy(XXX,y);
           }
       }/**end del droite**/
     else

     /** DEL GAUCHE **/

     if ( (!Key_Code) && (ch == 8) && (pose>0) )
      {
        if (debut > 0)
         { --pose;
           --debut;
           if ( debut == 0 ) writechar(x1-1,y,1,' ');
           for ( i=pose ; i<=finbuf; i++)
             SS[i] = SS[i+1];
           --finbuf;
           writexy(x1,y,"%s",copibox(debut,longeur,SS));
         }
        else
        if ( debut == 0  && (pose>0 &&  pose<=finbuf))
         { 
           for ( i=pose-1; i<=finbuf ; i++) SS[i] = SS[i+1];
           --finbuf;
           --pose;
           --x;
           writechar(x1,y,longeur+1,' ');
           writexy(x1,y,"%s",copibox(debut,longeur,SS));
           gotoxy(x,y);
         }
        else
        if ( pose > finbuf )
         { --pose;
           SS[pose] = '\0';
           --finbuf;
           --x;
           writechar(x,y,1,' ');
           gotoxy(x,y);
         }
      }/**end del gauche**/
     else

     /**<--FLECHE A GAUCHE**/

     if ((Key_Code) && (ch==75) && (pose>0))
      { --pose;
        if (x > x1)
         { --x;
           gotoxy(x,y);
         }
        else
         { debut = pose;
           writexy(x1,y,"%s",copibox(pose,longeur,SS));
         }
        if (pose == 0) writechar(x1-1,y,1,' ');
      } /**end fleche gauche**/
      else

     /**->FLECHE A DROITE**/
     if ((Key_Code) && (ch==77) && (pose<finbuf) && (pose<MaxCh))
      { ++pose;
        if (x+1 == x2)
         { if (pose<=finbuf)
            { ++debut;
              writexy(x1,y,"%s",copibox(debut,longeur,SS));
              writechar(x1+longeur,y,1,' ');
            }
           else
           if ( pose<=MaxCh)
            { ++debut;
              writexy(x1,y,"%s",copibox(debut,longeur,SS));
              writechar(x2-2,y,2,' ');
            }
         }
        else
         { ++x;
           gotoxy(x,y);
         }
      }/**end fleche droite**/
     else

     /**<< DEBUT GAUCHE**/
     if ((Key_Code) && (ch==71))
      { x = x1;
        pose = 0;
        debut = 0;
        writexy(x1,y,"%s",copibox(debut,longeur,SS));
        gotoxy(x,y);
        writechar(x1-1,y,1,' ');
      }/**end debut gauche**/
     else

     /*** FIN DROITE >>> ***/

     if ((Key_Code) && (ch==79))
      { if (finbuf>longeur)
         { writechar(x1,y,longeur+1,' ');
           debut = (finbuf-longeur)+1;
           pose = finbuf;
           writexy(x1,y,"%s",copibox(debut,longeur,SS));
           x =(x1+longeur)-1;
         }
        else
         { debut = 0;
           x = finbuf+x1;
           pose = finbuf;
         }
        gotoxy(x,y);
      }/**end fin droite**/
     else

     /**INSERT CARACTERE**/

     if ( (! Key_Code) && (ch>=32) && (finbuf < MaxCh) )
      {
        if (x == x2-1 )
        {  
          for (i = finbuf + 1; i >= pose; i--) SS[i+1]= SS[i];
          SS[pose] = ch;
          ++debut;
          ++pose;
          ++finbuf;
          writexy(x1,y,"%s",copibox(debut,longeur,SS));
        }
       else
       if (SS[pose] != '\0' )
        { for (i = finbuf+1; i >= pose; i--) SS[i+1]= SS[i];
          SS[pose] = ch;
          ++x;
          ++pose;
          ++finbuf;
          writexy(x1,y,"%s",copibox(debut,longeur,SS));
          gotoxy(x,y);
        }
       else
       if (( SS[pose] == '\0' )  && (x <= x2))
        {
          SS[pose]=ch;
          ++pose;
          ++finbuf;
          SS[pose] ='\0';
          if (x == x2 )
           { ++debut;
             writexy(x1,y,"%s",copibox(debut,longeur,SS));
             gotoxy(x,y);
           }
          else
           { writechar(x,y,1,ch);
             ++x;
             gotoxy(x,y);
           }
        }
      }/**end insert**/

     /**MARK EXTREMES**/

     if ( MaxCh > longeur )
      { if (debut > 0 )  writechar(x1-1,y,1,0x11);
        else writechar(x1-1,y,1,' ');
        if (finbuf-debut >= longeur )  writechar(x2,y,1,0x10);
        else 
        writechar(x2-1,y,1,' ');
      }
     gotoxy(x,y);
     ch = keyboard();   
     
     /**ENTRE DU CARACTERE**/

    } /*** END REPEAT ***/

   SS[finbuf]='\0';
   /**SUPPRIME LES BLANS DE LA DROITE**/
   if ( strlen(SS) > 0 )
    { 
      i = strlen(SS)-1;
      while (SS[i] == 0x20) --i;
      SS[i+1] = '\0';
    }
  
   /**RETURN***/
   if (ch == 13 )  return 1;
   else return 0;
}/**end readbox**/



//==========================================//
// entree de une chaine limite dans X et Y  //
//==========================================//

int readstr(int x,int y,int cant,char *chStr)
{
     unsigned char ch=' ';
     int nc=0;
     int xx=x;

     setcursor(x,y);
     --cant;

     /*repeat*/

     do{
         ch=keyboard();
         if ((!Key_Code) && (ch == 8) && (nc>0))
          { --nc;
            chStr[nc]=' ';
            setcursor(xx-1,y);
            cprintf(" ");
            xx--;
            setcursor(xx,y);
          }
         else
         if ((!Key_Code) && (nc<=cant) && (ch>=32 && ch<254))
          { 
            chStr[nc]=ch;
            cprintf("%c",ch);
            ++nc;
            xx++;
          }
       }while(ch !=27 && ch !=13);  /**end repeat**/
     
     if (ch==27) return(0);
     else
     return(1);
}/*end readch*/



int readnum(int x,int y, char N)
{   
    char Ligne[6]="      ";
    int Err=1,nn=0;
    char Nstr[6]="";
    char Nstrx[6]="";
    char Lig[6]="";
    char Ch;
    int nc=0;

    strncpy(Lig,Ligne,N);
    gotoxy(x-1,y);
    cprintf(" %s",Lig);
    gotoxy(x,y);
    do{
        Ch=readkey();
        if ((int)(Ch)==8 && nc>0)
         {  nc--;
            Nstr[nc]=' ';
            gotoxy(wherex()-1,y);
            cprintf(" ");
            gotoxy(wherex()-1,y);
         }
        else
        if ((int)(Ch)!=13 && nc<N && ((Ch>='0' && Ch<='9') || (Ch=='-')))
         {
           Nstr[nc]=Ch;
           cprintf("%c",Ch);
           nc++;
         }
         
        if ((int)(Ch)==13 && (Nstr!="" || nc>N))
         {  
           strncpy(Nstrx,Nstr,nc);
           nn=0;
           nn = atoi(Nstrx);
           if (errno == ERANGE) Err=-1;
           else
            {  gotoxy(x-1,y);
               cprintf(" %s",Lig);
               gotoxy(x,y);
               nc=0;
               strcpy(Nstr,"");
               Err=0;
            }
         }
      }while((int)(Ch)!=13 && (int)Ch!=27);

    if ((int)Ch==27) return(0);
    if (Err==0) return(nn);
    else return(0);
}/**readnum**/




float readreal(int x,int y, int N)
{
    char Ligne[12]="           ";
    int Err=1;
    float nn=0;
    char Nstr[11]="";
    char Nstrx[11]="";
    char Lig[11]="";
    char Ch;
    int nc=0;

    strncpy(Lig,Ligne,N);
    gotoxy(x-1,y);
    cprintf(" %s",Lig);
    gotoxy(x,y);
    do {
         Ch=readkey();
         if ((int)(Ch)==8 && nc>0)
          { nc--;
            Nstr[nc]=' ';
            gotoxy(wherex()-1,y);
            cprintf(" ");
            gotoxy(wherex()-1,y);
          }                       
         else
         if ((int)(Ch)!=13 && nc<N && ((Ch>='0' && Ch<='9') || (Ch=='-') || (Ch=='.')))
          {
            Nstr[nc]=Ch;
            cprintf("%c",Ch);
            nc++;
          }

        if ((int)(Ch)==13 && (Nstr!="" || nc>N))
         {  strncpy(Nstrx,Nstr,nc);
            nn=0;
            nn = atof(Nstrx);
            if (errno == ERANGE) Err=-1;
            else
             {  gotoxy(x-1,y);
                cprintf(" %s",Lig);
                gotoxy(x,y);
                nc=0;strcpy(Nstr,"");
                Err=0;
             }
         }
    } while((int)(Ch)!=13 && (int)Ch!=27);

   if ((int)Ch==27) return(0);
   if (Err==0) return(nn);
   else return(0);
}/**end readreal**/



#endif


//====fonctions sur l'unite=============================================//
// int   keyboard(void);                                                //
// char  readkey(void);                                                 //
//                                                                      //
// long  readnum(int x,int y,char *s, int maxlength);                   //
// float readreal(int x,int y,char *s, int maxlength);                  //
// int   readstr(int x,int y,int cant,char *chStr);                     //
// int   readbox(int x,int y,char *SS,int longeur,int MaxCh);           //
//                                                                      //
// void  highbox(int x1,int y1,int x2,int y2,int attC );                //
// void  writechar(int x,int y,int count, char ch);                     //
// void  writexy(int col, int row, char *format, ...);                  //
// void  boxfill(int x1,int y1,int x2,int y2,char ch);                  //
// void  write_f(int xx, int yy, int Nbr, char *format, ...)            //
//                                                                      //
// char  gettexte();                                                    //
// char  getfond();                                                     //
// void  crt_setcolor(char Texte, char Fond);                           //
//                                                                      //
// void  changecursor(int insmode);                                     //
// unsigned int getcursor(void);                                        //
// void  typecursor(unsigned int shape);                                //
// void  initcursor(void);                                              //
// int   readstring(int x,int y,char *s, int maxlength);                //
//                                                                      //
// exemple:                                                             //
//     char *SS;                                                        //
//     SS = (char *) calloc(20, sizeof(char));                          //
//     readstring(1,2,SS,20);                                           //
//     free(SS);                                                        //
//======================================================================//

Unite Get_key

//============================================================//
// Unite Get_key.c utilitaire foctions divers                 //
// Programmation Turbo C++ Ver 3.0 Borland                    //
// programmeur: A.ARA                                         //
// 64150 Mourenx - France                                     //
// Copyright (s) 1976-2011                                    //
// Licence d'utilisation accord dans un but demostratif       //
// Unit Get_Key.c                                             //
//============================================================//

#ifndef __KEYCODE
#define __KEYCODE

#ifndef __DOS_H
#include<dos.h>
#endif

#ifndef __BIOS_H
#include<bios.h>
#endif

unsigned  short   Maj=0;
unsigned  short   Ctrl=0;
unsigned  short   Alt=0;
unsigned  short   Inser_Mode=1;
unsigned  short   Key_Code=0;

#define RIGHT  0x01
#define LEFT   0x02
#define CTRL   0x04
#define ALT    0x08

int keybios(void)
{
  int kkey, modifiers;
  int lo, hi;

  // Wait until a key is pressed *
  while (_bios_keybrd(_KEYBRD_READY) == 0);

  // Fetch the key that is waiting
  kkey = _bios_keybrd(_KEYBRD_READ);

  // Determine if shift keys are used
  modifiers = _bios_keybrd(_KEYBRD_SHIFTSTATUS);

  if (modifiers)
  {
    if (modifiers & RIGHT) Maj=1;
    else Maj=0;

    if (modifiers & LEFT) Maj=1;
    else Maj=0;

    if (modifiers & CTRL)  Ctrl=1;
    else Ctrl=0;

    if (modifiers & ALT)   Alt=1;
    else Alt=0;
  }

  lo = kkey & 0X00FF;

  if(lo==0 || lo==224) Key_Code=1;
  else
   Key_Code=0;

  hi = (kkey & 0XFF00) >> 8;

  return((lo == 0) ? hi : lo);
}         /**end keybios**/


//====================================//
// entree de un caractere sans echo   //
//====================================//
char readkey(void)             
{ 
   union REGS Register;
   Register.h.ah = 7;
   int86(0x21,&Register,&Register);
   return(Register.h.al);
}/*end readkey*/


int keyboard(void)
{ 
   union REGS Reg;
   int key;

   Reg.h.ah = 0;
   int86(0x16,&Reg,&Reg);
   if (Reg.h.al==0 || Reg.h.al==224)
    {
      key=(Reg.h.ah);
      Key_Code = 1;
    }
   else
    {
      key=(Reg.h.al);
      Key_Code = 0;
    }
   
   //etat du clavier
   Reg.h.ah = 2;
   int86(0x16,&Reg,&Reg);
   if (Reg.h.al & 128) Inser_Mode = 1;
   else Inser_Mode=0;
   if (Reg.h.al & 8)   Alt = 1;
   else Alt=0;
   if (Reg.h.al & 4) Ctrl = 1;
   else Ctrl=0;
   if (Reg.h.al & 2) Maj = 1;
   else Maj=0;
   return(key);

}/*end keyboard*/



float Read__Real(int x,int y,int N, int *Ent)
{   float nn;
    char NStr[11];
    char Ch;
    int Nc;

    nn=0;
    Nc=0;

    gotoxy(x,y);
    cprintf("          ");
    gotoxy(x,y);
    NStr[0]='\0';

    Ch=(char)*Ent;
    if (strchr("0123456789-.", Ch) != NULL)  Ch=(char)*Ent;
    else Ch='#';
    do {
          if (!Key_Code && Ch==8 && Nc>0)
           {
             strncpy(NStr,NStr,strlen(NStr)-1);
             gotoxy(wherex()-1,y);
             cprintf(" ");
             gotoxy(wherex()-1,y);
             Nc--;
           }
          else
          if ((!Key_Code) && (Ch!=13) && (Nc<N) && (strchr("0123456789-.", Ch) != NULL))
           {
              cprintf("%c",Ch);
              NStr[Nc]=Ch;
              Nc++;
           }
          Ch=readkey();
          if ((!Key_Code) && (Ch==13) && (strcmpi(NStr,"")!=0) && (Nc<=N))
           {
              nn = atof(NStr);
           }

       } while (Ch!=13 && Ch!=27);
    *Ent=Ch;
    if (Ch==27)  return(0);
    else return(nn);
}/**end Read_Real**/

#endif

RotationG3 C++

//=================== FICHIER DE CDNUM ================// // Graphe Trace Usinage machines commande numerique N750 // // programmation Turbo C++ ver 3.0 Borland // // Copyright (S) 1997-2011 // // programmeur A.Ara // // 64150 Mourenx France. // // Licence d'utilisation accord dans un but démonstratif // // File : rotation_G3.c logiciel CDnum c.n pour le bois // //=======================================================// #include<stdlib.h> #include<string.h> #include<conio.h> #include<MATH.H> //============================// // Retourne le cosinus // //============================// double Cosinus(float nn) { return(cos(M_PI*nn/180)); }/*end*/ //============================// // Retourne le sinus // //============================// double Sinus(float nn) { return(sin(M_PI*nn/180)); }/*end*/ //===============================================// // Rotation sens G3 valeur de angle // //===============================================// void Rotation_sur_G3(float *X,float *Y,float Angle) { float XX,YY; if (Angle>=0 && Angle<=360) { XX = (*X * Cosinus(Angle)) - (*Y * Sinus(Angle)); YY = (*X * Sinus(Angle)) + (*Y * Cosinus(Angle)); *X=XX; *Y=YY; } }/*end Rotation_sur_G3**/ //======================================// // rotation d'un poin en degres 0..360 // // sens trigonometrique G3 // //======================================// void Donne_Rotation_G3(int X1,int Y1) { int key,Y,Chois; float N,DX1,DY1,CENX,CENY,RX,RY; float Ang; char SnX[9],SnY[9]; DX1=0;DY1=0; RX=0;RY=0; CENX=0;CENY=0; Ang=0; textattr(Menu_Color); boxfill(X1,Y1,X1+30,Y1+8,' '); Crtrectangle(X1,Y1,X1+30,Y1+8,DOUBLE); Putxy(X1+10,Y1," Rotation G3 "); Putxy(X1+10,Y1+8," F1 = Calcul "); Putxy(X1+3,Y1+1,"Centre X :"); Putxy(X1+3,Y1+2,"Centre Y :"); Putxy(X1+3,Y1+3,"Angle :"); Putxy(X1+3,Y1+4,"Coordinate X :"); Putxy(X1+3,Y1+5,"Coordinate Y :"); Y=1; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); do { CSOFF(); Key=keyboard(); if (Key==80 && Y<5) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Y++; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); } else if (Key==72 && Y>1) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Y--; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); } else if ((! Key_Code) && ((Key==13) || (Key==45) || (Key>=48 && Key<=57))) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); N=0; N=Read__Real(X1+19,Y+Y1,10,&Key); if (N>100000 || N<-100000) Key=27; switch(Y) { case 1: if (Key==27) Putxy(X1+19,Y+Y1,"%6.3f",CENX); else CENX=N; break; case 2: if (Key==27) Putxy(X1+19,Y+Y1,"%6.3f",CENY); else CENY=N; break; case 3: if (Key==27 || (N<=0) && (N>=360)) Putxy(X1+19,Y+Y1,"%6.3f",Ang); else Ang=N; break; case 4: if (Key==27) Putxy(X1+19,Y+Y1,"%6.3f",DX1); else DX1=N; break; case 5: if (Key==27) Putxy(X1+19,Y+Y1,"%6.3f",DY1); else DY1=N; break; } if (Y<5) Y++; else Y=1; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Key=0; } if (Key_Code && Key==59) { RX=DX1-CENX; RY=DY1-CENY; Rotation_sur_G3(&RX,&RY,Ang); textattr(116); Putxy(X1+3,Y1+6,"Rotation X : "); Putxy(X1+19,Y1+6,"%6.4f",RX+CENX); Putxy(X1+3,Y1+7,"Rotation Y : "); Putxy(X1+19,Y1+7,"%6.4f",RY+CENY); textattr(Menu_Color); } }while(Key!=27); }/**end donne rotation**/ //============================================================================================// // Rotation Centre X, Y | Angle degrés 0..360 | coordinat X, Y // // Donne le point X,Y de rotation sens trigonométrique G3 // // G3 = sens inverse horaire : 3h:0, 12h :90, 9h :180, 6h : 270° etc. // // G2 = interpolation circulaire sens anti-trigonométrique sens horaire // // Exemples de rotation G3 sens // // centreX:50 centreY:50 angle:90 cordix:100 cordix:50 RotationX:50.00 RotationY:100.00 // // centreX:50 centreY:50 angle:45 cordix:100 cordix:50 RotationX:85.355 RotationY:85.355 // // centreX:50 centreY:50 angle:90 cordix:0 cordix:100 RotationX:0.000 RotationY:0.000 // //============================================================================================//


Distance & angle C++

//===================================================================//
// Pour le calcul du point (A) ou point (B) avec angle degrés,       // 
// sens trigonométrique G3.                                          //
// G3 = Sens inverse horaire:3h:0°,12h:90°,9h:180°,6h:270° etc.      //
// exemples distance et rotation                                     //
// Begin:0   Begin:0  ... end:50  end:50   Rayon:70.7110  Angle:45°  //
// Begin:0   Begin:0  ... end:100 end:100  Rayon:141.421  Angle:45°  //
// Begin:0   Begin:0  ... end:100 end:50   Rayon:111.803  angle:27°  // 
// Begin:0   Begin:0  ... end:50  end:100  Rayon:111.803  angle:63°  // 
// Begin:50  Begin:50 ... end:0   end:100  Rayon:70.7113  angle:135° // 
// Begin:100 Begin:100... end:50  end:50   Rayon:70.7113  angle:225° // 
// Begin:50  Begin:0  ... end:50  end:100  Rayon:100.00   angle:90°  // 
// Begin:0   Begin:0  ... end:100 end:10   Rayon:100.499  angle:6°   // 
//===================================================================//

float Radian_Degre(float Radi) { return(Radi*(360/(2*M_PI))); } int Angle__G3(float XX1,float YY1,float CXX,float CYY,float RR) { float Angle; Angle=400; /**depar position 0**/ if (YY1>CYY) { if (XX1>CXX) Angle=Radian_Degre(asin((YY1-CYY)/RR)); else if (XX1<CXX) Angle=Radian_Degre(asin((CXX-XX1)/RR))+90; else if ((ceil((YY1-RR))==ceil(CYY)) && (ceil(XX1)==ceil(CXX))) Angle=90; } else if (CYY>YY1) { if ((ceil(CYY-RR)==ceil(YY1)) && (ceil(CXX)==ceil(XX1))) Angle=270; else if (CXX>XX1) Angle=180+Radian_Degre(asin((CYY-YY1)/RR)); else if (CXX<XX1) Angle=270+Radian_Degre(asin((XX1-CXX)/RR)); } else if ((ceil(CYY)==ceil(YY1)) && (ceil(CXX+RR)==ceil(XX1))) Angle=0; else if ((ceil(YY1)==ceil(CYY)) && (ceil(CXX)==ceil(XX1+RR))) Angle=180; if ((Angle>=0) && (Angle<=360)) return(ceil(Angle)); else return(400); }/**end Angle__G3**/ float HCalcul_Rayon(float Cx,float Cy, float X,float Y, float *Angle) { float R,C,B,AG; C=abs(Cx-X); B=abs(Cy-Y); if (C==0) C=0.00001; if (B==0) B=0.00001; R=sqrt(abs(C*C)+abs(B*B)); AG=Angle__G3(X,Y,Cx,Cy,R); if (AG==400) AG=-1; *Angle=AG; return(R); }/*end*/ void Cherche_Rayon(int X1,int Y1) { int Key,Y,Chois; float N,DX1,DY1,CENX,CENY,Ray; float Ang; DX1=0;DY1=0; CENX=0;CENY=0; Ang=0; Ray=0; textattr(Menu_Color); boxfill(X1,Y1,X1+30,Y1+7,' '); Crtrectangle(X1,Y1,X1+30,Y1+7,DOUBLE); Putxy(X1+8,Y1," Rayon Angle "); Putxy(X1+10,Y1+7," F1 = Calcul "); Putxy(X1+3,Y1+1,"Begin X :"); Putxy(X1+3,Y1+2,"Begin Y :"); Putxy(X1+3,Y1+3,"End X :"); Putxy(X1+3,Y1+4,"End Y :"); Y=1; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); do{ CSOFF(); Key=keyboard(); if (Key==80 && Y<4) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Y++; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); } else if (Key==72 && Y>1) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Y--; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); } else if ((! Key_Code) && ((Key==13) || (Key==45) || (Key>=48 && Key<=57))) { highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); N=0; N=Read__Real(X1+16,Y+Y1,10,&Key); if ((N>100000) || (N<-100000)) Key=27; switch(Y) { case 1: if (Key==27) Putxy(X1+16,Y+Y1,"%6.4f",CENX); else CENX=N; break; case 2: if (Key==27) Putxy(X1+16,Y+Y1,"%6.4f",CENY); else CENY=N; break; case 3: if (Key==27) Putxy(X1+16,Y+Y1,"%6.4f",DX1); else DX1=N; break; case 4: if (Key==27) Putxy(X1+16,Y+Y1,"%6.4f",DY1); else DY1=N; break; }/*switch*/ if (Y<4) Y++; else Y=1; highbox(X1+2,Y+Y1,X1+28,Y+Y1,BX); Key=0; } if (Key_Code && Key==59) { Ang=0; Ray=HCalcul_Rayon(CENX,CENY,DX1,DY1,&Ang); textattr(116); Putxy(X1+3,Y1+5,"Rayon : "); Putxy(X1+16,Y1+5,"%6.4f",Ray); Putxy(X1+3,Y1+6,"Angle ¦ : "); Putxy(X1+16,Y1+6,"%6.4f%c",Ang,167); textattr(Menu_Color); } }while(Key!=27); /*end do*/ }/**end cherche rayon**/

© 2009 - 2012   Parti Pour Les Animaux - Pays : France | All GNU  CopyLeft WebSite  |  Last Updated : Mai 13, 2012   |  Page Editor: A. Ara  | SiteMap
Cet emplacement web non-commercial, et totalement libre & indépendant de tout les parti politique ou d'organisme officiel de toute nature.
Nous réflexions sont exclusivement l'avis de personnes qui rejettent le massacre que la société fait aux animaux pour tout motif.