Fichier n-c.txt 09/08/95 06/12/1995 11:57 Notes sur le langage C
PRIORITES 09/08/95 09/08/95
P PTR XX LOGIQUE XX ARITHMETIQUE XX ------------------------------------------------------------------------------ 1 array [] function () Member selection . Member selection -> ------------------------------------------------------------------------------ 2 indirection * logical not ! type cast (type) address of & size in bytes sizeof() Arithm Negat - Bitwise comp ~ Increment ++ Decrement -- ------------------------------------------------------------------------------ 3 Multiplication * Division / Remainder % ------------------------------------------------------------------------------ 4 Addition + Soustraction - ------------------------------------------------------------------------------ 5 left shift << right shift >> ------------------------------------------------------------------------------ 6 less than < greater than > less or equal <= greater or equ >= ------------------------------------------------------------------------------ 7 Equality == Inequality != ------------------------------------------------------------------------------ 8 bitwise and & ------------------------------------------------------------------------------ 9 bitwise and/or | ------------------------------------------------------------------------------ 10 bitwise xor ^ ------------------------------------------------------------------------------ 11 logical and && ------------------------------------------------------------------------------ 12 logical or || ------------------------------------------------------------------------------ 13 Conditional t?x:y ------------------------------------------------------------------------------ 14 Assignment = add ass += sub ass -= mul ass *= div ass /= rem ass %= Rshift ass >>= Lshift ass <<= bitAnd ass &= bitOr ass |= bitXor ass ^= ------------------------------------------------------------------------------ 15 sequentiel eval , ------------------------------------------------------------------------------ BE CAREFULL with << & >>, they have inferior priority to + & - !! To remplace x*1024 <=> (x<<10) x/2048 <=> (x>>11) Don't forget the ()!!!! Histo Concatenation avec use-c.txt 16/09/93:19175 ============================================================================== preprocessor commande ============================================================================== ------------------------------------------------------------------------------ #ifdef, #ifndef Directive <#ifdef> ------------------------------------------------------------------------------ #ifndef Syntax #ifdef identifier #ifndef identifier These directives test whether identifier is currently defined. The #ifdef directive returns true (nonzero) if it is currently defined and returns false (0) if it is not. The #ifndef directive returns the opposite. The #if directive combined with the defined operator is preferred for all new programs because they can be used in expressions that check multiple conditions on the same line. For example: #ifdef __cplusplus #ifdef M_I8086 #pragma message ("C++ and 8086/88") #endif #endif #if defined( __cplusplus ) && defined( M_I8086 ) #pragma message ("C++ and 8086/88") #endif ------------------------------------------------------------------------------ #undef Directive <#undef> ------------------------------------------------------------------------------ Syntax #undef identifier The #undef directive removes the current definition of identifier, which must have been previously defined with the #define directive. ------------------------------------------------------------------------------ #if, #elif, #else, #endif Directive <#if>, <#elif>, <#else>, <#endif> ------------------------------------------------------------------------------ Syntax #if test expression [text-block] [#elif test expression text-block] . . . [#else text-block] #endif This set of directives evaluates each test expression associated with an #if or #elif directive until a true (nonzero) expression is found, then processes the text-block associated with that test expression. If there is an #else clause, the text-block associated with it is processed only if no test expression in the #if or #elif clauses has a nonzero value. The test expression can be any expression that evaluates to a constant, and can contain logical operators and the defined operator. It cannot use the sizeof operator, type casts, or the float or enum types. The text-block can contain C code or compiler directives. ------------------------------------------------------------------------------ Token-Pasting Operator Operator <##> ------------------------------------------------------------------------------ Syntax token##parameter parameter##token The token-pasting operator is used only with macros. If ## precedes or follows a formal parameter in the definition of a macro, the actual argument is concatenated with the token on the other side of the ## when the macro is expanded. For example, #define printvar(x) printf("%d", var##x) causes the statement printvar(7); to be expanded into printf("%d",var7); ------------------------------------------------------------------------------ Charizing Operator Operator <#@> ------------------------------------------------------------------------------ Syntax #@parameter The charizing operator is used only with the arguments of macros. If a #@ precedes a formal parameter in the definition of the macro, the actual argument is enclosed in single quotation marks and treated as a character when the macro is expanded. For example, #define makechar( x ) #@x causes the statement a = makechar( b ); to be expanded into a = 'b'; causes the statement printvar( 7 ); to be expanded into printf( "%d", var7 ); The single-quotation character cannot be used with the charizing operator. ------------------------------------------------------------------------------ defined Operator <defined> ------------------------------------------------------------------------------ Syntax defined( identifier ) !defined( identifier ) The defined operator is used with the #if directive to test whether identifier is currently defined. It returns true (nonzero) if identifier is currently defined and returns false (0) if it is not. The logical NOT operator (!) can be used to reverse the logic of the defined operator. For example, #if defined( __cplusplus ) #if defined( __cplusplus ) && !defined( M_I8086 ) #ifdef #if defined #else #endif ============================================================================== Pointeur Long /Court ============================================================================== Format printf %p Far Pointeur %hp Near Pointeur %Fs Far string %.200Fs Far string cut at 200 %lX Long %X short %hx short __DATE__ char * .res date de la compile __TIME__ char * .res time de la compile __FILE__ char * __LINE__ int __TIMESTAMP__ char * date & time du fichiers source ============================================================================== Expression ambigues 09/08/95 21/08/95 ============================================================================== struct {char toto[x];char *tata} FAR * tata; tata->toto => pointeur FAR tata->tata => pointeur FAR struct {char* FAR titi} NEAR *titi; titi->titi => pointeur FAR titi => pointeur NEAR *qsd->dsfq[dsqf]->tyty.eee <=> *(qsd->dsfq[dsqf]->tyty.eee) &qsd->dsfq[dsqf]->tyty.eee <=> &(qsd->dsfq[dsqf]->tyty.eee) &(xx+yy) <> &xx+yy *(xx+yy) <> *(xx)+yy &(xx++) <> &xx++ <=> &(xx),xx++ *(xx++) <> *xx++ <=> (*x) ,*x++ toto< tata-1 && toto>4 <> (toto<(tata-1)) && (toto>4) 1>2?3:4 <> 1>(2?3:4) <=> (1>2)?3:4 En regle generale toujours delimiter la partie externe de (?:) Declaration de fonction: typedef LONG (WINAPI *WEPfn)(void); Pointeur de fonction de type: LONG WINAPI exempleWepFn(void); Ordre d'evaluation: L'ordre d'evaluation n'est jamais garanties même si ces parentheses sont ajoutées. Seul , && || garantissent l'ordre de gauche à droite. ex: x=(printf ("toto"))+(print("tata"))*3; pourra être evalué comme toto, tata ou bien tata,toto Car l'addition est commutative. Par contre x= toto,tata||titi est forcement evalué dans l'ordre toto,tata et titi si tata est faux. titi n'est jamais evalué si tata est vrai. -------------------------------------------------------------------------- 0x10 16 1<<4 | 0x100 256 1<<8 | 0x1000 4096 1<<12 0x20 32 1<<5 | 0x200 512 1<<9 | 0x2000 8192 1<<13 0x40 64 1<<6 | 0x400 1024 1<<10 | 0x4000 16384 1<<14 0x80 128 1<<7 | 0x800 2048 1<<11 | 0x8000 32768 1<<15 -------------------------------------------------------------------------- if (0!=stuff) if (stuff) printf("\nstuff!=0"); printf("\nstuff!=0"); else else printf("\nstuff==0"); printf("\nstuff==0"); if (0==stuff) if (!stuff) printf("\nstuff==0"); printf("\nstuff==0"); else else printf("\nstuff!=0"); printf("\nstuff!=0"); ============================================================================== LES BIDOUILLES EN C ============================================================================== declaration de cellule ---------------------- typedef struct ma_structure !!!! { int valeur; ma_structure *fils_gauche; ma_structure *fils_droit; } UNE_CELLULE,*UN_POINTEUR_DE_CELLULE struct{ char c[][]; int toto; }= { { "...","...."}, /* don't forget , after the bracket */ 10 } union { int initializable; char non_initializable[2]} val={0x1234}; /* only first member of union */ union { /* can be initialize */ char initializable[2], int noninitializable} val={{'0','1'}}; UN_POINTEUR_DE_CELLULE fonction() { UNE_CELLULE tempo; } remarque: tableau et structure ne ce passe que par adresse !!! (En realite on peut passer une structure par variable et le recopier maise la perte d'efficacite est trop importante) tableau double dimension ATTENTION tableau commencent a ZERO jusqu'a N-1 ------------------------ Deux solutions distinctes dimension = constante tab[10][10] ce qui revient strictement a ecrire tab[100] en effet tab[i][j] ::== tab[i*10+j] dimensions inconnues: allocation dynamique declaration: float **tab initialisation: tab=calloc(nb_ligne,sizeof(float *)) (for i=0; i<nb_ligne; i++) tab[i]=calloc(nb_colonne,sizeof(float)) utilisation : tab[i][j]=5 ::== ((tab->i)->j)=5 !!! Conclusion: ----------- On utilise toujours la meme syntaxe pour les tableaux, que ce soit dans le programme principal ou dans les fonctions et quelque la structure physique. Toutefois cette syntaxe a chaque fois une signification differente. L'ecriture est homogene ("facilite" du C) mais pas le sens. POINTEUR DE FONCTION -------------------- -declaration int (__cdecl *fn)(float); ^ ^ ^ ^ | | | | | | | `---- parameters of the function | | `------- name of the pointor | `---------------- convention d'appel de la fonction | `------------------------ return type of the function pointeur sur une fonction retournant un entier et prenant comme parametre un flot. -as a parameter extern fn_bidule(param1,param2, void (*)(void)); ^ ^ ^ | | | | | `---- parameters of fn | | | `------- pointor to a fn | `------------- return type -as a prototype typedef void FN_VOID(int); typedef void (*PTR_FN_VOID)(int); -initialisation fn=transforme_flottant_en_entier; -utilisation printf("La valeur arondie est %d",fn(5.3)); PASSAGE de parametre par valeur (type int,float) ------------------------------------------------ a partir d'une fonction: fonction2(int x1,int x2) { x2 *=3; } ma_fonction (int x1,int x2) { x1 *= x2; x2= fonction2(x1,x2); } main() { int x1,x2; ma_fonction(x1,x2); } on veut les transformer avec passage par adresse 1ere regle: ----------- rajouter * a l'interieur des fonctions 2eme regle: ----------- declarer avec une etoile dans le prototype 3eme regle: ----------- rejouter & pour l'appel 4eme regle: ----------- &* = rien du tout 5eme regle: ----------- tab[10] = * (tab+10) -> tableau transparant a l'interieur des fonctions 6eme regle: ----------- dans le prog principal dans les fonctions str.nom => str->nom == (*str).nom 7eme regle: ----------- structure et tableau se passe tjs par adresse tab est deja une pseudo-adresse str aussi APPLICATION: ============ fonction2(int *x1, int *x2) { *x2 *= 3; } ma_fonction(int *x1,int *x2) { *x1 *= *x2; /* attention aux abrevations, mettre des espaces */ fonction2(x1,x2); /*x1,x2 sont deja des adresses*/ } main() { int x1,x2; ma_fonction(&x1,&x2); } ============================================================================== RUNTIME STANDARD 11/04/96 96/12/11 17:09 ============================================================================== if (Ptr= (char *)strstr("texte","cle")) -> recherche cle dans texte. Nota: strstr("texte","") -> retourne un pointeur au debut de texte if (Ptr= (char *)strchr("texte",'K')) -> recherche K dans texte Nota: strchr("texte",0) -> retourne un pointeur sur la fin de texte. if (Index=(int)strcspn("texte","set")) Ptr="texte"+Index; -> recherche la premiere occurance d'un caractere appartenant … charset dans texte. Nota: retourne un index if (Index=(int)strspn("texte","set")) Ptr="texte"+Index; -> recherche la premiere occurance d'un caractere N'APPARTENANT PAS … charset dans texte. Nota: retourne un index Les fonctions suivantes sont dangereuses dans certains contextes particuliers: calloc _execv _fullpath _spawn _execve _getcwd _spawnve _execvp _getdcwd _spawnvp _execvpe putenv _spawnvpe _execcl _searchenv _spawnl _execcle system _spawnle _execlp setvbuf _spawnlp _execlpe _tempnam _spawnlpe fgetc getc _fgetchar getchar fgets gets _getw fprintf printf vfprintf fputc putc vprintf _fputchar putchar fputs puts _putw fread fscanf scanf fseek fsetpos fwrite ungetc _strdup Toutes ces fonctions appellent malloc qui fait appel au system. Il est … not‚r que sprintf et vsprintf n'en font pas partie. Low Level or standard input/output _read,_write and _fread ont besoin du systeme aussi. Les fonctions dependant du systemes: _getcwd et time. Enfin longjump est dangereux. STDIO.H ------- getc(fp) macro a resultat int; restitue le caractere suivant du FILE *fp flot pointe par fp;EOF si erreur ou fin de fichier getchar() macro= getc(stdin) putc(c,fp) macro a resultat int; ajoute le caractere c au flot char c;FILE *fp; pointe par fp; retourne c ou EOF si PB putchar(c) macro=puc(c,stdout) feof(fp) macro a resultat int; retourne une valeur non nulle FILE *fp; si fin de flot pointe par fp ungetc(c,fp) macro a resultat int; replace le caractere c dans le FILE *fp; flot pointe par fp; donc le prochain getc recevra c; char c; retourne c ou EOF si PB ungetch(c) macro=ungetc(c,stdin) fflush(fp) force le vidage du tampon associe a fp; le faire avant FILE *fp; une redirection char *fgets(ch,n,fp) lit dans le flot pointe par fp n-1 caracteres ou moins char *ch; s'il y a un return et les place dans la chaine ch int n; (avec \n si il y a) et ajoute \0; retourne ch ou FILE *fp; NULL si fin de flot ou PB. gets(ch) macro=fgets(ch,???,stdin) int*fputs(ch,fp) envoie tous les caracteres de la chaine ch (sauf \0) cahr *ch; dans le flot pointe par fp; retourne le dernier FILE *fp; caractere envoye ou EOF si PB. puts(ch) macro=fputs(ch,stdout) int fprintf(fp,format,valeur1, valeur2, ...) FILE *fp; char *format; Convertit les valeurs v1, vlauer v2, ... sous forme de chaine de caractere, selon le format specifie et l'ecrit dans le flot pointe par fp; retourne le nombre d'octects ecrits ou EOF si PB. Dans FORMAT, tous les caracteres sont imprimes tel quel sauf: \n qui fait passer a la ligne, \t la tabulation, et les specifications de conversion d'une valeur commancant par % et suivi, oprtionnellemnt par: un - pour un cadrage a gauche dans le champ, un nombre indiquant la longueur du champ, on nombre.nombre pour les reels ou le 2nd indique le nombre de chiffres apres le . un caractere: d pour un entier decimal, o pour un entier octal, x pour un entier hexadecimal, eventuellement precede de l pour long, e pour un reel en virgule flottante, f pour un reel avec un point fixe, c pour un caractere, s pour une chaine, u pour un entier non signe. Sous Dos: \n est converti par printf en \r\n == \0x0D\0x0A == CR LF The escape sequences allow you to use a sequence of characters to represent special characters. Escape sequences are as follows: Seq. Name Seq. Name \a Alert (bell) \? Literal quotation mark \b Backspace \' Single quotation mark \f Formfeed \" Double quotation mark \n Newline(LineFeed) \\ Backslash \r Carriage return \ddd ASCII character in octal notation \t Horizontal tab \xdd ASCII character in hex notation \v Vertical tab Note that for characters notated in hexadecimal, the compiler ignores all leading zeros. It establishes the end of the hex- specified escape character when it encounters either the first non-hex character or more than two hex charactersÄÄnot including leading zeros. In the latter case, it reports an error and ignores all characters beyond the second one. DONC: %d entier %u entier non signe %ld entier long %lu entier long non signe %f reel %lf long reel %c caractere %s chaine de caractere %x Hexa Lower Case %lX Long Hexa Upper Case %p Pointor %Np Near pointor %Fp Far pointor printf(for,v1,v2,..) macro = fprintf(stdout,for,v1,v2,...) int fscanf(fp,for,liste_de_pointeur_sur_objet) FILE *fp; char *for; permet de lire dans le flot pointe par fp une suite de caractere repondant au format sepcifie et , toujours selon le format, d'en extraire, apres conversion, des valeurs, qui sont affectees aux objets designes dans la liste; retourne le nombre de valeurs converties et affectees ou 0 ou EOF si PB. Dans format, tous les caracteres ordinaires sont lus sans affectation execptes les specifications de conversion d'une valeur commencant par % et suivi, optionnellement pas: un * signifie qu'il n'y a pas d'affectation a realiser un nombre indiquant la longueur du champ (tres utile pour les chaines) un caractere de conversion comme fprintf. scanf(for,v1,v2..) macro = fscanf(stdin,for,v1,v2..) sous unix: DESCRIPTION scanf() and nl_scanf() read from the standard input stream stdin. fscanf() and nl_fscanf() read from the named input stream. sscanf() and nl_sscanf() read from the character string s. Each function reads characters, interprets them according to the control string format argument, and stores the results in its pointer arguments. If there are insufficient arguments for the format, the behavior is undefined. If the format is exhausted while arguments remain, the excess arguments are ignored. The control string contains conversion specifications and other characters used to direct interpretation of input sequences. The control string contains: + White-space characters (blanks, tabs, newlines, or formfeeds) that cause input to be read up to the next non-white-space character (except in two cases described below). + An ordinary character (not %) that must match the next character of the input stream. + Conversion specifications, consisting of the character %, an optional assignment suppressing character *, an optional numerical maximum-field width, an optional l (ell), h or L indicating the size of the receiving variable, and a conversion code. + The conversion specification can alternatively be prefixed by the character sequence %n$ instead of the character %, where n is a decimal integer in the range (1-{NL_ARGMAX}) (NL_ARGMAX is defined in <limits.h>). The %n$ construction indicates that the value of the next input field should be placed in the nth argument, rather than to the next unused one. The two forms of introducing a conversion specification, % and %n$, must not be mixed within a single format string with the following exception: Skip fields (see below) can be designated as %* or %n$*. In the latter case, n is ignored. Unless the specification contains the n conversion character (described below), a conversion specification directs the conversion of the next input field. The result of a conversion specification is placed in the variable to which the corresponding argument points, unless * indicates assignment suppression. Assignment suppression provides a way to describe an input field to be skipped. An input field is defined as a string of non-space characters; it extends to the next inappropriate character or until the field width, if specified, is exhausted. For all descriptors except [ and c, white space leading an input field is ignored. The conversion code indicates the interpretation of the input field; the corresponding pointer argument must be of a restricted type. For a suppressed field, no pointer argument is given. The following conversion codes are legal: % A single % is expected in the input at this point; no assignment is done. d A decimal integer is expected; the corresponding argument should be an integer pointer. u An unsigned decimal integer is expected; the corresponding argument should be an unsigned integer pointer. o An octal integer is expected; the corresponding argument should be an unsigned integer pointer. x, X A hexadecimal integer is expected; the corresponding argument should be an unsigned integer pointer. The x and X conversion characters are equivalent. i An integer is expected; the corresponding argument should be an integer pointer. The value of the next input item, interpreted according to C conventions, will be stored; a leading 0 implies octal, a leading 0x implies hexadecimal; otherwise, decimal is assumed. n Cause the total number of bytes (including white space) scanned since the function call to be stored; the corresponding argument should be an integer pointer. No input is consumed. The function return value does not include %n assignments in the count of successfully matched and assigned input items. e,E,f,g,G A floating-point number is expected; the next field is converted accordingly and stored through the corresponding argument, which should be a pointer to a float. The input format for floating-point numbers is an optionally signed string of digits, possibly containing a radix character, followed by an optional exponent field consisting of an E or an e, followed by an optional +, -, or space, followed by an integer. The conversion characters E and G behave the same as, respectively, e and g. C A character is expected; the corresponding argument should be a wchar_t pointer. The normal skip-over- white-space is suppressed in this case; to read the next non-space character, use %1S. The character is read and converted into a wide character according to the setting of LC_CTYPE. If a field width is given, the corresponding argument refers to a wide character array; the indicated number of characters is read and converted. c A character is expected; the corresponding argument should be a character pointer. The normal skip- over-white-space is suppressed in this case; to read the next non-space character, use %1s. If a field width is given, the corresponding argument refers to a character array; the indicated number of characters is read. S A character string is expected; the corresponding argument should be a wchar_t pointer pointing to an array of wide characters large enough to accept the string and a terminating (wchar_t)0, which is added automatically. Characters are read and converted into wide characters according to the setting of LC_CTYPE. The input field is terminated by a white- LC_CTYPE. The input field is terminated by a white- space character. scanf() cannot read a null string. s A character string is expected; the corresponding argument should be a character pointer pointing to an array of characters large enough to accept the string and a terminating \0, which is added automatically. The input field is terminated by a white-space character. scanf() cannot read a null string. [ Indicates string data and the normal skip-over- leading-white-space is suppressed. The left bracket is followed by a set of characters, called the scanset, and a right bracket; the input field is the maximal sequence of input characters consisting entirely of characters in the scanset. The circumflex (^), when it appears as the first character in the scanset, serves as a complement operator and redefines the scanset as the set of all characters not contained in the remainder of the scanset string. Construction of the scanset follows certain conventions. A range of characters may be represented by the construct first-last, enabling [0123456789] to be expressed [0-9]. Using this convention, first must be lexically less than or equal to last; otherwise, the dash stands for itself. The dash also stands for itself when it is the first or the last character in the scanset. To include the right square bracket as an element of the scanset, it must appear as the first character (possibly preceded by a circumflex) of the scanset, in which case it will not be interpreted syntactically as the closing bracket. The corresponding argument must point to a character array large enough to hold the data field and the terminating \0, which are added automatically. At least one character must match for this conversion to succeed. p A sequence of unsigned hexadecimal numbers is expected. This sequence may be produced by the p expected. This sequence may be produced by the p conversion character of printf(). The corresponding argument shall be a pointer to a pointer to void into which the value represented by the hexadecimal sequence is stored. The behavior of this conversion is undefined for any input item other than a value converted earlier during the same program execution. The conversion characters d, i, and n can be preceded by l or h to indicate that a pointer to a long int or short int rather than to an int is in the argument list. Similarly, the conversion characters u, o, x, and X can be preceded by l or h to indicate that a pointer to unsigned long int or unsigned short int rather than to an unsigned int is in the argument list. Finally, the conversion characters e, E, f, g, and G can be preceded by l or L to indicate that a pointer to a double or long double rather than to a float is in the argument list. The l, L or h modifier is ignored for other conversion characters. The scanf() functions terminate their conversions at EOF, at the end of the control string, or when an input character conflicts with the control string. In the latter case, the offending character is left unread in the input stream. FILE *fopen(ch,m) char *ch,*m; Ouvre le fichier de nom ch selon le mode m precise: m="r" en lecture, "w" en ecriture (s'il existe, l'ancien est perdu, sinon est cree), "a" (append) ouvert a l'ecriture en fin de fichier; retourne un pointeur ou NULL si PB. TESTER existance d'un fichier: QNX: FILE *file; if (!(file=fopen(filename,"n"))) printf("\nFile %s do not exist",filename); else fclose(file); DOS: if (!fopen(filename,"r")) printf("\nFILE %s do not exist",filename); else fclose(file); int fclose(fp) FILE *fp; Ferme le flot pointe par fp en ayant vide son tampon; retourne 0, ou EOF si PB. STDLIB.H (ne pas l'inclure) -------- int atoi(ch) char *ch convertit ch en un int qu'elle retourne; 0 si PB int rand() renvoit un nombre aleatoire void srand(init) unsigned init; initialise la fonction pseudo-periodique rand; par defaut: srand(1) CTYPE.H ------- isalpha(c) macro a resultat int; verifie si c est une lettre int c; isdigit(c) macro a resultat int; verifie si c est un chiffre islower(c) macro a resultat int; verifie si c est une minuscule isupper(c) macro a resultat int; verifie si c est une majuscule tolower(c) macro a resultat int; convertit c en miniscule toupper(c) macro a resultat int; convertit c en majuscule STRING.H -------- int strlen(ch) char *ch; Donne la longeur de la chaine ch (excepte le \0 final) int strcpy(destination,origine) char *destination,*origine; Copie le contenu de la chaine pointe par origine dans celle pointe par destination, retourne destination. int strcat(destination,origine) char *destination,*origine; Copie le contenu de la chaine pointe par origine a la fin de celle pointe par destination, retourne destination. int strcmp(ch1,ch2) Compare lexicographiquement les contenus des 2 chaines; retourne un entier positif si ch1 > ch2, 0 si ch1=ch2, sinon un entier negatif ATTENTION strcmp("AA","BB") est evalue a VRAI !!! <0 strcmp("AA","AA") est evalue a FAUX !!! 0 ALLOC.H ------- char *malloc(t) unsigned t; Alloue une zone memoire de "taille t"; retourne un pointeur sur cette zone ou NULL si PB. Cette zone memoire est contigue. char *calloc(n,t) int n; unsigned t; Alloue une zone memoire pour memorise n objets de "taille t"; ] retourne un pointeur sur cette zone ou NULL si PB. Cette zone memoire peut presenter des trous entre chaque element (Pb d'alignement memoire) free(ptr) char *ptr; Libere la zone pointe par ptr (obtenu par malloc ou calloc) SORT.H: ======= _lfind linear search for a specified key: _lfind(cle,base,SizeOfBase,WidthOfBase,FnCompare); _lsearch: perform linear search for a value: add it at the end if not found. Liste Ordonn‚e: qsort sort a list bsearch perform search on a sorted list => return NULL if not found: if (NULL==bsearch()) { addIt; qsort(); } USING A VARIABLE LIST OF ARGUMENTS AND FILE ARGUMENTS ===================================================== A function in C can use a variable number of arguments using va_list, va_start,va_arg and va_end macros defined in stdarg.h. It change nothing on the calling side but onl the implementation on the function side. ex: /* file warning.c*/ #include <stdarg.h> #include <stdio.h> int warning(format) const char *format; { int result; va_list ap; fprintf(stderr,"\nWarning"); va_start(ap,format); result=vfprintf(stderr,format,ap); va_end(ap); } /* file buggy.c */ #extern warning(const char *format,...); /* the three ... means to the compiler a variable number of arguments */ int main(argc,argv) int argc;char *argv[]; { if (argc<3) warning("\nnumber of argument %d, file:%s",argc,argv[0]); } syntax: void va_start(va_list ap, paramN ) Type va_arg(va_list ap,Type) va_arg() is evaluated as a quantity of type Type void va_end(va_list ap) These macros can be used to maitain a list of variables of mixed types on the stack. The variables must have been put on the stack by a function call. The va-list (for "variable arguments list") is initialized in the function whi is called. The macro va_start() intializes the arguments list, ap, which will point to the first argument on the list after execution of this macro. The unusual parameter, paramN, is the parameter just to the left (in the C function declaration) of the parameters that should go into the va_list. Once va_start() has been executed, a call to va_aeg() will be evaluated as a quantity of type type form ap. The va_list will be updated as appropriate. The va_end() macro closes up the va_list. EXEMPLE Part of printf() might look like this: #include <stdarg.h> int printf(char *format) { va_list ap; int i,count=0; double d; va_start(ap,format) ;/* init the arg list after the argument format*/ while(*format){ if (*format!='%') putchar(*format++) else { ++format; switch(*format) { case 'd': i=va_arg(ap,int); /* get an int */ ... break; case 'f': d=va_arg(ap,double); /*get a double ... break; ... } } } va_end(ap); return count; } ****************************************************************************** file: [15]1:/user/francois/notes/use-c.txt author: Francois Turi date: 16 jully 1993 Librairie en C -------------- Langage C: help cc .instruction c specifique: help cc run_time .ecriture du c (syntaxe des boucles, etc..) : help cc language_topics (h cc la) .fonctions de librairie C: help cc run-time_functions (h cc ru) Une librairie en C se distingue par le fait qu'il n'y a pas de fonction main La librairie s'ecrit comme n'importe qu'elle prog ex: fichier ma_librairie.c ========================= #include "necessaire.h" int mon_entier_global void ma_fonction() { ... ... } Mais il sera necessaire pour utiliser cette librairie de creer un .h fichier ma_librairie.h ========================== extern int mon_entier_global; extern void ma_fonction(); Le programme appelant effectue la declaration seule: fichier programme_appelant.c #include "ma_librairie.h" main() { ma_fonction(); printf("valeur globale: %d",mon_entier_global); } LA LIBRAIRIE C STANDARD ======================= Syntaxe for(initialisation ; test ; incrementation) {} for(initialisation ; test ; incrementation) instruction; ex: for(i=1; i<10;i++) printf("\n %d",i); /* Attention au ; */ -------------------- while (expression_vrai) {} -------------------- do {} while (expression_vrai) /* Tourne tant que c'est VRAI !! */ -------------------- switch (expression) /* cte1 cte2 sont des constantes */ { case cte1: tatata; tototo ; break; case cte2: tatata; tototo ; break; default : nununu; } -------------------- if (expression) instruction; else instruction; if (expression) {} else {} -------------------- /* Pas de THEN */ Operateur Symbole Prior/Assoc Remarques ______________________________________________________________________________ Les operateurs d'affectation et de d'acces: appel de fonction () 15 <<= !!!Aucun ordre pour evaluer arguments. indexation [] 15 <<= champs de structure -> . 15 <<= incrementation ++ 14 --> decrementation -- 14 --> moins unaire - 14 --> adresse & 14 --> indirection * 14 --> taille sizeof 14 --> affectation = += -= *= 2 <-- Pas d'ordre entre /= %= &= != affecte et affectant >>= <<= ______________________________________________________________________________ Les operateurs logiques: negation logique ! 14 --> relation arithmetique < <= => > 10 --> (in)egalite == != 9 --> conjonction logique && 5 --> Evalue G puis D si disjonction logique || 4 --> necessaire expression cond. (test)?(exp_true):(exp_false) 3 --> ______________________________________________________________________________ Les operateurs aritmetiques: regles de conversion short int ---> int char ---> int float ---> double coercision "castle" (<type>) 14 --> multiplication * 13 --> division / 13 --> modulo % 13 --> addition + 12 --> soustraction - 12 --> expression compose , 1 --> ______________________________________________________________________________ Les operateurs binaires: negation bit a bit ~ 14 --> decalage >> << 11 --> et bit a bit & 8 --> ou exclusif bit a bit ^ 7 --> ou inclusif bit a bit | 6 --> ------------------------------------------------------------------------------ <<= 15 <primaire> ::= indexation[] appel_fn() .champ ->champ <<= 14 <valeur> ::= ++ -- - & * ! ~ sizeof (conversion) {primaire} -> 13 nombre1 ::= {valeur} * / {valeur} -> 12 NOMBRE ::= {nombre1} + - {nombre1} -> 11 shift ::= {NOMBRE} >> << {NOMBRE} -> 10 ordre ::= {shift} < <= => > {shift} -> 9 egalite ::= {ordre} == != {ordre} -> 8 binary1 ::= {egalite} & {egalite} -> 7 binary2 ::= {binary1} ^ {binary1} -> 6 BINARY ::= {binary2} | {binary2} -> 5 logique1 ::= {BINARY} && {BINARY} -> 4 LOGIQUE ::= {logique1} || {logique1} -> 3 expression ::= {LOGIQUE} ? {LOGIQUE} : {LOGIQUE} <== 2 affectation ::= {expression} = ..= {expression} -> 1 compose ::= {affectation} , {affectation} ****************************************************************************** file n_C.htm fin