/* Schwerpunkt             Funktionen, call by reference                   16 */
/*----------------------------------------------------------------------------*/
/*                            () = Funktionsoperator,
Wertparameter sind immer Kopien der übergebenen Argumente, d.h. call by value,
Wertänderungen betreffen dann nur die Kopien.
Variablen- oder Referenzparameter werden durch Adressübergabe mit Zeigern oder
Referenzen möglich, denn dann wird die Adresse kopiert und damit kann der Inhalt
auch für das aufrufende Programm geändert werden, d.h. call by reference.
Die Deklaration von Funktionen kann vor oder auch nach main erfolgen, extern
gespeicherte Funktionen können mit #include <pfad.name> eingefügt werden.
Parameter in der Deklaration sind immer Platzhalter und werden beim Aufruf der
Funktion durch die jeweiligen aktuellen Parameter ersetzt.
------------------------------------------------------------------------------*/
/* Zeiger (Pointer) auf Variablen oder Feldelemente sind Adressen und werden
durch den Indirektoperator * bezeichnet. Ein Feldname ohne Index ist ein Zeiger,
der die Anfangsadresse des Feldes angibt.
Der Zugriff auf Feldelemente durch Zeiger ist schneller als der Zugriff über
Feldname und Index.
Zeiger sind unverzichtbar bei dynamischer Speicherplatzbelegung, bei der Verein-
barung von Dateien und der Parameterübergabe an Funktionen durch
call by reference.
----------------------------------------------------------------------------- */
/* Klausuraufgabe Feb. 2002: Berechnen Sie den Schwerpunkt eines Systems von n
Punkten (n<=500) in der Ebene, ohne Strukturen zu verwenden und mit Hilfe einer
Funktion für das EINLESEN der Koordinaten eines(!) Punktes und einer für das
BERECHNEN der Schwerpunktkoordinaten. Die Funktionen dürfen nicht mit globalen
Variablen arbeiten! Hinweis: xs= (x1+x2+...+xn)/n           ys= (y1+y2+...+yn)/n
----------------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
void einlesen( float* x, float* y)
{  printf(" Koordinaten: "); scanf("%f %f", x, y);
}
void berechnen(float *x, float y[], int n, float* xx, float* yy) /*geht beides*/
{   int i; *xx= *yy= 0;               /* float* xx heißt, xx ist eine Adresse */
                                      /*      xx* heißt Inhalt der Adresse xx */
    for( i=0; i<n; i++)
             { *xx = *xx + x[i];    *yy = *yy + y[i];  }
    if( n>0) { *xx = *xx/n;         *yy = *yy/n;       }
}
/* noch mehr Zeiger, bzw. nur Zeiger geht auch: ------------------------------*/
void berechnen_z(float* x, float* y, int n, float* xx, float* yy)
{ int i;  *xx= *yy= 0;
    for( i=0; i<n; i++) { *xx = *xx + *x;    *yy = *yy + *y;  x++; y++; }
    if( n>0)                { *xx = *xx/n;       *yy = *yy/n;               }
}
int main()
{ int i, n; float xp[500], yp[500], xs, ys;

   float* xk; float* yk;  xk= xp; yk= yp;
  printf("\n Anzahl der Punkte: ");        scanf("%i", &n);    if(n>500) n=500;

  for( i=0; i<n; i++) einlesen( &xp[i], &yp[i] );

  berechnen( xp, yp, n, &xs, &ys);    printf("%.1f %.1f\n", xs, ys);

  /* oder mit noch mehr Zeigern*/



  for( i=0; i<n; i++) { einlesen( xk, yk ); xk++; yk++; }

  berechnen_z( xp, yp, n, &xs, &ys);    printf("%.1f %.1f\n", xs, ys);

  system("PAUSE"); return 0;
} /*--------------------------------------------------------------------------*/
