C Referenz
1. Datentypen, Operatoren
und Ausdrücke. 2
a. Low-Byte / High-Byte. 2
b. typedef. 2
c. Konstanten. 2
d. Aufzählungskonstanten. 2
e. Variablenvereinbarung. 2
f. Typkonvertierungen. 3
i. Implizite Typkonvertierung. 3
ii. Explizite Typkonvertierung. 4
g. Arithmetische Operatoren. 4
h. Vergleichsoperatoren. 4
i. Zuweisungsoperatoren. 4
j. Logische Operatoren. 4
k. Operatoren zu Bit- Manipulation. 5
l. Sonstige Operatoren. 5
2. Ein- und Ausgabe. 5
a. Funktion scanf. 5
b. Funktion printf. 5
3. Kontrollstrukturen. 6
a. if - / if – else – Anweisung. 6
b. 4.2 switch-Anweisung. 6
c. for-Anweisung: 6
d. while- und do-Anweisung. 7
e. continue- und break-Anweisung. 7
4. Funktionen. 8
a. Funktionsdeklaration und Funktionsdefinition. 8
b. Übergabe von Argumenten und Rückgabewerten. 8
c. Gültigkeitsbereich und Lebensdauer von
Variablen. 9
5. Pointers und Vektoren. 10
a. Pointers. 10
b. Argument – Übergabe an Funktionen. 11
c. Vektoren. 11
d. Zusammenhang zwischen Pointer und Vektor. 11
e. Pointer-Arithmetik. 12
6. Strukturen Datentypen. 13
7. Unions. 14
a. Bit-Felder. 14
1.
Datentypen, Operatoren und Ausdrücke
a. Low-Byte
/ High-Byte
Speicherplatz im Arbeitsspeicher zB. 0x12345678
Little endian byte ordering: low-byte=12 & high-byte=78
Big endian byte ordering: low-byte=78 & high-byte=12
b.
typedef
type_def.h
/*** Definition of global types ***/
typedef unsigned char U_INT8;
…
programm.c
#include >type_def.h>
main()
{
U_INT8 variable1, …, variablen;
}
c.
Konstanten
84U à unsigned int 84
84 L à long ing 84
84 UL à unsigned long int 84
1.475e-3F à float
‘A’ à vom typ int (Wert anhand der ASCII Tabelle)
printf(“\”abc\””); à //“abc”
d.
Aufzählungskonstanten
typedef
enum {OFF, ON} KEY; // OFF=0 und ON=1
e.
Variablenvereinbarung
#define MAX_VAL 300 // präprozessoranweisung
const unsigned char test=2; //Wert nach initialisierung
nicht änderbar
volatile unsigned char test=2; // variable bleibt unbeachtet in
Compileroptimierung
f.
Typkonvertierungen
-bei Verknüpfung von Operanden mit unterschiedlichem Datentyp,
ist Datentyp-Umwandlung erforderlich.
i.
Implizite Typkonvertierung
Compiler nimmt automatisch Typkonvertierung vor.
o
für einen Ausdruck gilt u.a.:
-
ist ein Operand long double, werden andere Operanden in long double
konvertiert
-
ist ein Operand double, werden andere Operanden in double
konvertiert
- ist ein Operand float, werden andere
Operanden in float konvertiert
- Operand vom Typ char u. short
werden in int konvertiert
- ist ein Operand long, werden andere
Operanden in long konvertiert
- ist ein Operand unsigned int, werden
andere Operanden in undsigned int konvertiert
o
Beachte:
·
float-Op. Werden nicht automatisch in Typ double
konvertiert
·
Zuweisungen: Wert auf rechter Seite wird in Typ linker
Seite konvertiert
Ø Integrer –
Erweiterung
o Konvertierung
char, short int in int, wenn int zur Wertaufnahme
ausreicht, sonst in unsigned int
o C definiert nicht,
ob char- Variable Vorzeichen besitzen à
Konvertierung char-Variable in int-Variable maschinenabhängig z.B.:
char val1 = 0x84;
short int val3;
val3 = val1; // val3=0x0084 oder val3=0xFF84
o eindeutige int-Konvert.:
unsigned char val1 = 0x84;
signed char val2 = 0x84;
short int val3;
val3=val1; // val3=0x0084
val3=val2; // val3=0xFF84
ii.
Explizite Typkonvertierung
o Anweisung
Typumwandlung eines Ausdrucks mittels cast-Operator:
(type_name) expression …
o Typumwandlung
des Wertes von eypression in Typ type_name entsprechender
Typkonvertierungsregeln z.B.:
Bibliotheksfkt. sqrt ( n ) mit n vom Typ double
#include <math.h>
unsigned int m_val;
double result;
result = sqrt ((double) m_val);
o bei Zugriff auf
Absolutadressen ist expl. Typkonvertierung erforderlich
o Beachte:
-int-Werte mit „gr. Bereich“ werden in int-Werte mit „kl. Bereich“ konvertiert,
durch Abschneiden überzähliger Bits von links her
-bei Typumwandlung float in int wird Bruchteil abgeschnitten
- Typkonvertierung double in float ist implementationsabhängig.
g.
Arithmetische Operatoren
% Modulo-Division //
8 % 3 à =2
o Bei division
von int-Werten wird gebrochener teil Abgeschnitten
o Auf float- u.-
double-Werten %-Op, nicht anwendbar
h.
Vergleichsoperatoren
o
numer. Wert vergleichsoperation:
1: Vergleich trifft zu (true)
0: Vergleich trifft nicht zu (false)
i.
Zuweisungsoperatoren
o expr2 op = expr2 // Äquival.: expr1 = (expr1) op
(expr2)
j.
Logische Operatoren
o && log.
UND
o || log.
ODER
o ! log.
Negation
Negationsoperator ! besitzt Wert:
1 wenn Operand = 0
0 wenn Operand ≠ 0
Test auf ungleich 0 à If (x) statt
if (x!= 0)
Test auf 0 à
If (!x) statt if (x== 0)
if((val1>val2)&&(val3++<val4)) à gefährlich!
Auswertung von links nach rechts, abgebrochen, sobald Resultat feststeht
!!!
k.
Operatoren zu Bit- Manipulation
o
Bit-.Operatoren:
& UND
| ODER
^ Exklusiv – ODER
<< Shift left inbyte <<=0x03 à 3 NULL-Bits von rechts
>> Shift right outbyte >>=0x03 à 3 NULL Bits von links (unsigned)
à Vorzeichen Bit oder NULL Bit bei
(signed)
~ Bit – Komplement
l.
Sonstige Operatoren
o konditionaler
Operator ?:
- Max_temp=(temp1>temp2) ? temp1:temp2;
expr1 ≠ 0: condition true à Berechnung expr2
expr1 = 0: condition false à Berechnung
expr3
àResultatwert ist Wert des ermitt.
Ausdrucks
o Operator sizeof
length=sizeof array;
length=sizeof(long double); à liefert Anzahl an Bytes zur Speicherung
2.
Ein- und Ausgabe
scanf Lesen von Zeichen aus
Standard-Eingabe
fscanf Lesen von Zeichen aus
einer Datei
getchar Lesen eines Zeichens aus
Standard-Eingabe
printf Ausgabe von
Zeichen auf Standard-Ausgabe
fprintf Ausgabe von Zeichen in
Datei
putchar Ausgabe eines Zeichens auf
Standard-Ausgabe
Voraussetzung für Verwendung E/A-Funktionen: #include
<stdio.h>
a.
Funktion scanf
Scanf(“formatangaben“ , &arg1 , &arg2,…);
Scanf(“%d %f %c %x”, &wert, &var,
&zei, &addr); à %d
gehört zu &wert, %c gehört zu &zei …
b.
Funktion printf
Printf(“formatangaben“, arg1, arg2,
…);Ausgabe Text u. Daten:
z.B.: printf(“Spannung u1: %fV“, u_1);
3.
Kontrollstrukturen
a.
if - / if – else – Anweisung
o
allg. Form:
if (expression)
{
statement_1;
next_statement;
}
else
statement_2;
o ohne {} immer
nur für einen Anweisungsblock gültig
b.
4.2 switch-Anweisung
o allg. Form
switch (expression) switch(x)
{ {
case const_1: statement; case 5: y = 1000;
case const_2: statement; …
…
case const_n: statement;
default: statement;
}
next statement;
o es gilt
-Wert von expression: int-Typ
-const_i: ganzz. Konstante, konst. Ausdruck
-default ist optional
-mehrere case-Konstanten vor einem statement
-switch-Anw. können verschachtelt werden
-break; Verlassen switch-Anweisung
c.
for-Anweisung:
o allg. Form:
for(expr1; expr2; expr3;)
{
statements;
}
expr1 einmal bewertet
expr2 vor jeder Wiederholung berechnet:
-Wert ungleich Null (true); à Ausführung
statement
-Wert gleich Null (false): à Beenden
for-Anw.
-expr3 nach jeder Wiederholung bewertet
d.
while- und do-Anweisung
o allg. Form:
while (expression)
{
statements;
}
do
{
statements;
}
while (expression);
o statement wird
solange ausgeführt, solange Wert von expression ungleich Null (true)
e.
continue- und break-Anweisung
Ø continue
o beendet
innerhalb for-, while-, do-Anw. akt. Schleifendurchlauf u. verzweigt zum
nächsten Durchlauf
o allg. Form:
Ø break
o beendet for-,
while-, do-, switch-Anw. vorzeitig u. verzweigt zu next_statement
o -allg. Form:
4.
Funktionen
a.
Funktionsdeklaration und Funktionsdefinition
o allg. Form:
Typ Rückgabewert (optional) à void
ohne return value
Typ u. Parametername (optional) à void
ohne parameter
o Beispiel:
Aufbau C-Programm:
#include < . . . >
#define . . .
/* Funktionsdekl. */
void int_ports (void);
unsigned short int read_sensors (char val1, char val2, unsigned char3);
/* Funktion main */
void main(void)
{
char count1, count2;
unsigned char count3;
unsigned short int act_pos;
act_pos = read_sensors (count1, count2, count3); /*
Funktionsaufruf /*
act_pos = int_ports ();
}
/* Funktionsdef. */
void int_ports (void)
{
Anweisungen
}
unsigned short int read_sensors (char val1, char val2, unsigned char val3)
{
Anweisungen
}
b.
Übergabe von Argumenten und Rückgabewerten
o Call by value:
Argument-Übergabe erfolgt als Wert
o Return-Anweisung:
return (expression); à return
(variable);
Rückgabe Wert von expression an aufrufende Funktion.
o - ggf.
Typkonvert. in Resultattyp Fkt.
- fehlt expression: Rückkehr ohne return value
- aufrufende Fkt. kann return value ignorieren
- jede Fkt. besitzt max. eine return-Anweisung
- aufgerufene Fkt. erhällt nicht ursprüngliche Argumente, sondern lokale Kopien
c.
Gültigkeitsbereich und Lebensdauer von Variablen
o lokale
Variable:
- wird nach Blockanfang def. und gilt bis Blockende
- aktueller Wert geht von einem Funktionsaufruf zum nächsten verloren
o globale
Variable: à z.B.: unsigend
short int global_control;
- wird außerhalb aller Funktionen eines Moduls def.
- gilt bis zum Modul-Ende
- akt. Wert bleibt bis zur nächsten Zuweisung erhalten
o externe Variable u. externe Funktion:
-Variable oder Funktion kann modulübergreifend verwendet werden, wenn sie im
Modul x außerhalb von allen Funktionen definiert u. im Modul y mittels extern
deklariert werden.
- ext. Variable ist immer verfügbar
- extern-Dekl. von Variablen u. Funktionen oft innerh. Include
file
Modul 1
extern void read_frequ(void);
extern unsigned char counter;
double max_frequ = 0;
void main(void)
{
…
read_frequ();
…
if ( max_frequ >= …)
…
if (counter == …)
…
}
Modul 2
extern double max_frequ;
unsigned char counter = 1;
void read_frequ(void)
{
…
max_frequ = …
counter = …
…
}
o Static-Variable
u. static-Funktion:
- Gültigkeitsbereich auf Block beschränkt, in dem Variable def. wurde
- Lebensdauer bleibt über gesamten Programmablauf erhalten
void write_lcd (…)
{
static unsigned short int cursor_pos = 0;
…
cursor_pos = …
…
}
o Static globale
Variable u. Funktion:
- Gültigkeitsbereich auf Modul beschränkt, in dem Variable bzw. Funktion def.
wurde
- Lebensdauer von Variablen bleiben über gesamten Programmablauf erhalten
- wird außerhalb der Funktion deklariert
5.
Pointers und Vektoren
a.
Pointers
o unsigned char
*byte_ptr;
- Pointer zeigt nur auf den in Def. festgelegten Datentyp
o Adress-Operator:
&
float &act_temp ; // erste Adresse der
float variable wird angezeigt
(float 4 bytes
groß)
unsigned &char out_byte; // Adresse der char variable
wird angezeigt
liefert in Verbindung mit einem
Variablennamen die Adresse der Variablen
o inhalts-Operator:
*
liefert angewandt auf einen Pointer, das Objekt auf das der Pointer zeigt
(Wert der Variable wird angezeigt, auf die der Pointer zeigt)
*byte_ptr; // initialisierung
des pointers byte_ptr (4 bytes groß)
unsigned char byte1 = 21; // initialisierung der variable byte1
byte_ptr = &byte1; // Adresse von byte1 wird in
byte_ptr geschrieben
byte_ptr*; // Inhalt von Variable byte1 wird
angezeigt
b.
Argument – Übergabe an Funktionen
o Call by reference
void swap (unsigned char *byte_p1, unsigned char
*byte_p2);
main()
{
unsigned char high_byte, low_byte;
swap (&high_byte, &low_byte); /*byte swap*/
}
void swap (unsigned char *byte_p1, unsigned char *byte_p2)
{
unsigned char temp;
temp = *byte_p1;
*byte_p1 = *byte_p2;
*byte_p2 = temp;
}
- korrekter Tausch von high_byte,
low_byte in main
-wird Name eines Vektors als Argument an Fkt. übergeben, erhält Fkt. Adresse des Vektors
c.
Vektoren
o allg. Form: à typ vektor_name
[elemente_anzahl];
unsigned char buffer[40]; //Vektor besitzt 40 Elemente
buffer[0]-buffer[39]
unsigned char message [] = “HELLO“; // Vektor besitzt
länge 5
double temp[400] = {10.0, 20.0}; // rest wird
mit NULL aufgefüllt
unsigned char *message_p = “hello tom“; // Pointer zeigt auf die Adresse
des Strings
mit dem Inhalt “Hello Tom“
*(message_p+7) = ‘i‘; // *(&message[7])
= i;
unsigned int position[3][2] = {{3,2},{5,7},{6,3}}; // 2 Spalten, 3
Zeilen
out_ptr=error_p[2]
d.
Zusammenhang zwischen Pointer und Vektor
buff_ptr=&buffer[0]; //
1 Adresse vom Vektor buffer wird in buff_ptr geschrieben
buff_ptr=&buffer[3]; // 4 Adresse vom Vektor buffer wird in buff_ptr
geschrieben
buff_ptr=buffer;
buff_ptr=buffer+3; // gleicher aber besserer code als oben
value=buffer[3]; // Inhalt vom Vektor buffer wird in value geschrieben
value=*(buffer+3); // gleicher code (erst Klammer dann
Inhaltsoperator)
e.
Pointer-Arithmetik
a) Zuweisung auf Pointer
-Pinter kann mit Pointer gleichen
Typs oder mit ganzz. Ausdruck initial. warden
unsigned char *count_p1, **count_pp; //**
Pointer der auf Pointer zeigt
port1_p = (unsigned char *) 0x00F00000;
count_pp = &count_p1; //count_pp erhält Adresse auf die
count_p1 zeigt
++**count_pp; // ++(*(*count_pp))
b)
Addition, Subtraktion int-Wert zu Pointer
-zu Pointer kann int-Wert
addiert/subtrahiert werden
number = *++rec_p; //Adresse um 1 erhöht und
dann Wert zugewiesen
number = *(rec_p+2); // Adresse um 2 erhöht und dann Wert
zugewiesen
c.) Subtraktion von Pointers
-Pointers können voneinander
subtrahiert werden, wenn sie auf Elemtente des gleichen Vektors zeigen.
unsigend short int buffer[1000], *start_p, *end_p;
start_p = buffer; //Adresse von buffer wird start_p zugewiesen
end_p = buffer; //Adresse von buffer wird end_p zugewiesen
length = end_p – start_p + 1;
d.) Vergleich von Pointers
-Pointers können miteinander
verglichen warden, wenn sie auf Elemtente des gleichen Vektors zeigen
unsigend short int i, j, *start_p, *end_p,
out_buff[2000];
start_p = out_buff + i;
end_p = out_buff + j;
if (start_p > end_p )
{ /*error handling */ }
6.
Strukturen Datentypen
o Struktur:
Zusammenfassung von Variablen unterscheidl. oder gleichen Typs unter gemeinsamen.
Namen
typdef struct
{
unsigend char day;
unsigend char info [3];
} MESSAGE_STRUCT;
MESSAGE_STRUCT short_message;
short_message.day = 5;
short_message.info[ 0 ] = `M`;
//oder
MESSAGE_STRUCT short_message = {20, “abc”};
o - Struktur kann andere Struktur als Komponente enthalten
typedef struct
{
MESSAGE_STRUCT time;
float startTemp;
float endTemp;
} TEMP_MEAS;
TEMP_MEAS motorTemp;
meas_hour = motorTemp.time.day;
o Vektoren von Strukturen
typedef struct
{
unsigned short int nr;
unsigned char art[4];
} MESS_STRUCT;
MESS_STRUCT messung[20];
o Struktur kann
anderer Struktur zugewiesen werden, wenn diese vom Gleichen Typ ist
MESS_STRUCT mess1, mess2;
mess2 = mess1;
o Pointers auf
Strukturen
- für Pointers auf Strukturen
gilt Pointer-Arithmetik
unsigned short int mess_nummer;
MESS_STRUCT *messung_p;
messung_p=&mess_1;
mess_nummer=(*messung_p).nr;
vereinfachte Schreibweise für
Zugriff auf Strukturkomponenten mittels Pointer
messung_p=&mess_1;
mess_nummer=(*messung_p).nr;
mess_nummer= messing_p -> nr; //
mess_nummer=mess_1[0].nr
7.
Unions
o Union:
Variable, die zu unterschiedlichen Zeitpunkten Objekte mit verschiedenen
Datentypen und Größen enthält.
- Speicher für größten Datentyp wird reserviert àhier
double. Bei neuer Wertzuweisung wird Speicherbereich überschrieben
typdef union
{
unsigned char control_byte;
unsigned short int number;
double temp;
} TRANS_BUFF;
TRANS_BUFF transmit_buffer, *buff_p;
buff_p = &transmit_buffer;
buff_p -> control_byte = c_byte;
buff_p -> number = act_nr;
buff_p -> temp = act_temp;
a.
Bit-Felder
o Menge
nebeneinander liegender Bits innerhalb eines Worts
typedef struct //max 16 Bit da
U_INT16
{
U_INT16 direction : 1; // 1 Bit groß
U_INT16 speed : 4; // 4 Bit groß
} CTRL_PORT;
CTRL_PORT *ctrl_port_p = (CTRL_PORT *) 0x00F0600;
ctrl_port_p -> direction = FORWARD;
ctrl_speed_p -> speed = SLOW;