Que doit savoir un programmeur C? [fermé]

11

Quels sont les concepts / techniques / fonctionnalités de langage que tout programmeur C décent devrait connaître / être au courant (exclure l'ingénierie logicielle générale et similaire et se concentrer uniquement sur des choses spécifiques C). Je voudrais savoir pour pouvoir combler certaines lacunes possibles dans mes connaissances en C.

Anto
la source
9
Commencez par les questions C de Stack Overflow et voyez s'il y a quelque chose que vous ne savez pas.
chrisaycock
3
Le programmeur AC devrait probablement savoir que2 + 2 = 4
Edward Strange
21
Ils devraient connaître un magasin qui vend des chaussures pare-balles.
Adam Crossland
1
Il existe des centaines de livres écrits sur ce sujet. Votre question est vraiment assez vague. Vous devrez être plus précis pour obtenir des réponses décentes qui ne sont pas seulement une liste de choses. Et vu les réponses dégagées si loin de cette question, je pense qu'elle doit être retravaillée ou fermée.
Walter
2
Un autre langage de programmation?
Muhammad Alkarouri

Réponses:

19

Spécifique à C? Mis à part les constructions standard communes à la plupart des langages procéduraux, je dois dire:

  • (ab) utilisation du préprocesseur
  • éditeur de liens vs compilateur
  • Pointers Pointers Pointers!
  • Comment les tableaux sont des pointeurs sont des tableaux
  • Comment fonctionnent les chaînes C et comment elles sont également des pointeurs et des tableaux
  • Comment une mauvaise utilisation de la chaîne C peut entraîner des débordements de tampon
  • Comment lancer n'importe quoi sur quoi que ce soit (ce ne sont que des 1 et des 0 après tout :))
  • Gestion de mémoire manuelle malloc / gratuit
  • Stack vs Heap
  • Aliasing de pointeur, (pourquoi son illégal en C99)
  • Penser le développement en termes de modules (fichiers .h / .c) avec un ensemble de fonctions exposées publiquement au lieu de classes strictement
  • Les syndicats
  • Pourquoi Sprintf peut vous faire sauter le pied
  • Pointeurs de fonction
Doug T.
la source
J'ajouterais des «débordements de tampon» à la liste.
Aidan Cully
@Aidan, bonne prise. Ajoutée.
Doug
2
Comment les tableaux C et les pointeurs ne sont pas les mêmes: books.google.ca/…
Matthieu
les pointeurs auraient dû être répétés au moins 3 fois plus
Gaurav
8

Comprenez les pointeurs et vous comprendrez les ordinateurs.

PP.
la source
12
Non, vous aurez simplement l'illusion que vous comprenez les ordinateurs.
Job
4

En plus de l'excellente réponse de pythagras,

comment écrire (ou au moins lire) des déclarations compliquées, telles que char (*(*funcs[4])())[10]

funcs est un tableau [4] de pointeurs sur une fonction renvoyant un pointeur sur le tableau [10] de char

tcrosley
la source
1
Si cela devient si complexe, cela appartient peut-être dans un commentaire?
Job
7
peut-être devrait-il apprendre à éviter d'écrire comme ça?
FabianB
3
  1. Règles de promotion des nombres entiers
  2. Initialiser tout à une valeur connue
  3. GOTO n'est pas mal surtout lorsqu'il est utilisé pour gérer les exceptions / échecs
  4. malloc et / ou calloc peuvent retourner NULL ... assurez-vous que vos valeurs de retour de contrôle
  5. De petites allocations de mémoire fréquentes peuvent provoquer une fragmentation sur le tas.
  6. Arithmétique du pointeur
  7. Les masques de bits sont votre ami
  8. x >> 1 est équivalent à x / 2 pour les entiers non signés
Pemdas
la source
+1 pour GOTO n'étant pas mauvais :)
zvrba
2

Le programmeur AC devrait connaître ... d'autres langues! ;-) Il est toujours utile de connaître les concepts d'autres langages de différents paradigmes, comme la POO, la programmation fonctionnelle, etc.

Plus sérieusement, un coup d'œil au concours de programmation obscurci est amusant et, curieusement, une bonne expérience aussi.

PhiLho
la source
2

J'ai mentionné "débordements de tampon" dans un commentaire à la réponse de Pythagras, je devrais probablement clarifier ce que je voulais dire un peu. En C, il ne suffit pas de savoir que travailler directement avec la mémoire est dangereux - vous devez également comprendre les façons précises dont il est dangereux. Je n'aime pas vraiment la métaphore "se tirer dans le pied" pour tous ces cas - la plupart du temps, ce n'est pas vous qui appuyez sur la gâchette, mais souvent c'est un acteur avec des intérêts contraires au vôtre et / ou à vos utilisateurs '' .

Par exemple, dans une architecture avec une pile décroissante (les architectures les plus courantes correspondent à cette facture - x86 et ARM généralement inclus), lorsque vous appelez une fonction, l'adresse de retour de la fonction sera placée sur la pile après les variables locales définies dans le corps de la fonction. Donc, si vous déclarez un tampon en tant que variable locale et exposez cette variable au monde extérieur sans vérifier le dépassement de tampon, comme ceci:

void myFn(void) {
    char buf[256];
    gets(buf);
}

un utilisateur externe peut vous envoyer une chaîne qui écrase l'adresse de retour de la pile - en gros, il peut changer l'idée d'exécution de votre programme du call-graph qui mène à la fonction actuelle. Ainsi, l'utilisateur vous donne une chaîne qui est la représentation binaire d'un code exécutable pour votre architecture, suffisamment de remplissage pour déborder la pile myFnet quelques données supplémentaires pour écraser l'adresse de retour pour myFnpointer vers le code qu'il vous a donné. Si cela se produit, alors quand myFnaurait normalement retourné le contrôle à son appelant, il se connectera au code fourni par l'utilisateur malveillant. Si vous écrivez du code C (ou C ++) susceptible d'être exposé à des utilisateurs non fiables, vous devez comprendre ce vecteur d'attaque. Vous devez comprendre pourquoi un débordement de tampon contre la pile est souvent (mais pas toujours) plus facilement exploitable qu'un autre contre le tas, et vous devez comprendre comment la mémoire du tas est disposée (pas trop en détail, nécessairement, mais le L'idée qu'une malloc()région a des structures de contrôle qui l'entourent peut aider à comprendre pourquoi votre programme se bloque dans une autre malloc(), ou dans free()).

C vous expose à des détails de bas niveau sur le fonctionnement de votre machine, et il vous donne un contrôle plus direct sur votre machine que tout autre langage édité par l'utilisateur largement utilisé aujourd'hui. Une grande puissance s'accompagne d'une grande responsabilité - vous devez réellement comprendre ces détails de bas niveau afin de travailler avec C de manière sûre et efficace.

Aidan Cully
la source
0

En plus des autres bonnes réponses, je voudrais ajouter des techniques de programmation défensive à la liste.

Par exemple, utiliser des assertions au début / à la fin des fonctions pour vérifier le contrat.

AndersK
la source