Lezione del 11/7/2006¶
-
Esempio di compilazione tramite Makefile, file del progetto
File file.h
1/* se non e' definito FILE_H espande il blocco fino ad #endif */ 2#ifndef FILE_H 3#define FILE_H /* definisco FILE_H cosi non includo il file una seconda volta */ 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <math.h> 9 10/* prototipo della funzione */ 11extern int fattorizzazione_LU( double [], int, int, int [] ) ; 12 13extern void stampa_L( FILE * fd, 14 double A[], /* matrice da fattorizzare memorizzata per colonne */ 15 int N, /* dimensione della matrice da fattorizzare */ 16 int lda ) ; /* numero di righe usate in allocazione */ 17 18extern void stampa_U( FILE * fd, 19 double A[], /* matrice da fattorizzare memorizzata per colonne */ 20 int N, /* dimensione della matrice da fattorizzare */ 21 int lda ) ; /* numero di righe usate in allocazione */ 22 23extern void solve_LU( double LU[], /* matrice fattorizzata memorizzata per colonne */ 24 int N, /* dimensione della matrice da fattorizzare */ 25 int lda, /* numero di righe usate in allocazione */ 26 int perm[], /* vettori di interi di domensione >= N che 27 conterra' la permutazione */ 28 double b[], /* temine noto */ 29 double x[] ) ; /* soluzione */ 30 31static 32int 33max(int a, int b) 34{ return a > b ? a : b ; } 35/* test ? vero : falso */ 36 37#endif
File file-vuoto.h
1
File filea.c
1#include "file.h" 2#include "file.h" 3#include "file-vuoto.h" 4 5#define A(I,J) A[(I)+(J)*lda] 6 7int /* valore di ritorno se 0 = tutto ok */ 8 /* se 1 = matrice singolare */ 9fattorizzazione_LU( double A[], /* matrice da fattorizzare memorizzata per colonne */ 10 int N, /* dimensione della matrice da fattorizzare */ 11 int lda, /* numero di righe usate in allocazione */ 12 int perm[] ) { /* vettori di interi di domensione >= N che 13 conterra' la permutazione */ 14 int i, j, k, imax ; 15 double amax, acheck ; 16 17 /* Inizializzo il vettore della permutazione */ 18 for ( i = 0 ; i < N ; ++i ) perm[i] = i ; 19 20 for ( i = 0 ; i < N-1 ; ++i ) { 21 /* ricerca del pivot, cerco elemento di modulo massimo 22 nella colonna i-esima, cioe' A(i,i), A(i+1,i), ..., A(N-1,i) */ 23 imax = i ; 24 amax = fabs( A(i,i) ) ; 25 for ( j=i+1 ; j < N ; j++ ) { 26 acheck = fabs(A(j,i)); 27 if ( acheck > amax ) { 28 amax = acheck ; 29 imax = j ; 30 } 31 } 32 33 /* controllo che acheck > 0, se 0 la matrice e' singolare */ 34 if ( amax == 0 ) return 1 ; 35 if ( imax != i ) { /* scambio la riga i con la riga imax */ 36 /* scambio indici sul vettore della permutazione */ 37 k = perm[i] ; 38 perm[i] = perm[imax] ; 39 perm[imax] = k ; 40 /* scambio delle righe nella matrice A */ 41 for ( j=0 ; j < N ; ++j ) { 42 amax = A(i,j) ; 43 A(i,j) = A(imax,j) ; 44 A(imax,j) = amax ; 45 } 46 } 47 48 /* costruisco la parte della matrice Li e la applico alla matrice 49 LU in costruzione */ 50 for ( k = i+1 ; k < N ; ++k ) { 51 amax = A(k,i) / A(i,i) ; 52 A(k,i) = amax ; 53 for ( j= i+1 ; j < N ; ++j ) 54 A(k,j) -= amax * A(i,j) ; 55 } 56 } 57 return 0 ; /* tutto ok */ 58} 59 60void 61stampa_L( FILE * fd, 62 double A[], /* matrice da fattorizzare memorizzata per colonne */ 63 int N, /* dimensione della matrice da fattorizzare */ 64 int lda ) { /* numero di righe usate in allocazione */ 65 int i, j ; 66 for ( i = 0 ; i < N ; ++i ) { 67 for ( j = 0 ; j < i ; ++j ) { 68 fprintf( fd, "%-10lg ",A(i,j)) ; 69 } 70 fprintf( fd, "1\n") ; /* uso 10 caratteri per numero */ 71 } 72} 73 74void 75stampa_U( FILE * fd, 76 double A[], /* matrice da fattorizzare memorizzata per colonne */ 77 int N, /* dimensione della matrice da fattorizzare */ 78 int lda ) { /* numero di righe usate in allocazione */ 79 int i, j ; 80 for ( i = 0 ; i < N ; ++i ) { 81 for ( j = 0 ; j < i ; ++j ) { 82 fprintf( fd, " ") ; /* 10 spazi bianchi */ 83 } 84 for ( j = i ; j < N ; ++j ) { 85 fprintf( fd, "%-9lg ",A(i,j)) ; 86 } 87 fprintf( fd, "\n") ; /* vado a capo a fine riga */ 88 } 89} 90 91 92#undef A /* elimino la definizione di A(I,I) */ 93 94#define L(I,J) LU[(I)+(J)*lda] 95#define U(I,J) LU[(I)+(J)*lda] 96 97void 98solve_LU( double LU[], /* matrice fattorizzata memorizzata per colonne */ 99 int N, /* dimensione della matrice da fattorizzare */ 100 int lda, /* numero di righe usate in allocazione */ 101 int perm[], /* vettori di interi di domensione >= N che 102 conterra' la permutazione */ 103 double b[], /* temine noto */ 104 double x[] ) { /* soluzione */ 105 106 int i, j ; 107 /* applico la permutazione */ 108 for ( i = 0 ; i < N ; ++i ) x[perm[i]] = b[i] ; 109 110 /* Risolvo Lz = Pb */ 111 for ( i = 1 ; i < N ; ++i ) 112 for ( j = 0 ; j < i ; ++j ) 113 x[i] -= L(i,j)*x[j]; 114 115 /* Risolvo Ux = Lz */ 116 i=N; 117 do { 118 --i ; 119 for ( j = i+1 ; j < N ; ++j ) 120 x[i] -= U(i,j)*x[j]; 121 x[i] /= U(i,i) ; 122 } while ( i > 0 ) ; 123}
File fileb.c
1/* 2 * Esempio "complesso", fattorizzazione LU di Gauss di una Matrice 3 */ 4 5#include "file.h" 6 7int 8main() { 9 10 double M[] = { 11 4, 3, 2, 1, /* prima colonna */ 12 1, 2, 3, 4, /* seconda colonna */ 13 1, 0, 0, 1, /* terza colonna */ 14 0, 1, 2, 5 /* quarta colonna */ 15 } ; 16 17 double b[] = { 9, 11, 16, 32 } ; /* termine noto se la solzione e' 1,2,3,4 */ 18 double x[4] ; /* vettore che conterra' la soluzione */ 19 20 int i, perm[4] ; 21 22 int iflag, dim ; 23 24 dim = 4 ; 25 26 iflag = fattorizzazione_LU( M, dim, dim, perm ) ; 27 28 printf( "Valore del flag=%d\n",iflag); 29 30 #define A(I,J) M[(I)+(J)*4] 31 32 /* stampa della matrice L ed U e la permutazione */ 33 printf("MATRICE L\n") ; 34 stampa_L( stdout, M, dim, dim ); 35 36 printf("MATRICE U\n") ; 37 stampa_U( stdout, M, dim, dim ); 38 39 printf("PERMUTAZIONE\n") ; 40 for ( i = 0 ; i < dim ; ++i ) 41 printf( "perm[%d]=%d\n", i, perm[i]) ; 42 43 solve_LU( M, dim, dim, perm, b, x ) ; 44 45 printf("SOLUZIONE\n") ; 46 for ( i = 0 ; i < dim ; ++i ) 47 printf( "x[%d]=%lg\n", i, x[i]) ; 48 49 return 0 ; 50 51}
-
Semplice esempio di Makefile
File Makefile.vers1
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5test: filea.o fileb.o 6 gcc filea.o fileb.o -o test 7 8filea.o: filea.c file.h 9 gcc -Wall -c filea.c 10 11fileb.o: fileb.c file.h 12 gcc -Wall -c fileb.c 13 14clear: 15 rm filea.o fileb.o test
-
Makefile che usa alcune variabili per parametrizzare compilatore e flags
File Makefile.vers2
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi 14LIBS=-lc 15OBJS=filea.o fileb.o 16 17test: $(OBJS) 18 $(CC) $(OBJS) -o test $(LIBS) 19 20filea.o: filea.c file.h 21 $(CC) $(CFLAGS) -c filea.c 22 23fileb.o: fileb.c file.h 24 $(CC) $(CFLAGS) -c fileb.c 25 26clean: 27 rm $(OBJS) test
-
Makefile che usa un pattern per la compilazione
File Makefile.vers3
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi 14LIBS=-lc 15OBJS=filea.o fileb.o 16 17test: $(OBJS) 18 $(CC) $(OBJS) -o test $(LIBS) 19 20### modo obsoleto per la generazione della regola 21.c.o: 22 $(CC) $(CFLAGS) -c $< 23 24clean: 25 rm $(OBJS) test 26 27## elenco delle dipendenze 28filea.o: filea.c file.h 29fileb.o: fileb.c file.h
File Makefile.vers4
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi -O 14 15CXX=g++ 16CXXFLAGS=-Wall -ansi -O 17 18F77=g77 19FFLAGS=-O3 20 21LIBS=-lc 22OBJS=filea.o fileb.o 23 24test: $(OBJS) 25 $(CC) $(OBJS) -o test $(LIBS) 26 27# regola di compilazione per file tipo C 28%.o: %.c 29 $(CC) $(CFLAGS) -c $< 30 31# regola di compilazione per file tipo C++ 32%.o: %.cc 33 $(CXX) $(CXXFLAGS) -c $< 34 35# regola di compilazione per file tipo Fortran 36%.o: %.f 37 $(F77) $(FFLAGS) -c $< 38 39clean: 40 rm $(OBJS) test 41 42## elenco delle dipendenze 43filea.o: filea.c file.h 44fileb.o: fileb.c file.h
-
Makefile che usa mkdep per la generazione automatica delle dipendenze
File Makefile.vers5
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi -O 14 15CXX=g++ 16CXXFLAGS=-Wall -ansi -O 17 18F77=g77 19FFLAGS=-O3 20 21LIBS=-lc 22SRCS=filea.c fileb.c 23OBJS=filea.o fileb.o 24 25test: $(OBJS) 26 $(CC) $(OBJS) -o test $(LIBS) 27 28# regola di compilazione per file tipo C 29%.o: %.c 30 $(CC) $(CFLAGS) -c $< 31 32# regola di compilazione per file tipo C++ 33%.o: %.cc 34 $(CXX) $(CXXFLAGS) -c $< 35 36# regola di compilazione per file tipo Fortran 37%.o: %.f 38 $(F77) $(FFLAGS) -c $< 39 40clean: 41 rm $(OBJS) test 42 43depend: 44 mkdep $(CFLAGS) $(SRCS) 45 46# 47# Se .depend non esiste la prima volta va creato 48# con touch .depend 49# 50include .depend
-
Due esempi completi con mkdep e makedepend
File Makefile.vers6
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi -O 14 15CXX=g++ 16CXXFLAGS=-Wall -ansi -O 17 18F77=g77 19FFLAGS=-O3 20 21LIBS=-lc 22SRCS=filea.c fileb.c 23OBJS=$(SRCS:.c=.o) 24 25test: $(OBJS) 26 $(CC) $(OBJS) -o test $(LIBS) 27 28# regola di compilazione per file tipo C 29%.o: %.c 30 $(CC) $(CFLAGS) -c $< 31 32# regola di compilazione per file tipo C++ 33%.o: %.cc 34 $(CXX) $(CXXFLAGS) -c $< 35 36# regola di compilazione per file tipo Fortran 37%.o: %.f 38 $(F77) $(FFLAGS) -c $< 39 40clean: 41 rm $(OBJS) test 42 43depend: 44 mkdep $(CFLAGS) $(SRCS) 45 46# 47# Se .depend non esiste la prima volta va creato 48# con touch .depend 49# 50include .depend
File Makefile.vers7
1# 2# oggetto: elenco file dipendenze 3# (tab) comando o comandi da eseguire 4# 5# usando il comando 6# 7# gcc -MM file.c 8# 9# genero la linea delle dipendenze automaticamente 10# 11 12CC=gcc 13CFLAGS=-Wall -ansi -O 14 15CXX=g++ 16CXXFLAGS=-Wall -ansi -O 17 18F77=g77 19FFLAGS=-O3 20 21LIBS=-lc 22SRCS=filea.c fileb.c 23OBJS=$(SRCS:.c=.o) 24 25test: $(OBJS) 26 $(CC) $(OBJS) -o test $(LIBS) 27 28# regola di compilazione per file tipo C 29%.o: %.c 30 $(CC) $(CFLAGS) -c $< 31 32# regola di compilazione per file tipo C++ 33%.o: %.cc 34 $(CXX) $(CXXFLAGS) -c $< 35 36# regola di compilazione per file tipo Fortran 37%.o: %.f 38 $(F77) $(FFLAGS) -c $< 39 40clean: 41 rm $(OBJS) test 42 43depend: 44 makedepend $(SRCS) 45# DO NOT DELETE 46 47filea.o: file.h /usr/include/stdio.h /usr/include/_types.h 48filea.o: /usr/include/sys/_types.h /usr/include/sys/cdefs.h 49filea.o: /usr/include/machine/_types.h /usr/include/ppc/_types.h 50filea.o: /usr/include/string.h /usr/include/stdlib.h /usr/include/sys/wait.h 51filea.o: /usr/include/sys/signal.h /usr/include/sys/appleapiopts.h 52filea.o: /usr/include/machine/signal.h /usr/include/ppc/signal.h 53filea.o: /usr/include/sys/resource.h /usr/include/machine/endian.h 54filea.o: /usr/include/ppc/endian.h /usr/include/sys/_endian.h 55filea.o: /usr/include/stdint.h /usr/include/libkern/OSByteOrder.h 56filea.o: /usr/include/libkern/ppc/OSByteOrder.h /usr/include/alloca.h 57filea.o: /usr/include/machine/types.h /usr/include/ppc/types.h 58filea.o: /usr/include/math.h /usr/include/architecture/ppc/math.h 59filea.o: file-vuoto.h 60fileb.o: file.h /usr/include/stdio.h /usr/include/_types.h 61fileb.o: /usr/include/sys/_types.h /usr/include/sys/cdefs.h 62fileb.o: /usr/include/machine/_types.h /usr/include/ppc/_types.h 63fileb.o: /usr/include/string.h /usr/include/stdlib.h /usr/include/sys/wait.h 64fileb.o: /usr/include/sys/signal.h /usr/include/sys/appleapiopts.h 65fileb.o: /usr/include/machine/signal.h /usr/include/ppc/signal.h 66fileb.o: /usr/include/sys/resource.h /usr/include/machine/endian.h 67fileb.o: /usr/include/ppc/endian.h /usr/include/sys/_endian.h 68fileb.o: /usr/include/stdint.h /usr/include/libkern/OSByteOrder.h 69fileb.o: /usr/include/libkern/ppc/OSByteOrder.h /usr/include/alloca.h 70fileb.o: /usr/include/machine/types.h /usr/include/ppc/types.h 71fileb.o: /usr/include/math.h /usr/include/architecture/ppc/math.h
-
Uso del preprocessore per la compilazione condizionale
1/* 2 * esempio di compilazione condizionale 3 * 4 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8 9/* 10 * ci sono macro predefinite da sistema 11 * che possono essere usate in debugging e compilazione 12 * condizionale. 13 * le principali sono: 14 * 15 * __LINE__ = contiene la linea corrente file 16 * __FILE__ = contiene il nome del file corrente 17 * 18 */ 19 20/* esempio d'uso seil test A e' falso esco con un errore */ 21 22#define DEBUG_CHECK(A) \ 23 if ( !(A) ) { \ 24 printf("Errore alla linea %d nel file %s\n",__LINE__,__FILE__) ; \ 25 exit(1) ; \ 26 } 27 28/* \ a fine riga indica che la macro prosegue alla linea successiva */ 29 30int 31main() { 32 DEBUG_CHECK( 1 == 2 ) ; 33}
1/* 2 * esempio di compilazione condizionale 3 * 4 */ 5 6#include <stdio.h> 7#include <stdlib.h> 8 9#ifdef WIN32 10 /* viene espanso questo pezzo di codice se WIN32 e' definito */ 11 12 /* WIN32 di solito e' definito da un compilatore installato su un 13 sistema windows. In questo modo si possono compilare parti 14 critiche "SISTEM DEPENDENT" con un unico programma 15 */ 16#else 17 /* viene espanso questo pezzo di codice se WIN32 NON e' definito */ 18#endif 19 20#ifndef WIN32 21 /* viene espanso questo pezzo di codice se WIN32 NON e' definito */ 22#else 23 /* viene espanso questo pezzo di codice se WIN32 e' definito */ 24#endif 25 26/* 27 analogamente di puo usare 28*/ 29 30#if defined(WIN32) /* e' equivalente ad #ifdef WIN32 */ 31 /* questa forma e' piu' elastica */ 32 #if defined(PIPPO) && defined(PLUTO) 33 #else 34 #endif 35#endif 36 37#if !defined(WIN32) /* e' equivalente ad #ifndef WIN32 */ 38 39#endif 40 41#if 0 42/* questo pezzo NON viene compilato */ 43#endif 44 45#if 1 46/* questo pezzo VIENE compilato */ 47#endif 48 49 50/* esempio d'uso seil test A e' falso esco con un errore */ 51 52#define DEBUG_CHECK(A) \ 53 if ( !(A) ) { \ 54 printf("Errore alla linea %d nel file %s\n",__LINE__,__FILE__) ; \ 55 exit(1) ; \ 56 } 57 58/* esempio di concatenazione nella macro */ 59#define CONCATENA(A,B) A##B 60 61/* le macro possono definire delle costanti */ 62#define UNA_COSTANTE 1234 63 64/* \ a fine riga indica che la macro prosegue alla linea successiva */ 65 66int 67main() { 68 int abc = 2 ; 69 CONCATENA(ab,c) = 3 ; 70 DEBUG_CHECK( 1 == 2 ) ; 71}