'>

langage de programmation C

En informatique, C (/ si ː /, comme dans la lettre C) est un langage de programmation généraliste initialement développé par Dennis Ritchie entre 1969 et 1973 chez AT & T Bell Labs. [3] Comme la plupart des langues impératives dans la tradition ALGOL, C a installations pour la programmation structurée et permet lexical portée et la récursivité variables, tandis qu'un système de type statique empêche de nombreuses opérations non désirées. Sa conception permet des constructions qui correspondent efficacement aux instructions de la machine typiques, et par conséquent, il a trouvé une utilisation durable dans les applications qui avaient jadis été codés en langage assembleur, notamment un logiciel de système comme le système d'exploitation informatique Unix. [4]

C est un des langages de programmation les plus utilisés de tous les temps [5], [6] et compilateurs C sont disponibles pour la majorité des architectures informatiques disponibles et systèmes d'exploitation.

Beaucoup de langues plus tard, ont emprunté directement ou indirectement de C, notamment C #, D, Go, Rust, Java, JavaScript, Limbo, LPC, Perl, PHP, Python et C shell Unix. L'influence la plus profonde sur ces langues (hors Python) a été syntaxique, et ils ont tendance à combiner l'expression reconnaissable et syntaxe de l'instruction de C avec les systèmes sous-jacents de type, les modèles de données et la sémantique qui peut être radicalement différente. C + + qui a commencé comme un préprocesseur C et est actuellement près d'un sur-ensemble du C [7]

