int

Werbung
Vorlesung 1
•
•
•
•
C Sprache
Algorithmen
Effektivität von Algorithmen
Programme specifizieren, Algorithmen zu
ausarbeiten, Quelltext generieren,
dokumentieren
Elektrotechnik
• Kleine Klausuren: max. 6 P. (3 * 2P.)
• Laboren(8-13 Wochen): max. 18 P. (6 *
max. 3P.)
• Hausaufgabe: max. 10 P. (Note * 2P.)
• Grosse Klausur : max. 10 P. (Note * 2P.)
• Zusammen: max. 44 P.
Elektrotechnik
38 - 44 P. Note 5
32 - 37 P. Note 4
26 - 31 P. Note 3
20 - 25 P. Note 2
Informatik
• Grosse Klausur: es soll einen Note 2
erreicht werden
• Schriftliche Prüfung im Prüfungsperiod
Informatik labor
• 3 kleine Klausur
• Hausaufgabe
• Durchschnitt + od. - 1
• Vor C:
Multics project—General Electric, MIT, und
Bell Laboratory (1969) (kein Erfolg) – zu
große OP System
Bell Laboratory - Ken Thompson, Dennis
Ritchie, Brian Kernighan – „UNIX”
Ken Thompson – prog. Sprache B
• BCPL und B sind typenlose Sprachen
• C hat eine Reihe von Datentypen
– Zeichen, ganze Zahlen, Gleitpunktzahlen
– Es gibt eine Hierarchie von abgeleitete
Datentypen (mit Hilfe von Zeigern, Vektoren,
Strukturen und Unionen erzeugt)
– Kontrollstrukturen, die für wohlstrukturierte
Programme nötig sind:
– Kontrollstrukturen, die für wohlstrukturierte
Programme nötig sind:
• Zusammenfassung von Anweisungen { }
• Entscheidungen (if-else)
• Auswahl von einem aus einer Menge von
möglichen Fällen (switch)
• Schleifen mit Test des Abbruchkriteriums am
Anfang (while, for)
• oder am Ende (do)
• Vorzeitiges Verlassen einer Schleife (break)
– Funktionen können Werte der elementare
Typen, aber auch von Strukturen, Unionen
oder als Zeigern als Resultat liefern.
– Jede Funktion darf rekursiv aufgerufen
werden
– Die lokalen Variablen einer Funktion sind
typischerweise „automatisch”, das heißt, sie
werden bei jedem Aufruf der Funtion neu
erzeugt werden
– Funktionsdefinitionen können nicht
verschachtelt werden,
– Die Funktionen eines C Programms können
sich in verschiedenen Quelldateien befinden,
die getrennt voneinander übersetzt werden
– Ein Preprozessor ersetzt Makros im
Programmtext, fügt andere Quelldateien ein
und ermöglicht bedingte Übersetzung
– ANSI C standard 1988
– Definition einer Bibliothek, die zu C gehört
• Funktionen zum Zugriff auf das Betriebsystem
(Dateien zu lesen und schreiben)
• Funktionen für formattierte Ein- und Ausgabe
• Funktionen für Speicherverwaltung etc.
#include <stdio.h>
main()
{
printf(”hello, world\n”);
}
#include <stdio.h>
int main()
{
int a,b,c;
int summe;
a = 1; b = 2; c = 3;
summe = a+b+c;
printf(”summe=%d \n”,summe);
return 0;
}
• Arithmetische Operatoren
binäre +, -, /, *, %
unäre +, +, - (unären)
• Vorrang
*, / , %
+, - (binären)
arithmetische Operatoren werden von links
her zusammenfaßt
• Verbindung von arithmetische Operatoren
c = a = d+e;
von rechts her
Datentypen
• 4 elementare Datentypen
char ein Byte, ein Zeichen – Grundelement des
Speichers
int ganzahliger Wert, 16 oder 32 Bits
float ein einfach genauer Gleichpunktwert
double ein doppelt genauer Gleichpunktwert
Varianten dieser elementaren
Typen
• short int
• long int
das Wort int kann ausgelassen werden
short und int haben wenigstens 16 Bits
long hat mindestens 32 Bits
short ist nicht länger als int
int ist nicht länger als long
Varianten dieser elementaren
Typen
• signed
• unsigned
char oder int (sind ≥ 0)
• Wertebereich
int
-32768...32767
unsigned int 0...65535
float
3.4e-38...3.4e+38
double
1.7e-308...1.7e+308
long double
3.4e-4932...1.1e+4932
Konstanten
•
•
•
•
•
•
•
•
ganzzahlige Kostante 1234 hat den Typ int
long-Konstante 12345678l oder 12345678L
vorzeichenlose Kostante 456u oder 456U
5789ul oder 5789UL unsigned long
036 oktal
0x36 oder 0X36 hexadezimal
0XFUL unsigned long mit Dezimalwert 15
Gleitpunktkonstanten 123.4 (enthalten einen
Dezimalpunkt) oder 1e-2 (enthalten einen
Exponenten) sind double
• 113.6f oder 113.6F hat Typ float
• 113.6l oder 113.6L hat Typ long double
Elementare printf Umwandlungen
Zeichen
Argument; Ausgabe als
d,i
int; dezimale Zahl
o
int; oktale Zahl ohne
Vorzeichen
int; hexadezimale Zahl
ohne Vorzeichen
int; dezimale Zahl ohne
Vorzeichen
int; einzelnes Zeichen
x, X
u
c
• %d als dezimale ganze Zahl ausgeben
• %6d als dezimale ganze Zahl ausgeben,
mindestens 6 Zeichen breit
• %f als Gleitpunktzahl ausgeben
• %6f als Gleitpunktzahl ausgeben, mindestens 6
Zeichen breit
• %.2f als Gleitpunktzahl ausgeben, 2 Zeichen hinter
Dezimalpunkt (abgerundete Zahl)
• %6.2f als Gleitpunktzahl ausgeben, 6 Zeichen breit
und 2 Zeichen hinter Dezimalpunkt
• float f = 1.23456789;
• printf("f=%f \n",f);
1.234568
• printf("f=%15f \n",f);
1.234568
• printf("f=%-15f \n",f);
1.234568
• printf("f=%.3f \n",f);
1.235
• float f = 123.23456789;
• printf("f=%f \n",f);
123.234566
• printf("f=%3.3f \n",f);
123.235
• printf("f=%15e \n",f);
1.232346e+002
• printf("f=%15.2e \n",f);
1.23e+002
Elementare printf Umwandlungen
Zeichen
Argument; Ausgabe als
s
char*; aus der
Zeichenkette werden
Zeichen ausgegeben
double; [-]m.dddddd ,
wobei die Genauigkeit
die Anzahl der d festlegt
double; [-]m.dddddde±xx
, wobei die Genauigkeit
die Anzahl der d festlegt
f
e, E
• zeile ist ”hello, world” Zeichenkette
printf(”:%s:”,zeile);
:hello, world:
printf(”:%10s:”,zeile);
:hello, world:
printf(”:%.10s:”,zeile);
:hello, wor:
printf(”:%-15s:”,zeile);
:hello, world :
printf(”:%15.10s:”,zeile);
: hello, wor:
printf(”:%-15.10s:”,zeile);
:hello, wor :
• Vereinbarungen
int i,j,k;
double a,b;
• Eine Variable kann bei ihrer Vereinbarung
auch initialisiert werden
double a = 1.3, b = 2.3;
• Mit dem Attribut const kann bei der
Vereinbarung einer Variablen angegeben
werden, daß sich ihr Wert nicht ändert.
const int a=3;
dann a=a+1; /*ist falsch*/
• Das Komma Operator
mehrere Zuweisungen kann verbindet
werden
int i,j,k;
i = 3; j = 4;
k = i, i = j;
die Auswertung geht von links her
Mathematische Bibliothekfunktionen
• in <math.h> deklariert
abs int abs(int)
acos
double acos(double)
asin, atan,
atan2 double atan2(double,double)
atof, string to a floating point
double atof(const char*)
cabs,
ceil(x), kleinster ganzzahliger Wert, der nicht kleiner als x ist
cos, cosh,
exp,
fabs,
floor(x), größter ganzzahliger Wert, der nicht größer als x ist
log, log10,
pow,
sin, sinh,
sqrt,
tan, tanh
long a;
float f = 123.9;
a=f;
printf("a=%ld \n",a);
a=123
long a;
float f = 123.9;
f=f-(a=f);
printf("a=%ld \n",a);
printf("f=%15.2e \n",f);
a=123
f=
9.00e+002
Schleifen
• for Schleife
• while Schleife
while (Ausdruck) Anweisungen
• do while Schleife
do Anweisungen
while (Ausdruck);
do while Schleife
do Anweisungen
while (Ausdruck);
Anweisung(en)
Ausdruck ≠ 0
Ausdruck
Ausdruck = 0
Anweisungen werden durchgeführt bis
Ausdruck bleibt von 0 verschieden
j = 0; i = 4;
do {
j = j+i;
i = i-1;
}
while (i>0);
j = 0; i = 4;
do {
j = j+i;
i = i-1;
}
while (i);
j = 0; i = 4;
do
j = j+i;
while (i = i-1);
while Schleife
while (Ausdruck)
Anweisungen
Ausdruck
Ausdruck ≠ 0
Anweisung(en)
Ausdruck = 0
Ist Ausdruck von 0 verschieden, so wird
Anweisung ausgeführt und anshließend
Ausdruck erneut bewertet
i = 10; sum = 0;
while (i>0) { sum=sum+i;i= i-1};
i = 10; sum = 0;
while (i) { sum=sum+i;i= i-1};
for Schleife
for (init;test;post-expr)
statement;
if else Anweisung
if (Ausdruck)
Anweisung1
else
Anweisung2
Ausdruck ≠ 0
Ausdruck = 0
Ausdruck
Anweisung1
Anweisung2
Ausdruck hat einen von 0 verschiedenen
Wert, so wird Anweisung 1 ausgeführt. Bei 0
wird Anweisung 2 ausgeführt.
Inkrement- und DekrementOperatoren
• Der Inkrement-Operator ++ (addiert 1 zu
seinem Operanden)
• Der Dekrement-Operator -- (substrahiert 1)
• Präfix-Notation ++n
• Postfix-Notation n++
n = 5;
n = 5;
x = n++; /* x ist 5, n ist 6 */
x = ++n; /* x ist 6, n ist 6 */
b
a
b

