[WikiDyd] [TitleIndex] [WordIndex

Języki i metodyka programowania - kurs w sem. zimowym 2010/2011

Wykład IV: 26 października 2010

Mówiliśmy o mierzeniu czasu:

   1 #include <stdio.h>
   2 #include <time.h>
   3 
   4 int main() {
   5     clock_t start= clock();
   6     clock_t stop = clock();
   7 
   8     while( (stop=clock()) == start )
   9         ;
  10 
  11     printf( "D_clock=%ld ticks = %g s\n", stop-start, (float)(stop-start)/CLOCKS_PER_SEC );
  12 
  13     return 0;
  14 }

Dokończyliśmy czytanie liczb:

   1 #include <stdio.h>
   2 #include <time.h>
   3 #include <math.h>
   4 
   5 int
   6 main( int argc, char * argv[] ) {
   7   double sum = 0.0;
   8   double sum2 = 0.0;
   9   double x;
  10   int n = 0;
  11   time_t start;
  12 
  13   FILE *in = argc > 1 ? fopen( argv[1], "r" ) : stdin;
  14 
  15   if( in == NULL ) {
  16     fprintf( stderr, "%s: nie moge czytac %s\n", argv[0], argv[1] );
  17     return 1;
  18   }
  19 
  20   start= clock();
  21 
  22   while( fscanf( in, "%lf", &x ) == 1 ) {
  23     sum += x;
  24     sum2 += x*x;
  25     n++;
  26   }
  27 
  28   printf( "Czytanie trwalo %g s (CLOCKS/SEC=%ld)\n",
  29           (float)(clock()-start)/CLOCKS_PER_SEC, CLOCKS_PER_SEC );
  30 
  31   if( feof( in ) ) {
  32     printf( "%d liczb, wart. srednia=%g, odch. std=%g\n",
  33              n,                      sum/n,        sqrt( n*sum2 - sum*sum )/n
  34     ); 
  35     return 0;
  36   } else {
  37     fprintf( stderr, "%s: smieci w \"%s\" po przeczytaniu %i liczb\n",
  38                      argv[0], (argc > 1 ? argv[1] : "stdin"), n );
  39     return 2;
  40   }
  41 
  42 
  43   return 0;
  44 }

Zaczęliśmy mówić o wskaźnikach:

   1   int i;
   2   double d[100];
   3 
   4   int *pi;    /* wskaźnik na obiekt typu int */
   5   double *pd; /* wskaźnik na obiekt typu double */
   6   char *pc    /* itp, itd */
   7   FILE *in;   /* FILE to "coś" zdefinowane za pomocą #define w stdio.h */
   8 
   9   /* Możliwa inicjalizacja */
  10   pi = &i;     /* za pomocą adresu istniejącej zmiennej */
  11 
  12   pd = d;      /* nazwa tablicy to stała typu wskaźnikowego */
  13   pd = &d[0];  /* dokładnie to samo, co wyżej */
  14   pd = &d[5];  /* pd wskazuje na szósty element d */
  15 
  16   pi = NULL;    /* stała NULL to wskaźnik, który "nie wskazuje na nic" */  
  17 
  18   in = fopen( argv[1], "r" ); /* niektóre f. z biblioteki zwracają wskaźnik */
  19 
  20   /* Dopuszczalne operacje */
  21 
  22   /* - dodanie liczby całkowitej - przesuwa wskaźnik o odpowiednią liczbę
  23        obiektów typu wskazywanego */
  24   pd++;     /* przejscie do następnego obiektu z tablicy d */
  25   pd += 5;  /* przesunięcie pd o 5 obiektów */
  26 
  27   /* - odjęcie liczby calkowitej - przesuwa wskaźnik w tył */
  28   pd -= 1;     /* przejscie do poprzedniego obiektu z tablicy d */
  29 
  30   /* - odejmowanie wskaźników - zwraca liczbę obiektów pom. wskaźnikami +1 */
  31   n = pd - d;   /* na który element d wskazuje wskaźnik pd? */
  32 
  33   /* - dereferencja wskaźnika - pobranie wartości wskazywanej */
  34   i= 5;
  35   pi= &i;
  36   if( *pi == 5 ) /* tak jest! */
  37   ...
  38   *pi += 5;     /* teraz i == 10 */

Przykłady:

   1 #include <stdio.h>
   2 
   3 int
   4 main() 
   5 {
   6   double v[] = { 10, 20, 30, 0.1, 0.2, 0.3 };
   7   double *pv;
   8 
   9   pv= &v[0];
  10   printf( "%g\n", *pv );
  11 
  12   pv= v;
  13   printf( "%g\n", *pv );
  14 
  15   pv++;
  16   printf( "%g\n", *pv );
  17 
  18   pv= v + 4;
  19   printf( "%g\n", *pv );
  20 
  21   printf( "%d\n", pv-v );
  22 
  23   return 0;
  24 }

   1 #include <stdio.h>
   2 
   3 int lenstr( char *str ) {
   4   char *p = str;
   5   while( *str != '\0' ) /* while( *str ) */
   6     str++;                /*      str++;     */
   7 
   8   return str-p;
   9 }
  10 
  11 int 
  12 main( int argc, char *argv[] ) 
  13 {
  14   int i;
  15   for( i= 0; i < argc; i++ )
  16     printf( "Napis %s ma %d znaków\n", argv[i], lenstr( argv[i] ) );
  17 
  18   return 0;
  19 }

Praca domowa:

   1 double sumav( REAL v[], int n )
   2 {
   3   int i;
   4   double suma= 0;
   5   for( i= 0; i < n; i++ )
   6     suma += v[i];
   7 
   8   return suma;
   9 }
  10 
  11 double sumap( REAL *v, int n )
  12 {
  13   double suma= 0;
  14 
  15   while( n-- )
  16     suma += *(v++);
  17 
  18   return suma;
  19 }
  20 
  21 #include <stdio.h>
  22 
  23 int main() {
  24   REAL t[]= { 1, 2, 3, 4, 5, 6, 9, 19, 15.123 };
  25 
  26   printf( "sumav=%g\n", sumav( t, sizeof t / sizeof t[0] ) );
  27 
  28   printf( "sumap=%g\n", sumap( t, sizeof t / sizeof( REAL ) ) );
  29 
  30   return 0;
  31 }

Dlaczego tak jest:

jstar@jstar-lap:~/jimp$ cc -Wall -ansi -pedantic -DREAL=int kartk.c 
jstar@jstar-lap:~/jimp$ 

To znaczy, dlaczego kompilacja powyższego programu z podstawieniem int za REAL nie zwraca ostrzeżenie w linii

   1         REAL t[]= { 1, 2, 3, 4, 5, 6, 9, 19, 15.123 };

2015-09-23 06:44