Avant il y avait une norme officielle pour C, de nombreux utilisateurs et développeurs fondant sur une spécification informelle contenue dans un livre écrit par Dennis Ritchie et Brian Kernighan, cette version est généralement appelée "K & R" C. En 1989, l'American National Standards Institute a publié un standard C (généralement appelé "ANSI C" ou "C89"). L'année suivante, le même cahier des charges a été approuvé par l'Organisation internationale de normalisation comme norme internationale (généralement appelé "C90"). ISO libéré une extension du support de l'internationalisation de la norme en 1995, et une norme révisée (connu sous le nom "C99") en 1999. La version actuelle de la norme (maintenant connu comme "C11") a été approuvé en Décembre 2011. [

Conception

C est un langage impératif (procédurale). Il a été conçu pour être compilé en utilisant un compilateur relativement simple, pour fournir un accès de bas niveau à la mémoire, à fournir des éléments de langage qui correspondent efficacement aux instructions de la machine, et d'exiger un minimum de soutien à l'exécution. C est donc utile pour de nombreuses applications qui avaient autrefois été codées en langage d'assemblage, comme dans la programmation du système.

En dépit de ses capacités de bas niveau, le langage a été conçu pour encourager la programmation multi-plateforme. Un programme C conforme aux normes et portably écrit peut être compilé pour une très grande variété de plates-formes informatiques et de systèmes d'exploitation avec quelques modifications à son code source. Le langage est devenu disponible sur une très large gamme de plates-formes, à partir de microcontrôleurs embarqués aux superordinateurs.
Caractéristiques

Comme la plupart des langues impératives dans la tradition ALGOL, C dispose d'installations pour la programmation structurée et permet lexical portée et la récursivité variables, tandis qu'un système de type statique empêche de nombreuses opérations non désirées. En C, tout le code exécutable est contenu dans les sous-programmes, qui sont appelés «fonctions» (mais pas au sens strict de la programmation fonctionnelle). Les paramètres de fonction sont toujours passés par valeur. Passage par référence est simulé dans C en passant explicitement les valeurs de pointeur. Texte source du programme C est en format libre, en utilisant la virgule comme une déclaration de terminaison et des accolades pour regrouper les blocs d'instructions.

Le langage C présente également les caractéristiques suivantes:

    Il ya un petit nombre fixe de mots-clés, y compris un ensemble complet de flux de primitives de contrôle: pour, if / else, while, switch, et faire / temps. Il ya un espace de noms et les noms définis par l'utilisateur ne se distinguent pas de mots-clés par toute sorte de sceau.
    Il existe un grand nombre d'opérateurs arithmétiques et logiques, tels que +, + =, + +, et, ~, etc
    Plus d'une affectation peut être effectuée en une seule déclaration.
    les valeurs de retour de fonction peuvent être ignorés lorsqu'ils ne sont pas nécessaires.
    Typage est statique, mais faiblement appliquées: toutes les données a un type, mais les conversions implicites peut être effectuée, par exemple, les caractères peuvent être utilisés comme des entiers.
    Syntaxe de déclaration imite contexte d'utilisation. C n'a pas de mot «définir», mais plutôt une déclaration à commencer par le nom d'un type est considérée comme une déclaration. Il n'ya pas de "fonction" mot-clé, mais plutôt une fonction est indiqué par les parenthèses d'une liste d'arguments.
    Définis par l'utilisateur (typedef) et les types de composés sont possibles.
        Les types de données agrégées hétérogènes (struct) permettre aux éléments de données associés à être accessibles et attribuées comme une unité.
        indexation de tableau est une notion secondaire, défini en termes d'arithmétique de pointeur. Contrairement aux structures, tableaux ne sont pas des objets de première classe, ils ne peuvent être ni cédés ni comparées à l'aide des opérateurs intégrés simples. Il n'ya pas de mot-clé "du tableau", en cours d'utilisation ou de la définition, mais plutôt, les crochets indiquent les tableaux syntaxiquement, par exemple, mois [11].
        Les types énumérés sont possibles avec le mot-clé enum. Ils ne sont pas marqués et sont librement interconvertibles avec des nombres entiers.
        Chaînes ne sont pas un type de données distinct, mais sont classiquement mis en œuvre sous forme de tableaux à zéro terminal de caractères.
    Accès de bas niveau à la mémoire de l'ordinateur est possible en convertissant les adresses de la machine à pointeurs typés.
    Les procédures (sous-programmes qui ne retournent pas les valeurs) sont un cas particulier de la fonction, avec un type de retour vide non typée.
    Les fonctions peuvent pas être définies dans la portée lexicale d'autres fonctions.
    Fonction et données pointeurs permettent hoc run-time polymorphisme annonce.
    Un préprocesseur effectue définition macro, fichier du code source de l'inclusion et la compilation conditionnelle.
    Il ya une forme de base de la modularité: les fichiers peuvent être compilés séparément et reliés entre eux, avec contrôle sur les fonctions et objets de données sont visibles à d'autres fichiers via les attributs statiques et externe.
    Fonctionnalités complexes telles que I / O, la manipulation de chaînes, et des fonctions mathématiques sont systématiquement déléguée aux routines de la bibliothèque.

C n'inclut pas certaines fonctionnalités présentes dans les nouvelles, langages de haut niveau les plus modernes, y compris l'orientation objet et la collecte des ordures.
Histoire
Les premiers développements
Ken Thompson et Dennis Ritchie, les développeurs du langage de programmation C.

Le développement initial de C s'est produit à AT & T Bell Labs entre 1969 et 1973 [2]; selon Ritchie, la période la plus créative a eu lieu en 1972. Il a été nommé "C" parce que ses caractéristiques ont été obtenues à partir d'un langage plus tôt appelé "B", qui, selon Ken Thompson était une version allégée du langage de programmation BCPL. [9]

L'origine de C est étroitement liée au développement du système d'exploitation Unix, à l'origine mis en place en langage d'assemblage sur un PDP-7 par Ritchie et Thompson, intégrant plusieurs idées de ses collègues. Finalement, ils ont décidé de porter le système d'exploitation sur un PDP-11. L'incapacité de B pour tirer parti de certaines des caractéristiques du PDP-11, adressage notamment octet, a conduit à l'élaboration d'une première version de C.

La version originale PDP-11 du système Unix a été développé en langage assembleur. En 1973, avec l'ajout des types de structure, le langage C était devenu assez que la plupart du noyau Unix a été réécrit en C. puissant Ce fut l'un des premiers noyaux de systèmes d'exploitation mis en œuvre dans une langue autre que l'assemblage. (Instances antérieures incluent le système Multics (écrit en PL / I), et MCP (Master Control Program) pour le Burroughs B5000 écrit en Algol en 1961.) Vers 1977, d'autres modifications à la langue ont été faites par Ritchie et Stephen C. Johnson pour faciliter la portabilité du système d'exploitation UNIX. C Compiler Portable Johnson a servi comme base pour plusieurs implémentations de C sur de nouvelles plates-formes [10].
K & R C

En 1978, Brian Kernighan et Dennis Ritchie a publié la première édition de The C Programming Language. [11] Ce livre, connu pour les programmeurs C comme "K & R", a servi pendant de nombreuses années comme une spécification informelle de la langue. La version de C qu'il décrit est communément appelé K & R C. La deuxième édition de l'ouvrage [12] couvre la norme ANSI C plus tard.

K & R a introduit plusieurs fonctionnalités de langage:

    bibliothèque standard I / O
    type de données long int
    unsigned type de données int
    opérateurs d'affectation composés de la forme = op (comme = -) ont été modifiés pour la forme op = de lever l'ambiguïté sémantique créé par des concepts comme i = -10, qui avait été interprété comme i = - 10 (décrémenter i par 10 ) au lieu de la peut-être destiné i = -10 (soit i -10)

Même après la publication de la norme C de 1989, pendant de nombreuses années K & R C était encore considéré comme le "plus petit dénominateur commun» à laquelle les programmeurs C se sont limités quand une portabilité maximale était souhaitée, car de nombreux compilateurs plus étaient encore en usage, et parce que soigneusement écrit K & R code C peut être la norme juridique C ainsi.

Dans les premières versions de C, seules les fonctions qui ont renvoyé une valeur non-int devait être déclarée si elle est utilisée avant la définition de fonction, une fonction utilisée sans déclaration précédente était supposé retourner type int, si sa valeur a été utilisée.

Par exemple:

longue some_function ();
/ * Int * / other_function ();

/ * Int * / calling_function ()
{
    longue test1;
    inscrire / * int * / test2;

    test1 = some_function ();
    si (test1> 0)
          test2 = 0;
    autre
          test2 = other_function ();
    retourner test2;
}

Les spécificateurs de type int qui sont commentés sur pouvaient être omis dans K & R C, mais sont tenus dans les normes suivantes.

Depuis les déclarations de fonctions K & R ne comprennent pas toutes les informations sur les arguments de fonction, le paramètre fonction vérifications de type n'ont pas été effectuées, bien que certains compilateurs ne délivre un message d'avertissement si une fonction locale a été appelée avec le mauvais nombre d'arguments, ou si plusieurs appels à une fonction externe utilisé des numéros ou types d'arguments différents. Outils distincts tels que l'utilité de la fibre de Unix qui ont été développés (entre autres choses) pourrait vérifier la cohérence de l'utilisation de la fonction sur plusieurs fichiers source.

Dans les années qui ont suivi la publication de K & R C, plusieurs caractéristiques non officielles ont été ajoutés à la langue, soutenu par les compilateurs d'AT & T et d'autres vendeurs. Il s'agit notamment:

    fonctions vides (c. fonctions sans valeur de retour)
    fonctions retournant struct ou types d'union (plutôt que des pointeurs)
    Affectation des types de données struct
    types énumérés

Le grand nombre d'extensions et de l'absence d'accord sur une bibliothèque standard, ainsi que la popularité de la langue et le fait que même les compilateurs Unix précisément mis en œuvre la spécification K & R, a conduit à la nécessité de la normalisation.
ANSI C et ISO C
Article détaillé: ANSI C

À la fin des années 1970 et 1980, les versions de C ont été mises en œuvre pour une grande variété d'ordinateurs centraux, mini-ordinateurs et micro-ordinateurs, y compris les PC IBM, que sa popularité a commencé à augmenter de manière significative.

En 1983, l'American National Standards Institute (ANSI) a formé un comité, X3J11, afin d'établir une spécification standard de C. X3J11 base de la norme C sur l'application Unix, mais la partie non portable de la bibliothèque Unix C a ensuite été transféré au groupe de travail IEEE 1003 à devenir la base de la norme POSIX 1988. En 1989, la norme a été ratifiée C ANSI X3.159-1989 "langage de programmation C". Cette version de la langue est souvent désigné comme ANSI C, C standard, ou parfois C89.

En 1990, la norme ANSI C (avec des modifications de mise en forme) a été adoptée par l'Organisation internationale de normalisation (ISO) ISO / IEC 9899:1990, qui est parfois appelé C90. Par conséquent, les termes "C89" et "C90" se réfèrent au même langage de programmation.

ANSI, comme d'autres organismes nationaux de normalisation, ne développe plus la norme C de façon indépendante, mais s'en remet à la norme internationale C, maintenue par le groupe de travail ISO / IEC JTC1/SC22/WG14. L'adoption nationale d'une mise à jour de la norme internationale se produit généralement dans l'année de publication de l'ISO.

L'un des objectifs du processus de normalisation C était de produire un sur-ensemble de K & R C, intégrant de nombreuses fonctionnalités non officielles introduites par la suite. Le comité des normes aussi plusieurs fonctionnalités supplémentaires telles que des prototypes de fonctions (emprunté à C + +), pointeurs void, le support pour les jeux et les lieux de caractères internationaux, et des améliorations préprocesseur. Bien que la syntaxe des déclarations de paramètres a été augmenté pour inclure le style utilisé dans C + +, l'interface K & R a continué à être autorisée, pour la compatibilité avec le code source existant.

C89 est pris en charge par les compilateurs C actuels, et la plupart du code C étant écrit aujourd'hui repose sur elle. Tout programme écrit seulement dans la norme C et sans aucune hypothèse dépendant du matériel fonctionnera correctement sur n'importe quelle plateforme avec une mise en œuvre conforme C, dans les limites des ressources. Sans ces précautions, les programmes peuvent compiler seulement sur une certaine plate-forme ou d'un compilateur particulier, en raison, par exemple, à l'utilisation des bibliothèques non standard, telles que les bibliothèques GUI, ou à une dépendance à l'égard du compilateur ou des attributs spécifiques à la plateforme tels comme la taille exacte des types de données et endianness d'octets.

Dans les cas où le code doit être compilable soit conforme au standard ou K & R compilateurs C-base, la macro STDC__ de __ peut être utilisé pour diviser le code en sections standard et K & R pour empêcher l'utilisation d'un compilateur C basé K & R de fonctionnalités disponibles uniquement dans standard C.
C99
Article détaillé: C99

Après le processus de normalisation ANSI / ISO, la spécification du langage C est restée relativement stable depuis plusieurs années. En 1995 Amendement normative 1 à la norme 1990, C (ISO / IEC 9899/AMD1: 1995, connu officieusement comme C95) a été publié pour corriger certains détails et d'ajouter un soutien plus large pour les jeux de caractères internationaux. Le standard C a été révisé à la fin des années 1990, conduisant à la publication de la norme ISO / IEC 9899:1999 en 1999, ce qui est communément appelé «C99». Il a depuis été modifiée à trois reprises par Rectificatifs techniques [13].

C99 introduit plusieurs nouvelles fonctionnalités, y compris les fonctions inline, plusieurs nouveaux types de données (y compris à long long int et un type complexe pour représenter des nombres complexes), les tableaux de longueur variable, un support amélioré pour IEEE 754 à virgule flottante, le soutien aux macros variadiques (macros de variables arité), et le soutien pour les commentaires d'une ligne commençant par / /, comme dans BCPL ou C + +. Beaucoup d'entre eux avaient déjà été mises en œuvre comme des extensions dans plusieurs compilateurs C.

C99 est en grande partie compatible avec C90, mais est plus stricte à certains égards, en particulier, une déclaration qui n'a pas de spécificateur de type n'a plus int implicitement supposé. Une norme macro __ STDC_VERSION__ est défini avec 199901L de valeur pour indiquer que support C99 est disponible. GCC, Solaris Studio et d'autres compilateurs C prennent désormais en charge de tout ou partie des nouvelles fonctionnalités de C99.
C11
Article détaillé: C11 (C révision standard)

En 2007, les travaux ont commencé sur une nouvelle révision de la norme C, officieusement appelé "C1X» jusqu'à sa publication officielle le 2011-12-08. Le comité de normalisation C a adopté des directives pour limiter l'adoption de nouvelles fonctionnalités qui n'ont pas été testés par les implémentations existantes.

La norme C11 ajoute de nombreuses nouvelles fonctionnalités à C et la bibliothèque, y compris les macros type générique, les structures anonymes, un meilleur support Unicode, les opérations atomiques, multi-threading, et par ses limites fonctions. Il rend également certaines parties de la bibliothèque existante C99 en option, et améliore la compatibilité avec C + +.
Embedded C
Article détaillé: Embedded C

Historiquement, la programmation C embarqué nécessite une extension non standard pour le langage C afin de soutenir fonctionnalités exotiques tels que l'arithmétique en virgule fixe, plusieurs banques de mémoire distincts, et les opérations de base d'E / S.

En 2008, le Comité de normalisation C publié un rapport technique l'extension du langage C [14] pour résoudre ces problèmes en fournissant une norme commune pour toutes les implémentations à respecter. Il comprend un certain nombre de fonctionnalités non disponibles dans des conditions normales C, comme l'arithmétique en virgule fixe, espaces d'adressage nommés et matériel d'E / S de base d'adressage.
Syntaxe
Article détaillé: syntaxe C

C a une grammaire formelle spécifié par la norme C [15]. Contrairement aux langages tels que FORTRAN 77, le code source C est de forme libre qui permet l'utilisation arbitraire des espaces pour code de format, plutôt que de restrictions colonne ou à base de texte basé sur la ligne . Les commentaires peuvent apparaître soit entre les délimiteurs / * et * / ou (depuis C99) après / / jusqu'à la fin de la ligne. Commentaires délimités par / * et * / ne nichent pas, et ces séquences de caractères ne sont pas interprétés comme des séparateurs de commentaires si elles apparaissent à l'intérieur de chaînes ou de caractères littéraux. [16]

Les fichiers source C contiennent des déclarations et des définitions de fonction. Les définitions de fonctions, à leur tour, contiennent des déclarations et des déclarations. Déclarations soit définir de nouveaux types utilisant des mots clés tels que struct, union et enum ou attribuer des types de stockage de réserve et peut-être de nouvelles variables, généralement en écrivant le type suivi par le nom de la variable. Mots clés tels que char et int spécifier les types intégrés. Des sections de code sont enfermés dans des accolades ({et}, parfois appelée «accolades») pour limiter la portée des déclarations et d'agir comme une seule déclaration pour les structures de contrôle.

Comme un langage impératif, C utilise des instructions pour spécifier les actions. La déclaration la plus commune est une déclaration d'expression, consistant en une expression à évaluer, suivis par un point-virgule, comme un effet secondaire de l'évaluation, les fonctions peuvent être appelées et les variables peuvent être attribuées de nouvelles valeurs. Pour modifier l'exécution séquentielle normale des états, C fournit plusieurs états de flux de contrôle identifiés par mots clés réservés. La programmation structurée est soutenu par si l'exécution (-else) conditionnel et par do-while, tandis que, et pour exécution itérative (boucle). L'instruction for a initialisation séparé, les tests et les expressions de réinitialisation, tout ou partie de ce qui peut être omis. break et continue peuvent être utilisés pour quitter le compte de boucle incluse ou sauter à sa réinitialisation. Il ya aussi une instruction goto non structurés qui branches directement à l'étiquette désignée au sein de la fonction. commutateur sélectionne un cas pour être exécuté sur la base de la valeur d'une expression entier.

Les expressions peuvent utiliser une variété d'opérateurs intégrés et peuvent contenir des appels de fonction. L'ordre dans lequel les arguments des fonctions et des opérandes à la plupart des opérateurs sont évalués n'est pas spécifié. Les évaluations peuvent même être imbriquées. Cependant, tous les effets secondaires (y compris le stockage des variables) se produisent avant le prochain "point de séquence"; points de séquence comprennent la fin de chaque instruction d'expression, et l'entrée et le retour de chaque appel de fonction. Les points de séquence se produisent également lors de l'évaluation des expressions contenant certains opérateurs (&&, | |,: Et l'opérateur virgule). Cela permet un degré élevé d'objet l'optimisation du code par le compilateur, mais nécessite programmeurs C à prendre davantage soin d'obtenir des résultats fiables que ce qui est nécessaire pour d'autres langages de programmation.

Kernighan et Ritchie dire dans l'introduction du langage de programmation C: "C, comme toute autre langue, a ses défauts Certains opérateurs ont une fausse priorité; certaines parties de la syntaxe pourrait être mieux.". [17] La ​​norme C ne pas tenter de corriger un grand nombre de ces imperfections, en raison de l'impact de ces changements sur les logiciels déjà existants.
Jeu de caractères

Le jeu de caractères source C de base comprend les caractères suivants:

    Lettres: de a à z, A-Z, _
    Chiffres: 0-9
    Ponctuation: ~! @ #% ^ & * () - + =:;.? "'<>, | / \ {} []
    Caractères blancs: l'espace, tabulation horizontale, tabulation verticale, de forme, de nouvelle ligne

Newline indique la fin d'une ligne de texte, il ne doit pas correspondre à un seul personnage réel, mais pour plus de commodité C traite comme un.

D'autres caractères codés à plusieurs octets peuvent être utilisés, mais ne sont pas portables. La dernière norme C (C11) permet caractères Unicode multinationales à être incorporés de façon portable dans le texte source C en utilisant un encodage uDDDD \ (où DDDD désigne un code de caractère Unicode), bien que cette fonctionnalité n'est pas encore largement appliquée.

Le jeu de caractères d'exécution C de base contient les mêmes personnages, avec des représentations concernant l'alerte, retour arrière, et un retour chariot. Support d'exécution pour les jeux de caractères étendus a augmenté avec chaque révision de la norme C.
Mots-clés

C89 dispose de 32 mots clés (mots réservés ayant une signification particulière):

    auto
    pause
    cas
    caractères
    const
    continuer
    défaut
    faire



    doubler
    autre
    ENUM
    externe
    flotter
    pour
    goto
    si



    int
    longtemps
    s'inscrire
    retour
    court
    signé
    sizeof
    statique



    struct
    commutateur
    typedef
    union
    unsigned
    annulera
    volatile
    pendant que

C99 ajoute cinq mots-clés:

    _Bool
    _Complex



    _Imaginary
    inline



    restreindre

C11 ajoute sept autres mots-clés: [18]

    _Alignas
    _Alignof



    _Atomic
    _Generic



    _Noreturn
    _Static_assert



    _Thread_local

La plupart des mots-clés ajoutés récemment commencent par un tiret suivi d'une lettre majuscule, parce que les identificateurs de cette forme ont déjà été réservés par la norme C pour une utilisation uniquement par les implémentations. Puisque le code source d'un programme existant n'aurait pas dû être utilise ces identifiants, il ne serait pas affectée lorsque les implémentations C a commencé à soutenir ces extensions du langage de programmation. Certains en-têtes standards ne définissent synonymes plus commodes pour les identifiants soulignée. Le langage utilisé pour inclure un mot clé réservé appelée entrée, mais cela n'a jamais été mis en œuvre et a été supprimée comme un mot réservé. [19]
Opérateurs
Article détaillé: Les opérateurs en C et C + +

C prend en charge un ensemble complet d'opérateurs, qui sont des symboles utilisés dans une expression pour spécifier les manipulations à effectuer tout en évaluant cette expression. C est pour les opérateurs:

    arithmétique: +, -, *, /,%
    affectation: =
    augmentée attribution: + =, - =, * =, / =,% =, & =, | =, ^ =, << =, >> =
    bit logique: ~, &, |, ^
    des changements au niveau du bit: <<, >>
    logique booléenne:, &&, | |
    évaluation conditionnelle:? :
    test d'égalité: ==, =
    fonctions d'appel: ()
    augmentation et de diminution: + +, -
    sélection des membres: ->.
    taille de l'objet: sizeof
    relations d'ordre: <, <=,>,> =
    référence et déréférence: &, *, []
    séquençage:,
    subexpression groupement: ()
    Type de conversion: (typename)

C utilise l'opérateur =, réservée en mathématiques pour exprimer l'égalité, pour indiquer l'affectation, après le précédent de Fortran et PL / I, mais contrairement à Algol et de ses dérivés. La similitude entre l'opérateur de C pour l'affectation et pour l'égalité (==) a été critiquée comme il est facile de remplacer accidentellement un pour l'autre. Dans de nombreux cas, chacun peut être utilisé dans le contexte de l'autre sans une erreur de compilation (bien que certains compilateurs produisent des avertissements). Par exemple, l'expression conditionnelle dans le cas (a = b +1) est vraie si A n'est pas zéro après la cession [20] En outre, la priorité des opérateurs de C est non-intuitive, comme == lien plus fort que & et. | dans des expressions comme x & 1 == 0, ce qui aurait besoin d'être écrit (x & 1) == 0 pour être correctement évaluée. [21]
"Bonjour tout le monde" exemple

Le "bonjour tout le monde", par exemple, qui est apparu dans la première édition de K & R, est devenu le modèle pour un programme d'introduction dans la plupart des manuels de programmation, quel que soit le langage de programmation. Le programme affiche "bonjour tout le monde" sur la sortie standard, qui est habituellement un terminal ou un écran.

La version originale était: [22]

main ()
{
    printf ("Bonjour, monde \ n");
}

Un "bonjour tout le monde" programme conforme au standard est: [nb 1]

# Include <stdio.h>

int main (void)
{
    printf ("Bonjour, monde \ n");
}

La première ligne du programme contient une directive de prétraitement, indiqué par # include. Cela provoque le compilateur de remplacer cette ligne avec l'ensemble du texte de l'en-tête standard stdio.h, qui contient des déclarations pour l'entrée standard et des fonctions de sortie comme printf. Les crochets entourant stdio.h indiquent que stdio.h est situé à l'aide d'une stratégie de recherche qui préfère têtes standard à d'autres en-têtes portant le même nom. (Les guillemets sont utilisés pour inclure des fichiers d'en-tête local ou un projet particulier.)

La ligne suivante indique qu'une fonction nommée principale est définie. La fonction principale sert un but précis dans les programmes C, l'environnement d'exécution appelle la fonction principale pour commencer l'exécution du programme. Le spécificateur de type int indique que la valeur qui est retournée à l'invocateur (dans ce cas, l'environnement d'exécution) à la suite de l'évaluation de la fonction principale, est un entier. Le mot-clé vide comme une liste de paramètres indique que cette fonction ne prend aucun argument. [Nb 2]

L'accolade ouvrante indique le début de la définition de la fonction principale.

Les appels de ligne suivante (détourne exécution à) une fonction nommée printf, qui est alimenté à partir d'une bibliothèque système. Dans cet appel, la fonction printf est passé (fourni avec) un seul argument, l'adresse du premier caractère de la chaîne "bonjour, world \ n". La chaîne littérale est un tableau anonyme avec des éléments de type char, mis en place automatiquement par le compilateur avec une finale caractère 0-évalué pour marquer la fin du tableau (besoins printf le sachent). Le \ n est une séquence d'échappement qui se traduit par un C saut de ligne, dont la sortie indique la fin de la ligne courante. La valeur de retour de la fonction printf est de type int, mais il est éliminé en silence, car il n'est pas utilisé. (Un programme plus prudent pourrait tester la valeur de retour pour déterminer si oui ou non la fonction printf réussi.) Le point-virgule; termine le communiqué.

L'accolade fermante indique la fin du code de la fonction principale. Conformément à la spécification C99 et plus récents, principal implicitement retourner un état 0 en atteignant le} qui met fin à la fonction. Ceci est interprété par le système d'exécution comme un code de sortie indiquant une exécution réussie. [23]
Les types de données

C a un faible système de type typage statique qui partage quelques similitudes avec celle des autres descendants ALGOL comme Pascal. Il ya des haut-types pour les entiers de différentes tailles, à la fois signés et non signés, des nombres à virgule flottante, les caractères et les types énumérés (enum). C99 a ajouté un type booléen. Il ya aussi des types dérivés y compris les tableaux, pointeurs, les dossiers (struct), et les syndicats non marquées (syndicat).

C est souvent utilisé dans les systèmes à faible niveau de programmation où s'échappe du système de type peuvent être nécessaires. Le compilateur tente de veiller à ce type de correction de la plupart des expressions, mais le programmeur peut passer outre les contrôles de différentes façons, soit en utilisant un type CAST pour convertir explicitement une valeur d'un type à un autre, ou en utilisant des pointeurs ou des syndicats de réinterpréter les bits sous-jacents d'un objet de données d'une autre manière.

Certains trouvent déclaration syntaxe de la intuitif de C, en particulier pour les pointeurs de fonctions. (L'idée de Ritchie était de déclarer des identificateurs dans des contextes ressemblant à leur utilisation: "déclaration reflète l'utilisation"). [24]

Conversions arithmétiques habituelles de C permettent de code efficace doit être généré, mais peuvent parfois produire des résultats inattendus. Par exemple, une comparaison d'entiers signés et non signés de largeur égale nécessite une conversion de la valeur signée en unsigned. Cela peut générer des résultats inattendus si la valeur signée est négatif.
Pointeurs

C prend en charge l'utilisation de pointeurs, un type de référence qui enregistre l'adresse ou l'emplacement d'un objet ou une fonction en mémoire. Les pointeurs peuvent être déréférencés pour accéder aux données stockées à l'adresse pointée, ou d'invoquer une fonction pointu à. Les pointeurs peuvent être manipulées en utilisant la cession ou l'arithmétique des pointeurs. La représentation de l'exécution d'une valeur de pointeur est généralement une adresse mémoire brute (qui peut être améliorée par un champ de décalage-dans-mot), mais depuis un type de pointeur comprend le type de la chose pointé, expressions, y compris des pointeurs peut être typé au moment de la compilation. arithmétique de pointeur est automatiquement mis à l'échelle par la taille du type de données à pointes. Les pointeurs sont utilisés à de nombreuses fins différentes en C. Les chaînes de texte sont souvent manipulés en utilisant des pointeurs dans des tableaux de caractères. L'allocation dynamique de la mémoire est effectuée en utilisant les pointeurs. De nombreux types de données, tels que les arbres, sont couramment mises en œuvre sous forme d'objets struct alloués dynamiquement reliés entre eux utilisant des pointeurs. Pointeurs de fonctions sont utiles pour passer des fonctions comme arguments de fonctions d'ordre supérieur (comme qsort ou bsearch) ou en tant que rappels à être invoqués par les gestionnaires d'événements. [23]

Une valeur de pointeur nul indique explicitement à aucun emplacement valide. Déréférencer une valeur de pointeur nul est undefined, ce qui entraîne souvent une erreur de segmentation. Valeurs de pointeur NULL sont utiles pour indiquer des cas particuliers comme l'absence de pointeur "suivant" dans le noeud final d'une liste chaînée, ou comme une indication d'erreur de fonction retournant un pointeur. Dans des contextes appropriés dans le code source, comme l'assignation d'une variable pointeur, une constante pointeur NULL peut être écrite comme 0, avec ou sans conversion explicite à un type de pointeur, ou comme la macro NULL défini par plusieurs têtes standard. Dans des contextes conditionnels, les valeurs de pointeur NULL renvoient false, alors que toutes les autres valeurs de pointeur la valeur true.

pointeurs (void *) Point d'objets de type non précisé, et peuvent donc être utilisés comme pointeurs de données «génériques». Comme la taille et le type de l'objet pointu pour on ne sait pas, pointeurs void ne peuvent pas être déréférencés, pas plus que l'arithmétique des pointeurs sur leur permis, mais ils peuvent facilement être (et dans de nombreux contextes implicitement sont) converties et de tout autre pointeur d'objet Type [23].

Utilisation négligente de pointeurs est potentiellement dangereuse. Parce qu'ils sont généralement pas cochée, une variable pointeur peut être faite pour pointer vers un emplacement arbitraire, ce qui peut entraîner des effets indésirables. Bien que correctement utilisé pointeurs pointent vers des endroits sûrs, ils peuvent être faits pour pointer vers des endroits dangereux en utilisant l'arithmétique de pointeur non valide, les objets qu'ils pointent vers peut être libérée et réutilisé (ballants pointeurs), ils peuvent être utilisés sans avoir été initialisé (pointeurs sauvages ), ou ils peuvent être affectés directement une valeur à risque en utilisant un plâtre, syndicat, ou par un autre pointeur corrompu. En général, C est permissive en permettant la manipulation de conversion et entre types de pointeurs, mais les compilateurs fournissent généralement des options pour les différents niveaux de vérification. Certains autres langages de programmation résoudre ces problèmes en utilisant des types de référence plus restrictives.
Arrays

Les types de tableaux en C sont traditionnellement de taille fixe, statique spécifié au moment de la compilation. (La plus récente norme C99 permet aussi une forme de tableaux de longueur variable). Cependant, il est également possible d'allouer un bloc de mémoire (de taille arbitraire) au moment de l'exécution, en utilisant la fonction malloc de la bibliothèque standard, et le traiter comme un tableau. L'unification de C de tableaux et les pointeurs signifie que déclarées tableaux et ces tableaux simulés dynamiquement alloués sont pratiquement interchangeables.

Comme les tableaux sont toujours accessibles (en effet) via des pointeurs, accès aux tableaux ne sont généralement pas vérifiés contre la taille du tableau sous-jacent, même si certains compilateurs peuvent prévoir la vérification des limites en option [25]. Géant RAID violations sont donc possibles et assez commun dans désinvolture code, et peut conduire à diverses répercussions, y compris les accès illégaux de mémoire, la corruption de données, les dépassements de mémoire tampon, et les exceptions d'exécution. Si la vérification des limites est souhaitée, elle doit être faite manuellement.

C n'a pas de disposition particulière concernant la déclaration des tableaux multidimensionnels, mais s'appuie plutôt sur la récursivité dans le système de type de déclarer des tableaux de tableaux, qui accomplit effectivement la même chose. Les valeurs de l'indice de la "tableau multidimensionnel» qui en résulte peuvent être considérés comme de plus en plus l'ordre des lignes.

Les tableaux multidimensionnels sont couramment utilisés dans les algorithmes numériques (principalement de l'algèbre linéaire appliquée) pour stocker les matrices. La structure de la matrice C est bien adapté à cette tâche particulière. Cependant, puisque les tableaux sont passés comme de simples indications, les limites du tableau doivent être connus des valeurs fixes ou bien explicitement transmises à des sous-programme qui leur impose, et des tableaux de taille dynamique de tableaux ne sont pas accessibles en utilisant le double indexation. (Une solution pour cela est d'allouer le tableau avec un "vecteur ligne» supplémentaire de pointeurs vers les colonnes.)

C99 introduit "tableaux de longueur variable» qui traitent de certains, mais pas tous, des problèmes avec des tableaux C ordinaires.
Voir aussi: C string
Interchangeabilité Array-pointeur

La notation indice x [i] (où x désigne un pointeur) est un sucre syntaxique pour * (x + i). [26] Profitant de la connaissance du compilateur de type pointeur, l'adresse que x + i points n'est pas l'adresse de base (pointée par x) incrémenté par i octets, mais est plutôt définie comme étant l'adresse de base augmentée de i multiplié par la taille d'un élément x de points à.

En outre, dans la plupart des contextes d'expression (une exception notable est comme opérateur de sizeof), le nom d'un tableau est automatiquement converti en un pointeur vers premier élément du tableau; donc pour un tableau déclaré avec le nom A, A [i] désigne l' i +1 ième élément de la matrice. Cela suppose également qu'un tableau n'est jamais copié dans son ensemble lorsqu'il a été nommé un argument à une fonction, mais uniquement l'adresse de son premier élément est passé. Par conséquent, bien que les appels de fonction en C utilisent la sémantique de passage par valeur, les tableaux sont en effet passés par référence.

La taille d'un élément peut être déterminé en appliquant le sizeof opérateur à n'importe quel élément déréférencé de x, comme dans n = sizeof * x ou n = sizeof x [0], et le nombre d'éléments dans un tableau déclaré A peut être déterminée comme sizeof A / sizeof A [0]. Ce dernier s'applique uniquement aux noms de tableau: les variables déclarées avec des indices (int A [20]). En raison de la sémantique de C, il n'est pas possible de déterminer la taille totale de tableaux par des pointeurs vers des tableaux ou ceux créés par l'allocation dynamique (malloc); code tel que sizeof arr / sizeof arr [0] (où arr = A désigne un pointeur) ne fonctionnera pas car le compilateur suppose la taille du pointeur lui-même est demandée. [27] [28] Comme le nom arguments de tableau à sizeof ne sont pas converties en des pointeurs, ils ne présentent pas une telle ambiguïté. Cependant, les tableaux créés par allocation dynamique sont initialisés à des pointeurs plutôt que des variables d'ensemble vrais, ils souffrent des mêmes problèmes de sizeof que pointeurs de tableaux.

Ainsi, malgré cette apparente équivalence entre tableau et variables de pointeur, il ya toujours une distinction doit être faite entre eux. Même si le nom d'un tableau est, dans la plupart des contextes d'expression, converti en un pointeur (pour son premier élément), ce pointeur ne pas s'occuper tout stockage, le nom du tableau n'est pas une lvalue, et son adresse est une constante, contrairement à une variable de pointeur. Par conséquent, ce que un tableau "pointe vers" ne peuvent pas être changés, et il est impossible d'attribuer une nouvelle adresse pour un nom de tableau. contenu du tableau peut être copié, toutefois, en utilisant la fonction memcpy, ou en accédant aux éléments individuels.
la gestion de la mémoire

Une des fonctions les plus importantes d'un langage de programmation est de fournir des installations de gestion de la mémoire et les objets qui sont stockés dans la mémoire. C fournit trois façons distinctes pour allouer de la mémoire pour les objets [23]:

    Static allocation de mémoire: l'espace de l'objet est fourni dans le binaire au moment de la compilation, ces objets ont une étendue (ou la vie) aussi longtemps que le binaire qui contient les est chargé en mémoire.
    Automatique allocation de mémoire: objets temporaires peuvent être stockés sur la pile, et cet espace est automatiquement libéré et réutilisable après le bloc dans lequel elles sont déclarées est sorti.
    Allocation dynamique de la mémoire: des blocs de mémoire de taille arbitraire peut être demandé lors de l'exécution à l'aide des fonctions de bibliothèque comme malloc d'une région de mémoire appelé le tas; ces blocs persistent jusqu'à ce que par la suite libéré pour une réutilisation en appelant la fonction realloc de la bibliothèque ou libre

Ces trois approches sont appropriés dans des situations différentes et ont différents compromis. Par exemple, l'allocation de mémoire statique a peu de frais généraux d'allocation, l'allocation automatique peut impliquer un peu plus les frais généraux, et l'allocation dynamique de mémoire peut potentiellement avoir beaucoup de frais généraux pour les allocation et la libération. La persistance des objets statiques est utile pour maintenir des informations d'état à travers les appels de fonction, affectation automatique est facile à utiliser, mais l'espace de pile est généralement beaucoup plus limitée et transitoire que soit la mémoire statique ou espace de tas, et l'allocation dynamique de la mémoire permet une allocation pratique des objets dont taille n'est connu qu'au moment de l'exécution. La plupart des programmes C font un usage intensif des trois.

Lorsque cela est possible, l'allocation automatique ou statique est généralement plus simple parce que le stockage est géré par le compilateur, ce qui libère le programmeur de la corvée potentiellement sujette aux erreurs d'allocation et de libération manuellement stockage. Cependant, de nombreuses structures de données peuvent changer de taille à l'exécution, et depuis allocations statiques (et allocations automatiques avant C99) doivent avoir une taille fixe au moment de la compilation, il ya beaucoup de situations dans lesquelles l'allocation dynamique est nécessaire. [23] Avant l' C99 standards tableaux, de taille variable sont un exemple courant de cela. (Voir l'article sur malloc pour un exemple de tableaux alloués dynamiquement.) Contrairement à l'attribution automatique, qui peut échouer au moment de courir avec des conséquences incontrôlées, les fonctions d'allocation dynamique renvoient une indication (sous la forme d'une valeur de pointeur null) lorsque le stockage nécessaire ne peut être alloué. (Allocation statique qui est trop grand est habituellement détectée par le linker ou chargeur, avant que le programme ne puisse commencer l'exécution.)

Sauf indication contraire, les objets statiques contiennent des valeurs de pointeur nul ou nul lors du démarrage du programme. Objets automatiquement et dynamiquement allouées sont initialisées que si une valeur initiale est explicitement spécifié, sinon qu'ils ont initialement valeurs indéterminées (en général, quel que soit bit modèle arrive à être présent dans la mémoire, ce qui pourrait ne pas représenter encore une valeur valide pour ce type). Si le programme tente d'accéder à une valeur non initialisée, les résultats sont indéfinis. Beaucoup de compilateurs modernes tentent de détecter et avertir de ce problème, mais les deux faux positifs et des faux négatifs peuvent se produire.

Un autre problème est que l'allocation de mémoire de tas doit être synchronisé avec son utilisation réelle dans tout programme afin qu'il soit réutilisé autant que possible. Par exemple, si le seul pointeur vers une allocation de mémoire du tas est hors de portée ou a sa valeur écrasé avant de free () est appelée, alors que la mémoire ne peut pas être récupéré pour être réutilisé plus tard et est essentiellement perdu au programme, un phénomène connu sous le nom fuite de mémoire. Inversement, il est possible que la mémoire soit libéré, mais continuent à être référencés, ce qui conduit à des résultats imprévisibles. Généralement, les symptômes apparaissent dans une partie du programme éloignée de l'erreur réelle, ce qui rend difficile à traquer le problème. (Ces questions sont améliorés dans les langues avec la collecte des ordures automatique.)
Bibliothèques

Le langage de programmation C utilise des bibliothèques comme sa principale méthode d'extension. En C, une bibliothèque est un ensemble de fonctions contenues dans un seul fichier "archive". Chaque bibliothèque a généralement un fichier d'en-tête, qui contient les prototypes des fonctions contenues dans la bibliothèque qui peut être utilisée par un programme, et les déclarations de types de données spéciaux et des symboles macro utilisés avec ces fonctions. Pour qu'un programme d'utiliser une bibliothèque, il faut inclure le fichier d'en-tête de la bibliothèque et la bibliothèque doit être liée à ce programme, qui dans de nombreux cas nécessite des drapeaux de compilation (par exemple,-lm, raccourci pour "bibliothèque mathématique»). [ 23]

La bibliothèque la plus courante C est la bibliothèque standard C, qui est spécifié par la norme ANSI C et ISO et est livré avec toutes les implémentations C. (Implémentations qui ciblent les environnements limités tels que les systèmes embarqués peuvent fournir seulement un sous-ensemble de la bibliothèque standard.) Cette librairie supporte entrée de flux et de sortie, l'allocation de mémoire, les mathématiques, les chaînes de caractères, et les valeurs de temps. Plusieurs têtes standard distinctes (par exemple, stdio.h) précisent les interfaces pour ces derniers et d'autres installations de la bibliothèque standard.

Un autre ensemble commun de fonctions C bibliothèque sont ceux utilisés par les applications ciblées pour les systèmes Unix et Unix-like, en particulier les fonctions qui fournissent une interface avec le noyau. Ces fonctions sont détaillées dans différentes normes telles que POSIX et le Single UNIX Specification.

Depuis de nombreux programmes ont été écrits en C, il existe une grande variété d'autres bibliothèques disponibles. Les bibliothèques sont souvent écrites en C parce que les compilateurs C générer du code objet efficace; programmeurs puis créer des interfaces à la bibliothèque afin que les routines peuvent être utilisés à partir de langages de haut niveau comme Java, Perl et Python [23].
Outils linguistiques

Des outils ont été créés pour aider les programmeurs C éviter certains des problèmes inhérents à la langue, telles que les déclarations comportement indéfini ou des déclarations qui ne sont pas une bonne pratique, car ils sont susceptibles d'entraîner un comportement inattendu ou des erreurs d'exécution.

Automated source de vérification de code et d'audit sont bénéfiques dans n'importe quelle langue, et C existent beaucoup de ces outils, comme une peluche. Une pratique courante consiste à utiliser Lint pour détecter le code discutable quand un programme est d'abord écrit. Une fois le programme passe à Lint, il est ensuite compilé en utilisant le compilateur C. Aussi, de nombreux compilateurs pouvant éventuellement mettre en garde contre des constructions syntaxiquement valides qui sont susceptibles d'être en fait des erreurs. MISRA C est un ensemble exclusif de directives pour éviter un tel code discutable, développés pour les systèmes embarqués.

Il existe également des compilateurs, les bibliothèques et les mécanismes au niveau du système d'exploitation pour effectuer des actions qui ne sont pas un élément standard de C, comme la vérification des limites tableau, la détection de dépassement de tampon, la sérialisation et la collecte des ordures automatique.

Des outils tels que Purify ou Valgrind et la liaison avec les bibliothèques contenant des versions spéciales des fonctions d'allocation de mémoire peuvent aider à découvrir les erreurs d'exécution dans la mémoire.
Utilise
C est souvent utilisé pour "la programmation du système", y compris la mise en œuvre des systèmes d'exploitation et applications de systèmes embarqués, en raison d'une combinaison de caractéristiques souhaitables telles que la portabilité du code et de l'efficacité, la capacité d'accéder aux adresses matérielles spécifiques, la capacité de calembour types pour correspondre à l'accès aux données imposée de l'extérieur exigences, et la faible demande d'exécution sur les ressources système. C peut également être utilisé pour la programmation de sites Web utilisant CGI comme une «passerelle» pour des informations entre l'application Web, le serveur et le navigateur. [29] Quelques raisons pour choisir C sur les langages interprétés sont sa vitesse, la stabilité et quasi-universelle disponibilité [30].

Une des conséquences de grande disponibilité et l'efficacité de C est que les compilateurs, les bibliothèques et les interprètes d'autres langages de programmation sont souvent mises en œuvre C. Les principales implémentations de Python (CPython), Perl 5 et PHP sont tous écrits en C.

Grâce à sa fine couche d'abstraction et de bas frais généraux, C permet des implémentations efficaces des algorithmes et structures de données, ce qui est utile pour les programmes qui effectuent beaucoup de calculs. Par exemple, la bibliothèque multi-précision GNU, le GNU Scientific Library, Mathematica et MATLAB sont entièrement ou partiellement écrit en C.

C est parfois utilisé comme un langage intermédiaire par les implémentations d'autres langues. Cette approche peut être utilisée pour la portabilité ou de commodité, à l'aide de C comme un langage intermédiaire, il n'est pas nécessaire de développer des générateurs de code spécifiques à la machine. C dispose de quelques fonctionnalités telles que les directives du préprocesseur de numéros de lignes et les virgules superflues en option à la fin des listes d'initialiseur, qui charge la compilation du code généré. Cependant, certaines des lacunes de C ont suscité le développement d'autres langues basés sur C spécifiquement conçus pour être utilisés comme langues intermédiaires, tels que C -.

C a également été largement utilisé pour implémenter des applications de l'utilisateur final, mais une grande partie de ce développement s'est déplacée vers nouveaux langages.
Langues associées
C a directement ou indirectement influencé de nombreuses langues ultérieurs tels que C #, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Python et C de Shell Unix. L'influence la plus répandue a été syntaxique: toutes les langues mentionnées combiner la déclaration et (plus ou moins reconnue) syntaxe de l'expression de C avec des systèmes de type, les modèles de données et / ou des structures de programmes de grande envergure qui diffèrent de celles de C, parfois radicalement .

Plusieurs interprètes quasi-C C ou existent, y compris Ch et CINT, qui peut également être utilisée pour les scripts.

Quand langages orientés objet est devenu populaire, C + + et Objective-C sont deux extensions différentes de C qui ont fourni des capacités orientées objet. Les deux langues ont été initialement mis en œuvre comme les compilateurs source-sources; code source a été traduit en C, puis compilé avec un compilateur C.

Le C + + langage de programmation a été conçue par Bjarne Stroustrup comme une approche pour fournir une fonctionnalité orientée objet avec C-comme la syntaxe. C + + ajoute une plus grande force de frappe, de cadrage et d'autres outils utiles dans la programmation orientée objet et permet la programmation générique via templates. Près d'un sur-ensemble du C, C + + prend désormais en charge plus de C, à quelques exceptions près (voir Compatibilité de C et C + +).

Objective-C était à l'origine une couche très "fine" au-dessus de C, et reste un sur-ensemble strict de C qui permet la programmation orientée objet en utilisant un paradigme de frappe dynamique / statique hybride. Objective-C tire sa syntaxe à la fois C et Smalltalk: syntaxe qui implique prétraitement, expressions, déclarations de fonctions, et les appels de fonction est héritée de C, tandis que la syntaxe des fonctionnalités orientées objet a été prise à l'origine de Smalltalk.

En plus de C + + et Objective-C, Ch, Cilk et Unified Parallel C sont presque supersets de C.

Published By Drupal french Study