12.12.01 - RZ User
12.12.01 - RZ User
12.12.01 - RZ User
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
C-Kurs WS 01/02<br />
- 8. Übungszettel -<br />
31. Erstellen Sie eine Funktion mit drei Parametern, alle vom Typ int *.<br />
Die Funktion selber hat keinen Rückgabewert, ist also vom Typ<br />
void. Die Funktion soll die drei Variablen, die über ihre Adressen<br />
übergeben wurden, aufsteigend sortieren. Beispiel:<br />
int a=7, b=-5, c=3;<br />
dreisort(&a, &b, &c);<br />
Nach dem Aufruf von dreisort sollte a=-5, b=3 und c=7 sein. Testen<br />
Sie auch mit anderen Werten für a, b und c.<br />
32. Erweitern Sie die Funktion quagle aus dem Kurs (Programm steht in<br />
http://www.rzuser.uni-heidelberg.de/~x29/C/quagle.c) um einen<br />
Funktionswert vom Typ int mit folgenden Rückgabewerten:<br />
Zusatzaufgabe:<br />
-1: keine Lösung, weil Wurzel aus neg. Zahl<br />
0: keine Lösung, weil Division durch 0<br />
1: Lösungen berechnet und zurückgegeben<br />
Die Aufgabe 33 hat nichts mit Pointern zu tun.<br />
33. „Unser Drogist ist ein Witzbold. Neulich kaufte ich bei ihm vier Gegenstände.<br />
Er schrieb die Preise untereinander und fragte dann:<br />
„Soll ich zusammenzählen oder malnehmen?“ Zum Spaß sagte ich<br />
„malnehmen“, und das tat er dann auch. Zu unserem Erstaunen<br />
kam dabei der gleiche Betrag wie beim Zusammenzählen heraus:<br />
7,11 DM.“ Wieviel haben die einzelnen Gegenstände gekostet?<br />
Achtung: Nächster Termin für Kurs und Übungen: Mi., 9.1.2002<br />
Das C-Kurs-Team wünscht euch allen ein frohes Weihnachtsfest und<br />
einen guten Rutsch ins neue Jahr!<br />
Marcus Hauser, Martin Mohring, Markus Skowronek, Peter Stede<br />
U<strong>RZ</strong> / PS blatt8
* Uebung 28 */<br />
#include <br />
/* Uebung 26 */<br />
#include <br />
void main()<br />
{<br />
char satz[80];<br />
int i;<br />
void main()<br />
{<br />
char wort[80];<br />
int i;<br />
printf("Bitte einen Satz eingeben:\n");<br />
gets(satz);<br />
printf("Bitte Wort eingeben: ");<br />
scanf("%s",wort);<br />
printf("rückwärts: ");<br />
for (i=strlen(wort)-1; i>=0; i=i-1) printf("%c",wort[i]);<br />
printf("\n");<br />
for (i=0;i a.out<br />
Bitte Wort eingeben: Weihnachtsmann<br />
rückwärts: nnamsthcanhieW<br />
aixterm7:/u/fmath/pstede/c><br />
aixterm7:/u/fmath/pstede/c> a.out<br />
Bitte einen Satz eingeben:<br />
C ist blöd<br />
C<br />
ist<br />
blöd<br />
aixterm7:/u/fmath/pstede/c><br />
/* Uebung 27 */<br />
#include <br />
void main()<br />
{<br />
char wort[80];<br />
int i, laenge;<br />
/* Uebung 29 */<br />
#include <br />
printf("Bitte Wort eingeben: ");<br />
scanf("%s",wort);<br />
void main()<br />
{<br />
int i, j;<br />
laenge=strlen(wort);<br />
for (i=0; i<br />
}
aixterm7:/u/fmath/pstede> a.out<br />
32 : 56 : 8 80 : P 104 : h<br />
33 : ! 57 : 9 81 : Q 105 : i<br />
34 : " 58 : : 82 : R 106 : j<br />
35 : # 59 : ; 83 : S 107 : k<br />
36 : $ 60 : < 84 : T 108 : l<br />
37 : % 61 : = 85 : U 109 : m<br />
38 : & 62 : > 86 : V 110 : n<br />
39 : ' 63 : ? 87 : W 111 : o<br />
40 : ( 64 : @ 88 : X 112 : p<br />
41 : ) 65 : A 89 : Y 113 : q<br />
42 : * 66 : B 90 : Z 114 : r<br />
43 : + 67 : C 91 : [ 115 : s<br />
44 : , 68 : D 92 : \ 116 : t<br />
45 : - 69 : E 93 : ] 117 : u<br />
46 : . 70 : F 94 : ^ 118 : v<br />
47 : / 71 : G 95 : _ 119 : w<br />
48 : 0 72 : H 96 : ` 120 : x<br />
49 : 1 73 : I 97 : a 121 : y<br />
50 : 2 74 : J 98 : b 122 : z<br />
51 : 3 75 : K 99 : c 123 : {<br />
52 : 4 76 : L 100 : d 124 : |<br />
53 : 5 77 : M 101 : e 125 : }<br />
54 : 6 78 : N 102 : f 126 : ~<br />
55 : 7 79 : O 103 : g 127 :<br />
aixterm7:/u/fmath/pstede><br />
{<br />
if (text[i]>='A' && text[i]='a' && text[i]a.out<br />
Bitte Text eingeben: Rkvvy, gso qord´c?<br />
Bitte Schluessel eingeben: 10<br />
Verschluesseln (1) oder Entschluesseln (2)? 2<br />
Verschluesselter/Entschluesselter Text:<br />
Hallo, wie geht´s?<br />
aixterm7:/u/fmath/pstede/c>a.out<br />
Bitte Text eingeben: Rkvvy, gso qord´c?<br />
Bitte Schluessel eingeben: 5<br />
Verschluesseln (1) oder Entschluesseln (2)? 2<br />
Verschluesselter/Entschluesselter Text:<br />
Mfqqt, bnj ljmy´x?<br />
aixterm7:/u/fmath/pstede/c>
Anordnung von Variablen im Speicher<br />
(Beispiel):<br />
.......<br />
10478<br />
10479<br />
x 10480<br />
x 10481<br />
10482<br />
10483<br />
10484<br />
10485<br />
y[0] 10486<br />
y[0] 10487<br />
y[1] 10488<br />
y[1] 10489<br />
y[2] 10490<br />
y[2] 10491<br />
‘A‘ 10492<br />
10493<br />
10494<br />
10495<br />
10496<br />
10497<br />
‘H‘ 10498<br />
‘A‘ 10499<br />
‘L‘ 10500<br />
‘L‘ 10501<br />
‘O‘ 10502<br />
‘\0‘ 10503<br />
text[6] 10504<br />
text[7] 10505<br />
text[8] 10506<br />
text[9] 10507<br />
10508<br />
10509<br />
10510<br />
......<br />
int x;<br />
char c=‘A‘;<br />
int y[3];<br />
char text[10]=“Hallo“;<br />
Pointer<br />
- oder Zeiger bzw. Adressvariablen -<br />
Möchte man den Inhalt der Speicherstelle ändern oder<br />
benutzen, auf welche die Pointervariable zeiger zeigt,<br />
so benutzt man den Operator *:<br />
Beispiele:<br />
int *zeiger;<br />
int x=5, y=10;<br />
zeiger=&x;<br />
printf(“%d\n“,*zeiger);<br />
*zeiger=*zeiger+1;<br />
*zeiger++;<br />
++*zeiger;<br />
x=y*(*zeiger);<br />
Aber aufgepasst: Nach<br />
zeiger=zeiger+1;<br />
zeigt zeiger nicht mehr auf die Speicherstelle der Variablen<br />
x. Die Benutzung von *zeiger führt dann zu unbestimmten<br />
Ergebnissen.<br />
U<strong>RZ</strong> / PS ptr2<br />
Pointer<br />
- oder Zeiger bzw. Adressvariablen -<br />
Ein Pointer ist eine Variable, deren Inhalt die Adresse<br />
einer bestimmten Speicherstelle ist. Da diese Speicherstelle<br />
normalerweise der Speicherplatz einer anderen<br />
Variablen ist, ist auch der Pointervariablen ein bestimmter<br />
Datentyp zugeordnet. Beispiel:<br />
U<strong>RZ</strong> / PS ptr1<br />
int *zeiger;<br />
vereinbart eine Variable vom Datentyp Pointer, welche<br />
die Adresse einer int-Variablen aufnehmen kann. Allerdings<br />
hat auch eine Pointervariable direkt nach der Vereinbarung<br />
noch keinen Wert.<br />
● Der Name der Variablen ist „zeiger“, der Datentyp<br />
ist „int *“, d.h. „Zeiger auf eine int-Variable“.<br />
Auch ein Pointer muss vor seiner ersten Benutzung irgendwie<br />
initialisiert werden. Beispiel:<br />
zeiger=&var;<br />
Weist dem Pointer zeiger die Adresse der Variablen<br />
var zu. Ab jetzt zeigt zeiger auf die Variable var.<br />
Weiteres Beispiel:<br />
#include <br />
void main()<br />
{<br />
int x=4711;<br />
int *zeiger;<br />
}<br />
double x[10][20];<br />
double *pointer;<br />
pointer=&x[3][3];<br />
zeiger=&x;<br />
printf("x=%d\n",x);<br />
printf("zeiger=%d\n",zeiger);<br />
printf("*zeiger=%d\n",*zeiger);<br />
aixterm7:/u/fmath/pstede/c> a.out<br />
x=4711<br />
zeiger=804780912<br />
*zeiger=4711<br />
aixterm7:/u/fmath/pstede/c>
#include <br />
void main()<br />
{<br />
int x=4711;<br />
int *zeiger;<br />
}<br />
zeiger=&x;<br />
printf("zeiger=%d\n",zeiger);<br />
zeiger=zeiger+1;<br />
printf("zeiger+1=%d\n",zeiger);<br />
aixterm7:/u/fmath/pstede/c> a.out<br />
zeiger=804780912<br />
zeiger+1=804780916<br />
aixterm7:/u/fmath/pstede/c><br />
U<strong>RZ</strong> / PS arith<br />
Pointer<br />
- Rechnen mit Pointern -<br />
Pointervariablen kann man addieren und subtrahieren.<br />
Dabei ist der Typ der Speicherstelle maßgebend, auf<br />
welchen die Pointervariable zeigt:<br />
int *x, *z;<br />
int y;<br />
x=&y;<br />
x++; oder x=x+1;<br />
Jetzt zeigt x auf die Speicherstelle, welche auf die Variable<br />
y folgt, also 2 Byte (PC) bzw. 4 Byte (AIX) weiter.<br />
Auch möglich z.B. folgende Operationen:<br />
*(x+z);<br />
Inhalt der Speicherstelle, dessen Adresse die Summe<br />
der Zeiger x plus z ist.<br />
Beispiel:<br />
long int x[5][5];<br />
long int *zeiger;<br />
zeiger=&x[2][3]; /* zeiger -> x[2][3] */<br />
zeiger=zeiger+1; ]; /* zeiger -> x[2][4] */<br />
Anordnung von Variablen im Speicher<br />
(Beispiel):<br />
U<strong>RZ</strong> / PS byval<br />
.......<br />
10478<br />
10479<br />
x 10480<br />
x 10481<br />
10482<br />
10483<br />
10484<br />
10485<br />
y[0] 10486<br />
y[0] 10487<br />
y[1] 10488<br />
y[1] 10489<br />
y[2] 10490<br />
y[2] 10491<br />
‘A‘ 10492<br />
10493<br />
zeiger 10494<br />
zeiger 10495<br />
10496<br />
10497<br />
‘H‘ 10498<br />
‘a‘ 10499<br />
‘l‘ 10500<br />
‘l‘ 10501<br />
‘o‘ 10502<br />
‘\0‘ 10503<br />
text[6] 10504<br />
text[7] 10505<br />
text[8] 10506<br />
text[9] 10507<br />
10508<br />
10509<br />
10510<br />
......<br />
int x;<br />
int y[3];<br />
char c=‘A‘;<br />
char text[10]=“Hallo“;<br />
int *zeiger;<br />
...<br />
zeiger=&x;<br />
Funktionsparameter<br />
- „call by value“ -<br />
Parameter an Funktionen (Unterprogramme) werden<br />
grundsätzlich „by value“ übergeben: Der Wert eines<br />
Parameters beim Aufruf wird in den entsprechenden Parameter<br />
des Unterprogrammes kopiert. Das Unterprogramm<br />
kann also keine Variablen des Hauptprogramms<br />
verändern.<br />
Ausgabe:<br />
void main()<br />
{<br />
void up(int);<br />
int a;<br />
a=5;<br />
up(a);<br />
printf(“Hauptprog.: a=%d\n“,a);<br />
}<br />
void up(int x)<br />
{<br />
printf(“Unterprog.: x=%d“,x);<br />
x=-3;<br />
}<br />
Unterprog.: x=5<br />
Hauptprog.: a=5
U<strong>RZ</strong> / PS<br />
Funktionsparameter<br />
- „call by reference“ -<br />
Durch Benutzung eines Pointers als Parameter kann<br />
aber ein „call by reference“ simuliert werden:<br />
• Statt einer Variablen wird deren Adresse als Parameter<br />
übergeben.<br />
• Das Unterprogramm verwendet die Adresse, um dort<br />
den Wert des übergebenen Parameters auszulesen<br />
bzw. zu ändern.<br />
Ausgabe:<br />
void main<br />
{<br />
void up (int *);<br />
int a;<br />
a=5;<br />
up(&a);<br />
printf(“Hauptprog.: a=%d\n“,a);<br />
}<br />
void up(int *x)<br />
{<br />
printf(“Unterprog.: x=%d“,*x);<br />
*x=-3;<br />
}<br />
Unterprog.: x=5<br />
Hauptprog.: a=-3<br />
void main()<br />
{<br />
void tausch(int *, int *);<br />
int x=5, y=-3;<br />
}<br />
printf("Vorher: x=%d, y=%d\n",x,y);<br />
tausch(&x,&y);<br />
printf("Nachher: x=%d, y=%d\n",x,y);<br />
void tausch(int *a, int *b)<br />
{<br />
int zwischen;<br />
}<br />
zwischen=*a;<br />
*a=*b;<br />
*b=zwischen;<br />
aixterm7:/u/fmath/pstede/c> a.out<br />
Vorher: x=5, y=-3<br />
Nachher: x=-3, y=5<br />
aixterm7:/u/fmath/pstede/c><br />
void tausch(int *a, int *b)<br />
{<br />
int zwischen;<br />
}<br />
zwischen=*a;<br />
*a=*b;<br />
*b=zwischen;<br />
void main()<br />
{<br />
int x=5, y=-3;<br />
}<br />
printf("Vorher: x=%d, y=%d\n",x,y);<br />
tausch(&x,&y);<br />
printf("Nachher: x=%d, y=%d\n",x,y);<br />
aixterm7:/u/fmath/pstede/c> a.out<br />
Vorher: x=5, y=-3<br />
Nachher: x=-3, y=5<br />
aixterm7:/u/fmath/pstede/c><br />
#include <br />
#include <br />
void main()<br />
{<br />
int a, b, c;<br />
float x1,x2;<br />
void quagle(int, int, int, float *, float *);<br />
printf("Bitte a,b und c eingeben: ");<br />
scanf("%d %d %d",&a,&b,&c);<br />
quagle(a,b,c, &x1, &x2);<br />
printf("x1=%g, x2=%g\n",x1,x2);<br />
}<br />
void quagle(int c1, int c2, int c3, float *l1, float *l2)<br />
{<br />
float wurzl;<br />
wurzl=sqrt(c2*c2-4*c1*c3);<br />
*l1=(-c2+wurzl)/(2.*c1);<br />
*l2=(-c2-wurzl)/(2.*c1);<br />
}<br />
aixterm7:/u/fmath/pstede/c> a.out<br />
Bitte a,b und c eingeben: 2 1 -1<br />
x1=0.5, x2=-1