Le chiamate di funzione

La libreria fornita da Microsoft fornisce allo sviluppatore un ricco insieme di API: il nucleo centrale è basato sulla libreria di Berkeley, mentre un ulteriore insieme estende le funzionalità esportate con alcune caratteristiche specifiche per Windows.

Prosegue...

Vota questo articolo per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Concetti Preliminari

L’interfaccia di programmazione chiamata Windows Socket (Winsock) utilizza il paradigma delle socket introdotto dalla libreria BDS del mondo UNIX, anche se con qualche piccolo adattamento per il sistema operativo della Microsoft.

Prosegue...

Vota questo articolo per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

 

Big-endian e little-endian sono due metodi differenti usati dai calcolatori per immagazzinare in memoria dati di dimensione superiore al byte (es. word, dword, qword).

Ad esempio, Intel e Digital usano il formato little endian mentre Motorola, IBM e Sun usano il formato big endian.
Il big-endian, dato che è stato scelto come ordine standard in molti protocolli utilizzati in Internet, viene anche chiamato network byte order. Per contro viene chiamato host byte order l'ordine nativo dell'host in uso.

Prosegue...

Vota questo articolo per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Iniziamo con il codice più classico che esista e cerchiamo di compilare il programma:

#include <stdio.h>
int main (void)
{
  printf ("Hello, world!\n");
  return 0;
}

Se assumiamo che il programma sia memorizzato in un file denominato hello.c, il comando per compilarlo sarà il seguente:

gcc -Wall hello.c -o hello

Il comando precedente ha come effetto la compilazione del file hello.c e la produzione di un file eseguibile denominato "hello". Il nome del file oggetto viene specificato tramite l'opzione -o; questa opzione è generalmente l'ultima della riga di comando e se omessa ha come consequenza la generazione di un file oggetto con il nome predefinito "a.out". L'opzione -Wall abilita la visualizzazione di tutti i messaggi di warning. Per eseguire il programma è necessario digitare il nome del file eseguibile preceduto dal suo percorso; in questo caso:

$ ./hello

Nel caso di programmi di grandi dimensioni, per semplificare l'editazione e la comprensione del codice, è comune dividere il sorgente su più file; questa situazione comporta la compilazione separata di ciascun file del progetto. Supponiamo, ad esempio, che il progetto sia composto da file1.c e file2.c, allora per compilare e linkare l'applicazione in un unico file eseguibile di nome test, è sufficiente digitare il comando:

$ gcc -Wall file1.c file2.c -o test

Notare che eventuali file header inclusi nei sorgenti non devono essere specificati nel comando di compilazione.

Supponiamo adesso di aver modificato una funzione implementata nel file file2.c e di voler generare il nuovo eseguibile, in questo caso per evitare inutili perdite di tempo, è possibile ricompilare esclusivamente il file sorgente file2.c, tramite il comando:

$ gcc -Wall -c file2.c

Successivamente per linkare assieme il vecchio file1.c con il nuovo file2.c, si può scrivere:

$ gcc file1.o file2.o -o test

 

Correntemente valutato 4.4 da 5 utenti

  • Currently 4,4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

I puntatori a funzione sono variabili che possono essere inizializzate con l'indirizzo di una funzione; questo genere di puntatori sono molto utili, perché consentono di richiamare all'interno dello stesso blocco di codice funzioni diverse (anche se tutte con la stessa signature), modificando a tempo di esecuzione e sulla base di altri dati del programma, il comportamento del codice. Questo processo, in cui gli indirizzi delle funzioni da chiamare non sono risolti al momento della compilazione, ma in fase di esecuzione si chiama late binding.

Per dichiarare un puntatore a funzione basta iniziare scrivendo il prototipo della funzione, poi sostituire il nome_funzione con (*nome_puntatore) ed infine eliminare i nomi dei parametri; a questo punto nome_funzione è il puntatore da utilizzare. Ad esempio supponiamo di voler dichiarare un puntatore alla funzione:

void func(int value);

basta scrivere:

void (*pFunc)(int);

pFunc è il puntatore da utilizzare, adesso non resta che inizializzarlo:

pFunc = func;

E' bene notare che la riga precedente è equivalente a scrivere:

pFunc = &func;

A volte la presenza di più di un asterisco può rendere difficoltoso l'interpretazione del prototipo della funzione, ma la regola è sempre la stessa: isolare il nome della funzione con il suo asterisco ed interpretare il resto come una funzione "normale". Ad esempio:

void* (*pFunc)(int *);

L'invocazione di una funzione tramite un puntatore non è dissimile dall'invocazione della funzione tramite il suo nome:

pFunc(10);

La riga precedente è equivalente a scrivere:

(*pFunc)(10);

Vediamo desso come sia possibile passare una funzione come parametro ad un'altra funzione sfruttando i puntatori.

void func (int v)
{
  printf("valore: %d\n", v);
}

void call_func(int v, void (*f1)(int))
{
  printf("valore: %d\n", v);
  f1(v + 1);
}

int main_funptr(int argc, char *argv[])
{
   call_func(3, func);
   return 0;
}

Come si nota dal codice precente, la funzione call_func riceve come parametri un intero ed una funzione con la signature void f1(int).

Vota questo articolo per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Calendario

<<  settembre 2010  >>
lumamegivesado
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar
Licenza d'uso
Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati mediante:

Licenza Creative Common