Lezione del 20/6/2006¶
-
Ricerca del massimo su un vettore
File ex008.c
1#include <stdio.h> 2/* 3 * Vettori e Matrici: 4 * 5 * ricerca del massimo su un vettore 6 * 7 */ 8 9 10/* 11 * Un vettore e' dichiarato nel seguente modo: 12 */ 13 14int a[100] ; 15 16/* int = dichiarazione del tipo di vettore, 17 cioe' e' un vettore di interi */ 18 19/* a e' in nome del vettore */ 20/* [100] e' un vettore di 100 elementi indirizzati 21 da 0 a 99 */ 22/* per accedere all'iesimo elemento si scrive a[i] */ 23 24int /* ritorna la posizione dell'elemento massimo */ 25find_max_index( int const v[], /* vettore su cui fare la ricerca 26 [] indica che non conosco la dimensione 27 del vettore 28 const indica che non modifico il contenuto 29 del vettore all'interno della funzione 30 */ 31 int const size /* dimenzione del vettore o comunque 32 dimensione di lavoro o di ricerca */ ) { 33 int max_is = 0 ; /* dichiaro una variabile e la inizializzo contestualmente */ 34 /* e' equivalente a scrivere int max_is ; max_is = 0 ; */ 35 int i = 1 ; 36 for ( ; i < size ; ++i ) { 37 if ( v[i] > v[max_is] ) max_is = i ; 38 } 39 return max_is ; 40} 41 42int 43main() { 44 /* dichiarazione con inizializzazione */ 45 int a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 46 /* in vettore verra' dimensionato al numero di elementi 47 nella lista tra { }, in questo caso a 8 */ 48 /* si poteva anche scrivere 49 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 50 ma se tolgo un elemento avrei un elemento 51 non inizializzato 52 */ 53 int size = sizeof(a)/sizeof(a[0]) ; 54 int position ; 55 56 printf("Dimensione in byte del vettore: %ld\n", sizeof(a)); 57 printf("Dimensione in byte di un elemento del vettore: %ld\n", sizeof(a[0])); 58 printf("Dimensione in numero di elementi del vettore: %d\n", size); 59 60 position = find_max_index( a, size ) ; 61 62 printf("L'elemento massimo e' %d alla posizione %d\n", a[position], position); 63 64 return 0 ; 65}
-
Ordinamento Bubble Sort
File ex009.c
1#include <stdio.h> 2/* 3 * Vettori e Matrici: 4 * 5 * ordinamento bubble sort. 6 * 7 */ 8 9int /* ritorna la posizione dell'elemento minimo */ 10find_min_index( int const v[], /* vettore su cui fare la ricerca 11 [] indica che non conosco la dimensione 12 del vettore 13 const indica che non modifico il contenuto 14 del vettore all'interno della funzione 15 */ 16 int const size /* dimensione del vettore o comunque 17 dimensione di lavoro o di ricerca */ ) { 18 int min_is = 0 ; 19 int i = 1 ; 20 for ( ; i < size ; ++i ) { 21 if ( v[i] < v[min_is] ) min_is = i ; 22 } 23 return min_is ; 24} 25 26void /* vuoto, indica che la funzione non restituisce niente! 27 (come SUBROUTINE in FORTRAN) */ 28bubble_sort( int v[], /* vettore su cui fare l'ordinamento 29 [] indica che non conosco la dimensione del vettore 30 NON USO const perche' il vettore e' modificato 31 dalla funzione */ 32 int const size /* dimensione del vettore o comunque 33 dimensione di lavoro */ ) { 34 35 int i, pos_min ; 36 for ( i = 0 ; /* inizializzazione */ 37 i < size-1 ; /* vado dal primo (0-esimo) 38 al penultimo (size-2 esimo)elemento */ 39 ++i /* incremento, passo all'elemento successivo */ 40 ) { 41 pos_min = find_min_index( v+i, /* indirizzo di v[i] */ 42 size-i /* considero solo gli elementi necessari */ 43 ) ; 44 45 pos_min += i ; /* aggiungo i alla posizione del minimo 46 perche' sto considerando il sotto vettore 47 {v[i],v[i+1],...,v[size-1]} 48 */ 49 /* equivalente a pos_min = pos_min + i ; 50 si puo fare con gli operatori 51 + - * / 52 % resto divisione ( ad esempio 7 % 3 resto divisione 7/3 vale 1 53 perche 7 = 2*3 + 1) 54 || or 55 && and 56 | or bit a bit 57 & and bit a bit 58 */ 59 60 /* scambio l'emento i-esimo con l'elemento pos_min-esimo */ 61 int buffer = v[pos_min]; 62 v[pos_min] = v[i] ; 63 v[i] = buffer ; 64 } 65 66} 67 68int 69main() { 70 /* dichiarazione con inizializzazione */ 71 int a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 72 /* in vettore verra' dimensionato al numero di elementi 73 nella lista tra { }, in questo caso a 8 */ 74 /* si poteva anche scrivere 75 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 76 ma se tolgo un elemento avrei un elemento 77 non inizializzato 78 */ 79 int size = sizeof(a)/sizeof(a[0]) ; 80 int i ; 81 82 printf("Vettore non ordinato: %d",a[0]); 83 for ( i=1; i < size ; ++i ) 84 printf( ", %d",a[i]) ; 85 printf("\n"); 86 87 bubble_sort( a, size ) ; 88 89 printf("Vettore ordinato: %d",a[0]); 90 for ( i=1; i < size ; ++i ) 91 printf( ", %d",a[i]) ; 92 printf("\n"); 93 94 return 0 ; 95}
-
Ordinamento usando le librerie standard
File ex010.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Vettori e Matrici: 6 * 7 * ordinamento quick sort usando routione 8 * di sistema (libreria C standard) 9 * 10 */ 11 12/* 13 * routine di confronto di due numeri 14 * in doppia precisione 15 * 16 * la funzione deve essere del tipo: 17 * int (*compar)(const void *, const void *) 18 */ 19 20/* 21 * void const * pa ; 22 * con questa dichiarazione pa e' un puntatore 23 * a senza tipo a della memoria non modifcabile 24 */ 25 26int 27compare_double( void const * pa, void const * pb) { 28 /* * (aterisco) e' un operatore di deferenziazione 29 cioe' vado alla locazione indicata dal puntatore 30 ed estraggo il contenuto */ 31 double a = * (double*) pa ; 32 /* ^ ^ ^ ^ 33 * | | | | 34 * | | | +--- puntatore all'elemento 35 * | | +--- operatore di "CAST" cioe' reinterpreta 36 * | | quello che sta alla sua destra nel tipo 37 * | | indicato in parentesi. 38 * | | In questo caso, "pa" passa da puntatore 39 * | | a void a puntatore a double 40 * | | 41 * | +--- * (asterisco) e' l'operatore di deferenziazione 42 * | cioe' prende il contenuto della zona di memoria 43 * | indirizzata dal puntatore. 44 * | 45 * +-- variabile che memorizzera una copia 46 * del "doble" puntato da pa 47 */ 48 49 double b = * (double*) pb ; 50 51 if ( a < b ) return -1 ; 52 if ( a > b ) return +1 ; 53 return 0 ; 54} 55 56int 57main() { 58 /* dichiarazione con inizializzazione */ 59 double a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 60 /* in vettore verra' dimensionato al numero di elementi 61 nella lista tra { }, in questo caso a 8 */ 62 /* si poteva anche scrivere 63 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 64 ma se tolgo un elemento avrei un elemento 65 non inizializzato 66 */ 67 int size = sizeof(a)/sizeof(a[0]) ; 68 int i ; 69 70 printf("Vettore non ordinato: %lg",a[0]); 71 for ( i=1; i < size ; ++i ) 72 printf( ", %lg",a[i]) ; 73 printf("\n"); 74 75 qsort( a, size, sizeof(a[0]), 76 compare_double /* compare_double e' un puntatore a funzione */ 77 ) ; 78 79 printf("Vettore ordinato: %lg",a[0]); 80 for ( i=1; i < size ; ++i ) 81 printf( ", %lg",a[i]) ; 82 printf("\n"); 83 84 return 0 ; 85}
File ex011.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Vettori e Matrici: 6 * 7 * ordinamento quick sort usando routione 8 * di sistema (libreria C standard) 9 * 10 */ 11 12/* 13 * routine di confronto di due numeri 14 * in doppia precisione 15 * 16 * la funzione deve essere del tipo: 17 * int (*compar)(const void *, const void *) 18 */ 19 20/* 21 * void const * pa ; 22 * con questa dichiarazione pa e' un puntatore 23 * a senza tipo a della memoria non modifcabile 24 */ 25 26int 27compare_double( double const * pa, double const * pb) { 28 29 /* *pa e' il valore del numero "double" puntato da pa */ 30 /* *pb e' il valore del numero "double" puntato da pb */ 31 32 if ( *pa < *pb ) return -1 ; 33 if ( *pa > *pb ) return +1 ; 34 return 0 ; 35} 36 37 38int 39main() { 40 /* dichiarazione con inizializzazione */ 41 double a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 42 /* in vettore verra' dimensionato al numero di elementi 43 nella lista tra { }, in questo caso a 8 */ 44 /* si poteva anche scrivere 45 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 46 ma se tolgo un elemento avrei un elemento 47 non inizializzato 48 */ 49 int size = sizeof(a)/sizeof(a[0]) ; 50 int i ; 51 52 printf("Vettore non ordinato: %lg",a[0]); 53 for ( i=1; i < size ; ++i ) 54 printf( ", %lg",a[i]) ; 55 printf("\n"); 56 57 qsort( a, size, sizeof(a[0]), 58 (int (*) (const void *,const void *)) compare_double /* compare_double e' un puntatore a funzione */ 59 ) ; 60 61 printf("Vettore ordinato: %lg",a[0]); 62 for ( i=1; i < size ; ++i ) 63 printf( ", %lg",a[i]) ; 64 printf("\n"); 65 66 return 0 ; 67}
File ex012.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Vettori e Matrici: 6 * 7 * ordinamento quick sort usando routione 8 * di sistema (libreria C standard) 9 * 10 */ 11 12/* 13 * routine di confronto di due numeri 14 * in doppia precisione 15 * 16 * la funzione deve essere del tipo: 17 * int (*compar)(const void *, const void *) 18 */ 19 20/* 21 * void const * pa ; 22 * con questa dichiarazione pa e' un puntatore 23 * a senza tipo a della memoria non modifcabile 24 */ 25 26int 27compare_double( double const * pa, double const * pb) { 28 29 /* *pa e' il valore del numero "double" puntato da pa */ 30 /* *pb e' il valore del numero "double" puntato da pb */ 31 32 if ( *pa < *pb ) return -1 ; 33 if ( *pa > *pb ) return +1 ; 34 return 0 ; 35} 36 37typedef int (*compare_fun)( void const *, void const *) ; 38 39int 40main() { 41 /* dichiarazione con inizializzazione */ 42 double a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 43 /* in vettore verra' dimensionato al numero di elementi 44 nella lista tra { }, in questo caso a 8 */ 45 /* si poteva anche scrivere 46 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 47 ma se tolgo un elemento avrei un elemento 48 non inizializzato 49 */ 50 int size = sizeof(a)/sizeof(a[0]) ; 51 int i ; 52 53 printf("Vettore non ordinato: %lg",a[0]); 54 for ( i=1; i < size ; ++i ) 55 printf( ", %lg",a[i]) ; 56 printf("\n"); 57 58 qsort( a, size, sizeof(a[0]), 59 (compare_fun) compare_double /* compare_double e' un puntatore a funzione */ 60 ) ; 61 62 printf("Vettore ordinato: %lg",a[0]); 63 for ( i=1; i < size ; ++i ) 64 printf( ", %lg",a[i]) ; 65 printf("\n"); 66 67 return 0 ; 68}
-
Puntatori e allocazione dinamica
File ex013.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Aritmetica dei puntatori 6 * 7 */ 8 9int 10main() { 11 12 float a[] = {1, 2, -1, -2, 3.4, 5,-7, 0 }; 13 14 /* +------+ 15 * a --> | 1.0 | 16 * +------+ 17 * | 2.0 | 18 * +------+ 19 * | -1.0 | 20 * +------+ 21 * | -2.0 | 22 * +------+ 23 * | 3.4 | 24 * +------+ 25 * | 5.0 | 26 * +------+ 27 * | -7.0 | 28 * +------+ 29 * | 0.0 | 30 * +------+ 31 */ 32 33 float *p1, *p2, *p3 ; /* definisco 3 puntatori a float */ 34 35 p1 = a ; /* p1 ora punta al primo elemento */ 36 /* +------+ 37 * p1 = a --> | 1.0 | 38 * +------+ 39 * | 2.0 | 40 * +------+ 41 * | -1.0 | 42 * +------+ 43 * | -2.0 | 44 * +------+ 45 * | 3.4 | 46 * +------+ 47 * | 5.0 | 48 * +------+ 49 * | -7.0 | 50 * +------+ 51 * | 0.0 | 52 * +------+ 53 */ 54 printf("Primo elemento a[0] = %g *p1 = %g\n", a[0], *p1) ; 55 printf("Indirizzo elemento &a[0] = %X p1 = %X\n", 56 (unsigned)(&a[0]), 57 (unsigned)(p1)) ; 58 59 p2 = a+3 ; /* p2 ora punta al quarto elemento */ 60 /* +------+ 61 * p1 = a --> | 1.0 | 62 * +------+ 63 * | 2.0 | 64 * +------+ 65 * | -1.0 | 66 * +------+ 67 * p2 --> | -2.0 | 68 * +------+ 69 * | 3.4 | 70 * +------+ 71 * | 5.0 | 72 * +------+ 73 * | -7.0 | 74 * +------+ 75 * | 0.0 | 76 * +------+ 77 */ 78 printf("Primo elemento a[3] = %g *p2 = %g\n", a[3], *p2) ; 79 printf("Indirizzo elemento &a[3] = %X p2 = %X\n", 80 (unsigned)(&a[3]), 81 (unsigned)(p2)) ; 82 83 p3 = p2+2 ; /* p3 ora punta al sesto elemento */ 84 /* +------+ 85 * p1 = a --> | 1.0 | 86 * +------+ 87 * | 2.0 | 88 * +------+ 89 * | -1.0 | 90 * +------+ 91 * p2 --> | -2.0 | 92 * +------+ 93 * | 3.4 | 94 * +------+ 95 * p3 --> | 5.0 | 96 * +------+ 97 * | -7.0 | 98 * +------+ 99 * | 0.0 | 100 * +------+ 101 */ 102 printf("Primo elemento a[5] = %g *p3 = %g\n", a[5], *p3) ; 103 printf("Indirizzo elemento &a[5] = %X p3 = %X\n", 104 (unsigned)(&a[5]), 105 (unsigned)(p3)) ; 106 107 /* posso fare la differenza tra puntatori. 108 In risultato e' un intero (con segno) e 109 rappresenta la differenza in celle 110 della dimensione del tipo puntato */ 111 112 printf("p2-p3= %d\n",p2-p3) ; 113 printf("reinterpretati come puntatori a char p2-p3= %d\n", 114 (char*)p2-(char*)p3) ; 115 printf("reinterpretati come puntatori a double p2-p3= %d\n", 116 (double*)p2-(double*)p3) ; 117 118 /* 119 * facciamo arrabbiare il sistema operativo 120 * 121 */ 122 123 printf("*p3= %g\n",*p3) ; 124 p3 = (float*)((char*)p2-1) ; 125 /* | | 126 * | +-- decremento il puntatore come 127 * | puntatore a carattere, quindi p3 128 * | non puntera a inizio "parola". 129 * +--- reinterpreto l'indirizzo come puntatore a float 130 * mi aspetto un errore di accesso alla memoria in 131 * fase di esecuzione, o un valore floating point 132 * sensa senso 133 */ 134 printf("*p3= %g\n",*p3) ; 135 p3 = (float*)((char*)p2-4) ; 136 printf("*p3= %g\n",*p3) ; 137 138 return 0 ; 139}
File ex014.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Aritmetica dei puntatori 6 * 7 * loop su vettore 8 */ 9 10void 11stampa_vec( float const a[], int const dima) { 12 int i ; 13 printf("%g",a[0]); 14 for ( i=1; i < dima ; ++i ) 15 printf( ", %g",a[i]) ; 16 printf("\n"); 17} 18 19int 20main() { 21 22 float a[] = {1, 2, -1, -2, 3.4, 5,-7, 0 }; 23 24 /* +------+ 25 * a --> | 1.0 | 26 * +------+ 27 * | 2.0 | 28 * +------+ 29 * | -1.0 | 30 * +------+ 31 * | -2.0 | 32 * +------+ 33 * | 3.4 | 34 * +------+ 35 * | 5.0 | 36 * +------+ 37 * | -7.0 | 38 * +------+ 39 * | 0.0 | 40 * +------+ 41 */ 42 43 int const dima = sizeof(a)/sizeof(a[0]) ; 44 /* memorizzo la dimensione di a su una costante */ 45 46 float *pa, *pb ; /* definisco 2 puntatori a float */ 47 float b[dima-1] ; /* dimensione di a - 1 */ 48 int i ; 49 /* voglio costruire il vettore b che contiene 50 * all'i-esima posizione 51 * 52 * b[i] = a[i+1]-a[i] 53 * 54 */ 55 56 /* modo triviale */ 57 for ( i=0 ; i < dima -1 ; ++i ) b[i] = a[i+1]-a[i] ; 58 printf("Differenza modo 1\n") ; 59 stampa_vec( a, dima ) ; 60 61 /* usando i puntatori */ 62 for ( pa = a, pb = b ; pa < a + dima - 1 ; ++pa, ++pb ) 63 *pb = pa[1]-pa[0] ; 64 /* *pa e' equivalente a pa[0] 65 * *(pa+1) e' equivalente a pa[1] 66 * 67 * occhio che a e b pur essendo puntatori non 68 * sono modificabili, cioe' non posso scivere ++a 69 * o b = b -1 etc etc 70 */ 71 72 printf("Differenza modo 2\n") ; 73 stampa_vec( a, dima ) ; 74 75 76 return 0 ; 77}
File ex015.c
1#include <stdio.h> 2#include <stdlib.h> 3 4/* 5 * Aritmetica dei puntatori 6 * 7 * allocazione dinamica della memoria. 8 * 9 * SCOPO: 10 * se conosce in tempo di esecuzione la dimensione 11 * di un vettore conviene allocarla dinamicamente. 12 * 13 * essenzialmente bastano tre routine 14 * 15 * (void*) malloc( int numero_di_bytes ) 16 * (void*) realloc( void *old_ptr, int numero_di_bytes ) 17 * void free( void *ptr ) 18 * 19 */ 20 21void 22stampa_vec( float const a[], int const dima) { 23 int i ; 24 printf("%g",a[0]); 25 for ( i=1; i < dima ; ++i ) 26 printf( ", %g",a[i]) ; 27 printf("\n"); 28} 29 30int 31main() { 32 33 float *a, *b ; 34 35 a = malloc( 1000000000000LL * sizeof(double) ) ; 36 /* alloca la memoria per 10 elementi */ 37 if ( a == NULL ) { 38 /* NULL di solito e' il numero 0, 39 se il puntatore contiene queste valore 40 la memoria non e' stata allocata */ 41 42 /* FACCIO QUALCOSA DI ALTERNATIVO .... */ 43 } 44 printf("indirizzo puntato da a = %X\n", (unsigned)a); 45 46 b = malloc( 20 * sizeof(float) ) ; 47 /* alloca la memoria per 10 elementi */ 48 if ( b == NULL ) { 49 /* NULL di solito e' il numero 0, 50 se il puntatore contiene queste valore 51 la memoria non e' stata allocata */ 52 53 /* FACCIO QUALCOSA DI ALTERNATIVO .... */ 54 } 55 printf("indirizzo puntato da b = %X\n", (unsigned)b); 56 57 //printf("Differenza modo 2\n") ; 58 //stampa_vec( a, dima ) ; 59 60 /* 61 * Alla fine di tutto rilascio la memoria 62 * 63 */ 64 65 free(a) ; 66 free(b) ; 67 68 return 0 ; 69}
File ex016.c
1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4 5/* 6 * Aritmetica dei puntatori 7 * 8 * allocazione dinamica della memoria. 9 * 10 */ 11 12/* 13 * Esercizio stupido. 14 * 15 * Dati due vettori a e b costruisco la matrice 16 * M = I + a b^T 17 * 18 * +---------+ 19 * a = | a[0] | 20 * +---------+ 21 * .... 22 * +---------+ 23 * | a[n-1] | 24 * +---------+ 25 * 26 * +---------+ 27 * b = | b[0] | 28 * +---------+ 29 * .... 30 * +---------+ 31 * | b[n-1] | 32 * +---------+ 33 * 34 * AD ESEMPIO 35 * + + + + + + 36 * | 1 | | 1 | | 2 3 3 | 37 * M = I + a b^T = | 1 | + | 2 | + + 38 * | 1 | | 1 | 39 * + + + + 40 * + + 41 * | 3 3 3 | 42 * = | 4 7 6 | 43 * | 2 3 4 | 44 * + + 45 * 46 * Una volta costruita M calcolo la norma-1 47 * 48 * n n 49 * || M ||_1 = max sum | Mij | 50 * J=1 i=1 51 * 52 * Uso per macro per usare gli indici a partire a 1. 53 * 54 */ 55 56double /* norma risultante */ 57norma1_di_un_vettore( double const a[], 58 int const n ) { 59 int i ; 60 double res = 0 ; 61 for ( i = 0 ; i < n ; ++i ) 62 res += fabsf(a[i]) ; 63 return res ; 64} 65 66double /* norma risultante */ 67routine_inutile( double const a[], 68 double const b[], 69 int const n ) { 70 /* uso la allocazione dinamica per questioni 71 didattiche. 72 Esercizio, riscrivere la routione SENZA 73 allocazione dinamica */ 74 double * M ; /* puntatore alla matrice da allocare */ 75 double * p ; /* puntatore genrico per fare conti */ 76 double res ; /* memorizzo la norma 1 della matrice */ 77 double tmp ; 78 int i,j ; /* interi generici per i cicli vari */ 79 80 /* allocazione dinamica */ 81 M = malloc( n*n*sizeof(double)) ; 82 83 /* Da aggiungere il controllo della allocazione dinamica */ 84 85 /* 86 * Per la matrice M puo essere memorizzata 87 * per "colonne", cioe' 88 * M(riga,colonna) = M[riga-1+(colonna-1)*n] 89 * per "righe", cioe' 90 * M(riga,colonna) = M[colonna-1+(riga-1)*n] 91 * 92 */ 93 94 /* uso la macro per "risparmiare" le dita 95 uso la allocazione per colonne */ 96 #define M(I,J) M[(I-1)+(J-1)*n] 97 /* NOTA: cosa fa la macro ? 98 * 99 * se ad esempio scrivo 100 * M(i,j+1) questo viene espanso in 101 * M[(i-1)+(j+1-1)*n]. 102 * ovviamente la macro e' piu' leggibile 103 * ma bisogna definirne una per ogni matrice 104 */ 105 106 #define a(I) a[I-1] 107 #define b(I) b[I-1] 108 /* per evitare di scrivere a[i-1] b[j-1] 109 uso la macro per scrivere a(i) e b(i) */ 110 /* passo 1 setto M(i,j) = a(i)*b(j) */ 111 for ( i = 1 ; i <= n ; ++i ) 112 for ( j = 1 ; j <= n ; ++j ) 113 M(i,j) = a(i)*b(j) ; 114 115 /* se non avessi usato le macro 116 l'istruzione diventava: 117 M(i,j) = a(i)*b(j) ===> M[i-1+(j-1)*n] = a[i-1]*b[j+1] 118 119 oppure cambiando i cicli ad iniziale da 0 120 for ( i = 0 ; i < n ; ++i ) 121 for ( j = 0 ; j < n ; ++j ) 122 M[i+j*n] = a[i]*b[j] ; 123 */ 124 125 /* aggiungo la matrice identita' */ 126 for ( i = 1 ; i <= n ; ++i ) 127 M(i,i) += 1 ; /* e' equivalente a M(i,i) = M(i,i) + 1 ; */ 128 129 /* calcolo della norma 1 */ 130 res = 0 ; 131 for ( i = 1 ; i <= n ; ++i ) { 132 p = & M(1,i) ; /* Puntatore alla i-esima colonna */ 133 tmp = norma1_di_un_vettore( p, n ) ; 134 if ( tmp > res ) res = tmp ; 135 } 136 137 /* libero la memoria utilizzata */ 138 free( M ) ; 139 140 return res ; /* norma 1 di M */ 141} 142 143 144int 145main() { 146 147 /* dichiarazione con inizializzazione */ 148 double a[] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 149 /* in vettore verra' dimensionato al numero di elementi 150 nella lista tra { }, in questo caso a 8 */ 151 /* si poteva anche scrivere 152 int a[8] = { 2, 3, -1, 5, 6, 0, -3, -4 } ; 153 ma se tolgo un elemento avrei un elemento 154 non inizializzato 155 */ 156 int size = sizeof(a)/sizeof(a[0]) ; 157 double res ; 158 159 res = routine_inutile( a, a, size ) ; 160 161 printf("Risultato = %lg\n",res ) ; 162 163 return 0 ; 164}