Ausdrücke
C Programming: A Modern Approach — K. N. King
Wahlpflichtfach Informatik
+ - * / %= += -= …++ --| Op | Bedeutung |
|---|---|
+ | Addition |
- | Subtraktion |
* | Multiplikation |
/ | Division |
% | Modulo (Rest) |
| Op | Bedeutung |
|---|---|
+ | Vorzeichen plus |
- | Vorzeichen minus |
/ bei Integer: Ergebnis wird zur Null hin abgeschnitten% erfordert Integer-Operanden; Vorzeichen = Vorzeichen des Dividenden (C99)| Ausdruck | Ergebnis | Hinweis |
|---|---|---|
7 / 2 | 3 | abgeschnitten, nicht gerundet |
-7 / 2 | -3 | zur Null hin (C99) |
7 % 2 | 1 | Rest |
-7 % 2 | -1 | Vorzeichen wie Dividend |
(a/b) * b + a % b == a
| Priorität | Operatoren | Assoziativität |
|---|---|---|
| höher | * / % | links |
| tiefer | + - (binär) | links |
| unär | + - (Vorzeichen) | rechts |
int x = 2 + 3 * 4; /* x = 14, nicht 20 */
int y = -2 + 3; /* y = 1 */
Der Universal Product Code (UPC) ist der Strichcode auf Produkten in Nordamerika.
#include <stdio.h>
int main(void)
{
int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, total;
printf("Erste Ziffer: "); scanf("%1d", &d);
printf("Erste Fünfergruppe: "); scanf("%1d%1d%1d%1d%1d",
&i1,&i2,&i3,&i4,&i5);
printf("Zweite Fünfergruppe: "); scanf("%1d%1d%1d%1d%1d",
&j1,&j2,&j3,&j4,&j5);
total = 3*d + i1 + 3*i2 + i3 + 3*i4 + i5 +
3*j1 + j2 + 3*j3 + j4 + 3*j5;
printf("Prüfziffer: %d\n", 9 - ((total - 1) % 10));
return 0;
}
total9 - ((total - 1) % 10)v = e; /* speichert Wert von e in v */
v muss ein lvalue sein — eine adressierbare Speicherstelleei = j = k = 0; /* Kette: von rechts nach links */
printf("%d\n", i = 5); /* gibt 5 aus */
| Operator | Beispiel | Entspricht |
|---|---|---|
+= | i += 5 | i = i + 5 |
-= | i -= 5 | i = i - 5 |
*= | i *= 5 | i = i * 5 |
/= | i /= 5 | i = i / 5 |
%= | i %= 5 | i = i % 5 |
v += e wertet v einmal aus.v = v + e wertet v zweimal aus — bei Nebeneffekten ein Unterschied!
++i — erhöht i, gibt neuen Wert zurück--i — verringert i, gibt neuen Wert zurücki++ — gibt alten Wert zurück, erhöht danni-- — gibt alten Wert zurück, verringert dannint i = 5;
printf("%d\n", ++i); /* 6 — i ist 6 */
printf("%d\n", i++); /* 6 — i ist 7 */
printf("%d\n", i); /* 7 */
int i = 3, j;
j = ++i; /* i wird 4, j = 4 (Präfix: erst erhöhen) */
j = i++; /* j = 4, dann i wird 5 (Postfix: erst lesen) */
i++; und ++i; beide erhöhen i um 1.
++i ≡ (i += 1) — beide geben neuen Wert zurück.i++ gibt den alten Wert zurück.
| Priorität | Name | Operatoren | Assoz. |
|---|---|---|---|
| 1 (hoch) | Postfix | ++ -- | links |
| 2 | Präfix / Unär | ++ -- + - | rechts |
| 3 | Multiplikativ | * / % | links |
| 4 | Additiv | + - | links |
| 5 (tief) | Zuweisung | = *= /= %= += -= | rechts |
Ausgangsausdruck:
a = b += c++ - d + --e / -f
c++: a = b += (c++) - d + --e / -fa = b += (c++) - d + (--e) / (-f)a = b += (c++) - d + ((--e) / (-f))a = b += (((c++) - d) + ((--e) / (-f)))(a = (b += (((c++) - d) + ((--e) / (-f)))))Priorität legt die Struktur fest. Die Reihenfolge der Auswertung ist meist undefiniert.
(a + b) * (c - d)
/* C wertet (a+b) und (c-d) in unbekannter Reihenfolge aus! */
a = 5;
c = (b = a + 2) - (a = 1); /* Nicht vorhersagbar! */
b = a + 2; a = 1; c = b - a; → c ist immer 6.
C kennt drei Kategorien:
i = 2;
j = i * i++; /* SCHLECHT: j könnte 4 oder 6 sein */
++, -- oder = verändern.
In C kann jeder Ausdruck durch ; zur Anweisung werden.
i = 1; /* sinnvoll: Zuweisung hat Nebeneffekt */
i--; /* sinnvoll: Dekrement hat Nebeneffekt */
i * j - 1; /* sinnlos: kein Nebeneffekt, Wert weg */
i = j; /* gemeint: Zuweisung */
i + j; /* versehentlich: sinnlos! */
= und + liegen auf derselben Taste — leicht vertauscht.
gcc -Wall -Wextra
**-Operator in C (anders als Python)i * i * i = i³pow() aus <math.h>double x = i * i * i; /* i hoch 3 */
double y = pow(2.0, 0.5); /* Wurzel aus 2 ≈ 1.414 */
% erfordert Integer-Operandenfmod() aus <math.h>= stehen kann (hat eine Speicheradresse)i = 5; /* i ist lvalue, 5 ist rvalue */
i + 1 = 5; /* FEHLER: "lvalue required as..." */
printf("%d %d\n", i++, i); /* UNDEFINIERT */
i++;
printf("%d\n", i); /* OK */
++ und -- von Ken Thompson's B-Sprache geerbt. Kein Geschwindigkeitsvorteil in modernen Compilern — nur Kürze.
Welche Ausgabe erzeugen diese Fragmente? (i, j, k sind int)
| Code | Ausgabe |
|---|---|
i=5; j=3; |
1 2 |
i=2; j=3; |
0 |
i=7; j=8; k=9; |
1 |
i=1; j=2; k=3; |
0 |
| Ausdruck | Ergebnis | Erklärung |
|---|---|---|
8 / 5 | 1 | Standard |
-8 / 5 | -1 | Zur Null hin (nicht -2) |
8 / -5 | -1 | Zur Null hin |
-8 / -5 | 1 | Zwei Negative = Positiv |
-8 % 5 | -3 | Vorzeichen wie Dividend |
8 % -5 | 3 | Vorzeichen wie Dividend |
| Code | Ergebnis |
|---|---|
i=7; j=8; i*=j+1; |
i=63, j=8i = 7×(8+1) = 63 |
i=j=k=1; i+=j+=k; |
i=3, j=2, k=1j+=k→j=2; i+=j→i=3 |
i=1; j=2; k=3; i-=j-=k; |
i=2, j=-1, k=3j-=k→j=-1; i-=j→i=2 |
i=2; j=1; k=0; i*=j*=k; |
i=0, j=0, k=0 |
| Code | i | j |
|---|---|---|
i=5; j=++i*3-2; |
6 |
16 6×3-2 |
i=5; j=3-2*i++; |
6 |
-7 3-2×5 |
i=7; j=3*i--+2; |
6 |
23 3×7+2 |
i=7; j=3+--i*2; |
6 |
15 3+6×2 |
Zwei separate printf-Aufrufe — Sequenzpunkte trennen die Effekte.
| Code | 1. printf | 2. printf |
|---|---|---|
i=1; |
0 |
2 |
i=10; j=5; |
4 |
11 6 |
i=7; j=8; |
0 |
8 7 |
| Ausdruck | Geklammert |
|---|---|
a*b-c*d+e | ((a*b)-(c*d))+e |
a/b%c/d | ((a/b)%c)/d |
-a-b+c-+d | ((-a)-b)+(c-(+d)) |
a*-b/c-d | ((a*(-b))/c)-d |
i=1, j=2:
| Anweisung | i j |
|---|---|
i += j; | 3 2 |
i--; | 0 2 |
i * j / i; | 1 2 |
i % ++j; | 1 3 |
n % 10n / 10printf("%d%d\n", n%10, n/10)Ziffern einzeln mit %1d einlesen, dann umgekehrt ausgeben:
upc.c — einzelne Ziffern ohne Arithmetik trennen.
n % 8n / 8 wiederholen%o — dann geht es mit einem einzigen printf.
scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d",
&d, &i1, &i2, &i3, &i4, &i5,
&j1, &j2, &j3, &j4, &j5);
Europäische Artikelnummer (13 Stellen) — auf jedem deutschen Produkt:
9 - ((gesamt - 1) % 10)| Thema | Kernpunkte |
|---|---|
| Arithmetik | / schneidet ab; % nur Integer; (a/b)*b+a%b==a |
| Zuweisung | v = e ist ein Ausdruck; Ketten möglich; += etc. |
++ / -- |
Präfix = neuer Wert; Postfix = alter Wert; als Anweisung: kein Unterschied |
| Priorität | Postfix > Unär > */% > +- > Zuweisung |
| Undefiniert | Variable lesen und schreiben im selben Ausdruck → Gefahr! |
| Anweisungen | Nur mit Nebeneffekt sinnvoll; Warnungen lesen! |
Fragen?