a
N
f ( x)dx   f (a  (i  1)  )  
i 1
  b  a  / N
#include <stdio.h>
#include <math.h>
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
del = (b-a)/N;
sum = 0.0;
for(i=1;i<=N;i=i+1)
{
x = a+del*(i-1);
f = sin(x);
sum = sum + f;
}
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0;
}
Bedingter Ausdruck
if (a>b)
z = a;
else
z = b;
z = (a>b)?a:b;
Auch in Form
Ausd1?Ausd2:Ausd3
Zuweisungen und Ausdrücke
i = i+2;
Ausdruck
mit Zuweisungsoperator ( +=)
i += 2;
(+, -, *, /, %, <<, >>, &, |, ^)
#include <stdio.h>
#include <math.h>
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
del = (b-a)/N;
sum = 0.0;
for(i=1;i<=N;i+=1)
{
x = a+del*(i-1);
f = sin(x);
sum += f;
}
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0;
}
Operatoren
• Vergleichsoperatoren
== prüft auf Gleicheit ( a == b )
!= prüft auf Ungleicheit ( a != b )
>, >=, <, <=
• Verknüpfungen
&& AND (und-Verknüpfung)
|| OR (oder-Verknüpfung)
! NOT (Komplement; unär)
Beispiel
(a == b) && (c == d) || !(c == e)
#include <stdio.h>
int main()
{
int z1,nprim,i;
z1=23;
i=z1/2;
nprim=0;
while ((i>=2)&&(!nprim))
{
if (z1%i==0) nprim=1;
i--;
}
if (nprim) printf("Nicht Prim \n");
else printf("Prim \n");
return 1;}
Die switch Anweisung
Es ist eine Auswahl unter mehreren Alternativen
Untersucht, ob ein Ausdruck einen von mehreren
Konstanten ganzzahligen Werten besitzt.
switch(Ausdruck){
case const-Ausdruck1:Anweisung1
case const-Ausdruck2:Anweisung2
default : Anweisung3
}
i = 2;
switch(i){
case 1: printf(”Montag”);break;
case 2: printf(”Dienstag”);break;
case 3: printf(”Mittwoch”);break;
case 4: printf(”Donnerstag”);break;
case 5: printf(”Freitag”);break;
case 6: printf(”Sammstag”);break;
case 7: printf(”Sonntag”);break;
default : printf(”Fehler”);
}
Operatoren
• Bit-Operatoren
& Bit-AND
| Bit-OR
^ Bit-XOR
~ Bit NOT
>> Bitshift nach Rechts
<< Bitshift nach Links
int i = 8;
i = i >> 2; /* Dividierung mit 4 */
i= i << 2; /* Multiplizierung mit 4 */
Funktionen und Programmstruktur
Funktionsdefinition
Funktionstyp Funktionsname(Parameterdeklarationen)
{
Vereinbarungen und Anweisungen
return Ausdruck
}
return-Anweisung liefert einen Wert als Resultat von
der aufgerufenen Funktion zum Aufrufen
double addiert(double a, double b)
{
return a+b;
}
void ausschreibt(double a)
{
printf(”%lf ”,a);
} /*Funktion ohne Ausgangswert*/
#include <stdio.h>
#include <math.h>
double fv(double x)
{
return sin(x);
}
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
del = (b-a)/N;
sum = 0.0;
for(i=1;i<=N;i+=1)
{
x = a+del*(i-1);
f = fv(x);
sum += f;
}
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0;
}
#include <stdio.h>
#include <math.h>
double fv(double x)
{
return sin(x);
}
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
del = (b-a)/N;
sum = 0.0;
for(i=1;i<=N;i+=1)
sum += fv(a+del*(i-1));
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0; }
#include <stdio.h>
#include <math.h>
double fv(double x)
{
return sin(x);
}
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
del = (b-a)/N;
sum = 0.0;
for(i=1;i<=N;)
sum += fv(a+del*(i++-1));
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0; }
#include <stdio.h>
#include <math.h>
double fv(double x)
{
return sin(x);
}
int main()
{
int i,N=10;
double a=1,b=2,del,x,sum,f,integral;
for(i=1,sum=0.0,del = (b-a)/N;i<=N;sum += fv(a+del*(i++-1)))
;
integral = sum*del;
printf("Integral = %lf\n",integral);
printf("Integral = %lf\n",-cos(b)+cos(a));
return 0;
}
Zeiger und Vektoren
Ein Zeiger ist eine Variable, die die Adresse einer
Variablen enthält.
& unäre Adress-Operator
* Inhalts-Operator (indirection, dereferencing)
int x = 1, y = 2;
int *ip;
ip = &x;
y = *ip;
*ip = 0;
Zeiger und Vektoren
Die Vereinbarung
int a[10];
double v[25];
definiert einen Vektor mit 10 (25) Elementen,
einen Block aus 10 (25)
aufeinanderfolgenden Objekten, mit den
Namen
a[0] a[1] ... a[9]
Zeiger und Vektoren
Vereinbart man pa als Zeiger auf einen int
Wert
int *pa;
dann zeigt pa durch die Zuweisung
pa = &a[0];
auf das erste Element 0 von a; pa enthält die
Adresse von a[0]
Zeiger und Vektoren
pa + 1 ist eine Zeiger auf das nachfolgende
Element
pa + i ist eine Zeiger auf das i-te Element
nach (hinter) pa
Statt a[i] auch *(a+i) geschrieben werden
kann
pa = &a[0]; equivalent mit pa = a;
Zeigern als Funktionsargumente
void tausch(int *px,int *py)
{ int temp;
temp = *px;
*px = *py;
*py = temp;
}
in main() Funktion
tausch(&a,&b);
Zeigern als Funktionsargumente
• Auswahl maximaler Element
#include <stdio.h>
#include <stdlib.h>
int max(int *v,int g){
int maxwert = 0;
if(g){ maxwert = v[0];
while(--g)
if (v[g]>maxwert) maxwert =
v[g];
}
return maxwert;
}
int main()
{
int vekt[10],i;
for (i=0;i<10;i++){
vekt[i] = rand();
}
printf("%d \n",max(vekt,10));
return 0;
}
Char Zeiger
”konstante Zeichenkette”
das ist ein Zeichenvektor
der Vektor wird mit dem Nullzeichen ‘\0’ beendet
char *Zeichenzeiger;
Zeichenzeiger = ”Hallo”;
char Zeichenpuffer[] = ”Hallo”;
Zeichenzeiger:
·
Zeichenzeiger:
·
Zeichenpuffer:
H a l l o \0
H a l l o \0
Char Zeiger
int strlen(char *c)
{int n;
for(n = 0;*s!=‘\0’;s++) n++;
return n;
}
int main(){
printf(”%d”,strlen(”Guten Tag”);
Char Zeiger
int strlen(char *c)
{int n;
for(n = 0;*s!=‘\0’;s++) n++;
return n;
}
int main(){
char *Zeichenzeiger;
Zeichenzeiger = ”Hallo”;
char Zeichenpuffer[] = ”Hallo”;
strlen(Zeichenpuffer);
strlen(&Zeichenpuffer[]);
strlen(Zeichenzeiger);
strlen(Zeichenzeiger+2);
strlen(Zeichenpuffer+2);
void strcpy(char *s,char *t)
{int i = 0;
while (t[i]!=‘\0’) {s[i]=t[i];i++;}
s[i]=t[i];
}
void strcpy(char *s,char *t)
{int i = 0;
while ((s[i]=t[i])!=‘\0’) i++;
}
Type-Aliases (typedef)
Mit typedef kann man ein Alias für einen
existierenden Typ deklarieren:
typedef existing-type new-type;
Beispiele:
typedef int INTEGER;
typedef int bool;
typedef unsigned int uint;
Präzedenz und Bindung
Englisch: „precedence” und „ associativity”
(„grouping”)
Ohne diese ist ein Ausdruck der Art
a+b*c
nicht eindeutig
Präzedenz: Reihenfolge der Auswertung der
Operatoren
Assoziativität: Reihenfolge bei Operatoren gleicher
Präzedenz
C preprozessor
# include Definitionsdatei einfügen
#include <filename>
#include „filename”
#define Textersatz
Ersatztext
#define Name Ersatztext
#define sqr(x) x*x
a = 2;
c = sqr(a);
→ c = a*a;
/* c wird 4 sein */
Ersatztext
#define sqr(x) x*x
a = 2; b = 3;
c = sqr(a+b);
→ c = a+b*a+b;
/* c wird 2+3*2+3=11 sein */
#define sqr(x) (x)*(x)
c = sqr(a+b);
→
c = (a+b)*(a+b);
Ersatztext
#define sqr(x) (x)*(x)
a = 1; b = 2;
c = 9/sqr(a+b);
→ c = 9/(a+b)*(a+b);
/* c wird 9/3*3=9 sein */
#define sqr(x) ((x)*(x))
Ersatztext
#define ab(x) (x<0)?(-x):(x)
#define max(a,b) (a)>(b)?(a):(b)
Strukturen
• eine Ansammlung von einer oder mehrerer
Variablen (auch mit verschiedenen Typen)
• unter einem einzigen Namen
zusammenfassen
struct point {
double x;
double y;
};
Strukturen
•das reservierte Wort struct steht am Anfang
•Strukturvereinbarung – Liste von Deklarationen
•Etikett – hier point
•Etikett ist für Abkürzung für den Teil der
Vereinbarung in geschweiften Klammern
Strukturen
struct point pt;
•deklaration eine Variable pt, die eine Struktur
vom Typ struct point ist.
•Initialisieren von Strukturen
struct point pt1 = {100,200};
Strukturen
•Verweis auf eine Komponente einer bestimmten
Struktur
Struktur-Variablenname.Komponente
struct point pt;
pt.x = 150.5;
Rekursion
#include <stdio.h>
void printzahl(int zahl)
{
if (zahl<0){ putchar('-'); zahl = -zahl;
if (zahl/2) printzahl(zahl/2);
putchar(zahl % 2 +'0');
}
int main()
{ int i = 32;
printzahl(i);
printf("\n");
return 0;
}
}
Argumente aus der Kommandozeile
• Wenn main aufgerufen wird, werden zwei
Argumente Übergeben
• argc für argument count
• argv für argument vector
argv[0] der Programmname
argv[1] das erste Argument
argv[argc-1] das letzte Argument
hat argc den Wert 1, gibt es keine Argumente auf
der Kommandozeile
#include <stdio.h>
int main(int argc,char *argv[])
{ int i,j;
for (i=1;i<argc;i++)
{
j=0;
while(argv[i][j])putchar(argv[i][j++]+'A'-'a');
}
return 0;
}
Herunterladen