Che cosa dovrebbe sapere un programmatore C? [chiuso]

11

Quali sono alcuni concetti / tecniche / caratteristiche linguistiche che ogni programmatore C decente dovrebbe conoscere / conoscere (escludere l'ingegneria generale del software e simili e concentrarsi solo su cose specifiche di C). Mi piacerebbe sapere in modo che sarei in grado di colmare alcune possibili lacune nella mia conoscenza C.

    
posta Anto 15.02.2011 - 21:40
fonte

7 risposte

18

Specifico per C? A parte i costrutti standard comuni alla maggior parte dei linguaggi procedurali, dovrei dire:

  • (ab) usando il preprocessore
  • linker vs compilatore
  • Puntatori Puntatori Puntatori!
  • Come gli array sono puntatori sono array
  • Come funzionano le stringhe C e come sono anche i puntatori e gli array
  • Il cattivo utilizzo della stringa C può causare overflow del buffer
  • Come trasmettere qualsiasi cosa a qualsiasi cosa (è tutto solo 1s e 0s dopotutto :))
  • Gestione manuale della memoria malloc / gratuita
  • Stack vs Heap
  • Aliasing puntatore, (perché è illegale in C99)
  • Pensa allo sviluppo in termini di moduli (file .h / .c) con un insieme di funzioni pubblicamente esposte invece che strettamente classi
  • Sindacati
  • Perché sprintf può far saltare il piede
  • Puntatori di funzioni
risposta data 15.02.2011 - 21:48
fonte
7

Comprendi i puntatori e capirai i computer.

    
risposta data 15.02.2011 - 21:53
fonte
4

Oltre all'eccellente risposta di pythagras,

come scrivere (o almeno leggere) dichiarazioni complicate, come char (*(*funcs[4])())[10]

funcs è un array [4] di puntatori a una funzione che restituisce il puntatore all'array [10] di char

    
risposta data 15.02.2011 - 22:17
fonte
3
  1. Regole di promozione intera
  2. Inizializza tutto con un valore noto
  3. GOTO non è male, specialmente se usato per gestire eccezioni / errori
  4. malloc e / o calloc possono restituire NULL ... assicurati che il tuo controllo restituisca valori
  5. Frequenti allocazioni di piccole memoria possono causare la frammentazione nell'heap.
  6. Aritmetica puntatore
  7. Le maschere di bit sono tuoi amici
  8. x > > 1 è equivalente a x / 2 per interi senza segno
risposta data 16.02.2011 - 01:10
fonte
2

Un programmatore C dovrebbe sapere ... altre lingue! ;-) È sempre fruttuoso conoscere i concetti di altri linguaggi di vari paradigmi, come OOP, programmazione funzionale e così via.

Più seriamente, uno sguardo al contest di programmazione offuscato è divertente e, curiosamente, anche una bella esperienza.

    
risposta data 16.02.2011 - 00:30
fonte
2

Ho menzionato "buffer overflow" in un commento alla risposta di Pythagras, dovrei probabilmente chiarire cosa intendevo un po '. In C, non è sufficiente sapere che lavorare direttamente con la memoria è pericoloso - devi anche capire i modi precisi in cui è pericoloso. Non mi piace molto la metafora di "sparare te stesso nel piede" per tutti questi casi - il più delle volte, non è tu che tira il grilletto, ma spesso è un attore con interessi contrari a tuo e / o dei tuoi utenti.

Ad esempio, in un'architettura con uno stack discendente (le architetture più popolari si adattano a questo disegno di legge - x86 e ARM generalmente inclusi), quando si chiama una funzione, l'indirizzo di ritorno per la funzione verrà inserito nello stack dopo le variabili locali definite nel corpo della funzione. Quindi se dichiari un buffer come variabile locale ed esporti quella variabile al mondo esterno senza controllare l'overflow del buffer, in questo modo:

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

un utente esterno può inviarti una stringa che sovrascrive l'indirizzo di ritorno dallo stack - in pratica, può cambiare l'idea di runtime del programma del call-graph che conduce alla funzione corrente. Quindi l'utente ti fornisce una stringa che è la rappresentazione binaria di un codice eseguibile per la tua architettura, abbastanza padding da sovraccaricare lo stack da myFn , e alcuni dati aggiuntivi da sovrascrivere l'indirizzo di ritorno per myFn per puntare al codice che ha dato tu. Se ciò accade, quando myFn normalmente avrebbe restituito il controllo al proprio chiamante, verrà invece sostituito al codice fornito dall'utente malintenzionato. Se scrivi codice C (o C ++) che ha il potenziale di essere esposto a utenti non fidati, devi capire questo vettore di attacco . Dovresti capire perché un buffer overflow rispetto allo stack è spesso (ma non sempre) più facilmente sfruttabile di uno contro lo heap, e dovresti capire come viene strutturata la memoria nell'heap (non in modo troppo dettagliato, necessariamente, ma idea che una regione malloc() 'ed abbia strutture di controllo che la circondano può aiutarti a capire perché il tuo programma si arresta in modo anomalo in un altro malloc() o in free() ).

C ti espone a dettagli di basso livello su come funziona la tua macchina e ti dà un controllo più diretto sulla tua macchina rispetto a qualsiasi altra lingua modificata dall'utente oggi ampiamente utilizzata. Con un grande potere derivano grandi responsabilità - in realtà devi capire quei dettagli di basso livello per lavorare con C in modo sicuro ed efficace.

    
risposta data 16.02.2011 - 13:31
fonte
0

Oltre alle altre buone risposte, vorrei aggiungere programmazione difensiva tecniche alla lista.

es. utilizzando asserzioni all'inizio / fine delle funzioni per verificare il contratto.

    
risposta data 16.02.2011 - 05:14
fonte

Leggi altre domande sui tag