Beispiele: und ein Zahlenrätsel5 Fachhochschule Frankfurt am Main University of Applied Sciences...

20
1 Fachhochschule Frankfurt am Main University of Applied Sciences FB2 Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer Aufgabenstellung: Zu lösen ist das Zahlenrätsel S E N D + M O R E -------------------- M O N E Y Jeder Buchstabe steht für eine Ziffer, verschiedene Buchstaben sind verschiedene Ziffern. Ein C-Programm soll durch Probieren aller möglichen Zahlen die richtigen Lösungen herausfinden. Offensichtlich entspricht der Buchstabe M der Ziffer 1. Die Anzahl der Lösungen ist mitzuzählen. Am Anfang des Programms wird die Aufgabenstellung am Terminal angezeigt. Jede Lösung wird entsprechend aufbereitet zusammen mit dem Lösungszähler am Terminal ausgegeben. Dazu gehören auch: Programmbeschreibung und Struktogramm Beispiele: und ein Zahlenrätsel

Transcript of Beispiele: und ein Zahlenrätsel5 Fachhochschule Frankfurt am Main University of Applied Sciences...

1Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Aufgabenstellung:

Zu lösen ist das Zahlenrätsel S E N D

+ M O R E-------------------- M O N E Y

Jeder Buchstabe steht für eine Ziffer, verschiedene Buchstaben sind verschiedene Ziffern. Ein C-Programm soll durch Probieren aller möglichen Zahlen die richtigen Lösungen herausfinden. Offensichtlich entspricht der Buchstabe M der Ziffer 1.

Die Anzahl der Lösungen ist mitzuzählen. Am Anfang des Programms wird die Aufgabenstellung am Terminal angezeigt. Jede Lösung wird entsprechend aufbereitet zusammen mit dem Lösungszähler am Terminal ausgegeben.

Dazu gehören auch:

Programmbeschreibung und

Struktogramm

Beispiele: und ein Zahlenrätsel

2Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

und eine Lösung#include <stdio.h>

int s1,e1,n1,d1; int m2,o2,r2,e2; int m3,o3,n3,e3,y3;

int lz=0; int a,b,c;

void ausgabe(void);

void main()

{ int ar[10]; int i, ars;

printf("send + more = money\n===================\n\n");

m2 = m3 = 1; //Ziffer m muss 1 sein

for(a=9876; a>8012; a--)

{ s1=a/1000; d1=a%10;

e1 =(a-s1*1000)/100; n1=(a/10)%10;

for (b=1023; b<1987; b++)

{ o2=(b-1000)/100;e2=b%10;

r2=(b/10)%10;

c=a+b;

if((e1 == e2) && (c>10234))

{ e3=(c%100)/10; o3=(c%10000)/1000;

n3=(c%1000)/100; y3=c%10;

if((e1 == e3) && (o2 == o3) && (n1 == n3))

{ for(i=0;i<10;i++)ar[i]=0;ars=0;

ar[s1]=1;ar[e1]=1;ar[n1]=1;ar[d1]=1;ar[m2]=1;

ar[o2]=1;ar[r2]=1;ar[y3]=1;

for(i=0;i<10;i++) ars=ars+ar[i];

if(ars == 8)ausgabe();

} } } } }

void ausgabe(void)

{

printf(" %4d %4d %4d %4d\n",s1,e1,n1,d1);

printf(" %4d %4d %4d %4d\n",m2,o2,r2,e2);

printf("1%4d %4d %4d %4d\n",o3,n3,e3,y3);

printf("\n\n%8d\n",a);

printf("+ %6d\n",b);

printf("========\n");

printf("%8d\n",c);

lz=lz+1;

printf("das war Loesung Nummer %5d\n",lz);

}

3Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

main - Kommandozeilenparameter

Sie können einem Programm beim Aufruf Argumente übergeben• die das Programm zur Laufzeit auswerten kann• solche Argumente heißen Kommandozeilenargumente• und werden in der main Funktion deklariert

– entweder so

• int main (int argc, char *argv[ ])– oder so

• int main (int argc, char **argv)– argc = argument count

argc liefert hierbei die Anzahl der übergebenen Parameter

– argv = argument valuesargv ist ein Feld von Zeigern auf char (Liste von strings)

– dem ersten Parameter wird immer der Programm-Name selbst als Argument übergeben

• Die Namen argc und argv sind die üblichen Variablennamen für die Kommandozeilenparameter

4Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Zugriff auf die main - Kommandozeile

Das Betriebssystem speichert die einzelnen Worte, die Sie auf der Kommandozeile beim Programmaufruf eingeben, als Zeichenketten ab

3jzre\02gran\01gran\0eman

NULL101110051000

Die Anfangsadressen dieser Strings werden in einem Vektor von Zeigern gespeichert

Die Anfangsadressen dieses Vektors steht in der Variablen „argv“ argv: Kommandozeile: name narg1 narg2 Die Anzahl der übergebenen Argumente stehen in der Variablen „argc“ argc: 3

1200

5Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Zugriff auf die einzelnen Kommandozeilenargumente

Ausgehend von der Zeigervariablen “argv“ haben Sie mit einer ersten indirekten Adressierung (z.B. *argv oder argv[0]) die Anfangsadressen der jeweiligen Argumente, die als Zeichenketten zur Verfügung stehen

Mit einer zweiten indirekten Adressierung (z.B. **argv oder argv[0][0]) können Sie auf die einzelnen Zeichen der Argumente zugreifen

Dabei können Sie Zeigerschreibweise oder Vektorschreibweise verwenden. Zeigerschreibweise:

• Anfangsadresse von „name“: *argv

• 1. Zeichen von „name“: **argv

Vektorschreibweise: • Anfangsadresse von „name“: argv[0]

• 1. Zeichen von „name“: argv[0][0]

Gemischte Schreibweise:• 1. Zeichen von „name“: *argv[0]

• 2. Zeichen von „name“: (*argv)[1]

6Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Beispiele: Zugriff auf die Kommandozeilenargumente

#include <stdio.h>int main (int argc, char *argv[ ]) { printf ("Anzahl der uebergebenen Argumente ist: %i\n", argc); for (int i = 0; i < argc; i++) {

printf („Argument Nr. %i ist: %s\n", i, argv[i]); } return 0;}

#include <stdio.h>int main (int argc, char *argv[ ]) {

char *s;if (argc > 1) {

s = argv[1];if ((s[0] == '/') && (s[1] == '?')){

printf("Hilfe zum Programm\n");// weitere Hilfetexte

} } }

Programmname ausgeben:

puts(argv[0]); oder puts(*argv);

Erstes Argument auf Vorhandensein überprüfen:

if(argv[1] == NULL){

printf(“%s: Argurnent erwartet!\n“, argv[0]);

return 1;}

int i =1;

while(argv[i] != NULL) puts(argv[i++]);

int i =1;

while(i < argc) puts(argv[i++]);

while(*++argv != NULL) puts(*argv);

while(--argc != 0) puts(*÷+argv);

7Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Komplexe Datentypen

Neben den einfachen Datentypen (char, int, float) gibt es noch die zusammengesetzte Datentypen

• Aufzählungstypen enum• Strukturen struct• Vereinigungstypen union

die Bitfelder• zur komfortablen Benutzung einzelner bits

und die selbstdefinierten Datentypen• zur besseren Lesbarkeit von C-Programmen

8Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Aufzählungstyp

der Aufzählungstyp wird verwendet• um anstelle von Zahlen mit Namen arbeiten zu können• Beispiel: Wochentage (Montag .. Sonntag)

Vereinbarung eines Aufzählungstyps:• enum TypName {Element1, Element2, .. };

– hierbei ist TypName der Name eines so erstellten neuen Datentyps– gefolgt von einer in Klammern stehenden Liste

– in welcher durch Komma getrennt, die Namen der einzelnen Elemente stehen

Definition einer Variablen eines Aufzählungstyps:• enum TypName Variablenname;

Vereinbarung und Definition können zusammengefasst werden

enum Wochentage {Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag, Sonntag};

enum Wochentage tag;

enum {Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag, Sonntag} tag;

9Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

enum

Die Listenelemente werden durchnumeriert• beginnend mit 0• man kann dem Listenelement auch einen eigenen Wert zuordnen

– alle folgenden Elemente werden dann von dort aus aufsteigend numeriert

Variablendefinition• unter Nutzung des neuen Datentyps

enum Wochentage {Montag, Dienstag, Mittwoch = 5, Donnerstag, Freitag, Samstag, Sonntag};

0 1 5 6 7 8 9

if (tag == 5) { aktion = backup;}

if (tag == Mittwoch) { aktion = backup;}

durch enumwird der Code

lesbarer

// Variable tag mit Initialwert Montag:Wochentage tag = Montag;

10Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

enum - weitere Hinweise

Die Elemente der Liste werden beginnend mit 0 „bewertet“. Soll das erste Element mit einer anderen Zahl anfangen,

so wird diese dem ersten Element zugewiesen.

auch gleichwertige Elemente sind denkbardas jeweilige Element muss mit einem Wert versehen werdenvon da an wird wieder aufsteigend „bewertet“.

Typ-Definition, Variablen-Deklaration und Initialisierung sind in einem Schritt möglich:

enum Noten {sehr_gut = 1, gut, befriedigend, ausreichend, mangelhaft};

1 2 3 4 5

enum bool {falsch, unwahr = 0, richtig, wahr = 1};

0 1

enum bool {falsch, unwahr = 0, richtig, wahr = 1} fertig = falsch;

11Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Strukturen

Strukturen verwendet man dort, wo unterschiedliche Daten zu einem „Datenobjekt“ zusammengefasst werden

Vereinbarung einer Struktur:• beginnt mit Schlüsselwort struct• gefolgt von einem StrukturNamen• und einer Liste von Komponenten in Klammern { }• mit Semikolon abgeschlossen;• jede Komponente

– wird durch Name und Datentyp beschrieben.

Definition einer Strukturvariablen:• beginnt mit Schlüsselwort struct• gefolgt von dem StrukturNamen• und dem Variablennamen und Semikolon

Vereinbarung und Definition können zusammengefasst werden

// Datentyp für komplexe Zahlenstruct complex { float re; // Realteil float im; // Imaginärteil};

enum format {Pform, Rform};

// Datentyp für Vektorenstruct vektor { format form; double betrag; double winkel; double x; double y;};

12Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Arbeiten mit Strukturen

// Deklaration einer Struktur

// Datentyp für komplexe Zahlenstruct complex { float re; // Realteil float im; // Imaginärteil};

// Deklaration einer Variablen

complex c1, c2;

// Zugriff auf die Komponenten

c1.re = c2.re + 10.0;c1.im = c2.im + 20.0;

Auf die Komponenten einer Struktur wird mit dem Punkt-Operator . zugegriffen.

// Deklaration einer Struktur// und Variablendeklaration in einem Schritt

// Datentyp für komplexe Zahlenstruct complex { float re; // Realteil float im; // Imaginärteil} c1, c2;

Name der Struktur!

Name der Variablen!

13Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Zugriff auf Komponenten von Strukturen

über den . Operator (Punktoperator) bei Zeiger auf Strukturen

• über den -> Operator (Pfeiloperator)

• anstelle von (*Stukturname).Komponente

struct psatz {char *name;int Jahr;

} person, *person_ptr;

#include <stdio.h>

#include <stdlib.h>

int main () {

struct psatz {char * name; int jahr;} person;

struct psatz * person_ptr;

person_ptr = &person;

person.name = (char *) malloc (80);

printf ("Bitte geben Sie einen Namen ein: \n");

gets (person.name);

printf ("Bitte geben Sie das Alter von %s ein: \n", person.name);

scanf ("%i", &person.jahr);

printf ("%s ist %i Jahre alt\n", person_ptr->name, person_ptr->jahr);

printf ("%s ist %i Jahre alt\n", (*person_ptr).name, (*person_ptr).jahr);

return 0;

}

14Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Vereinigungstyp - union

Eine union wird ähnlich wie struct definiert.• Bei Strukturen werden die einzelnen Komponenten hintereinander im Speicher abgelegt. • Im Unterschied zu struct werden die Komponenten der union überlappend auf dem

selben Speicher abgelegt.• Nur eine der überlappenden Elemente ist sinnvoll. • Eine Unionvariable belegt mindestens soviel Speicherplatz wie ihre größte Komponente

Vereinbarung einer Union:• beginnt mit Schlüsselwort union• gefolgt von einem UnionNamen• und einer Liste von Komponenten in Klammern { } mit Semikolon abgeschlossen;• jede Komponente wird durch Name und Datentyp beschrieben.

Definition einer Unionvariablen:• beginnt mit Schlüsselwort union• gefolgt von dem UnionNamen• und dem Variablennamen und Semikolon

Ein Zugriff auf die Komponenten erfolgt entweder mit dem Punkt- oder mit dem Pfeiloperator

15Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Anwendung Vereinigungstyp - union

enum format {Pform, Rform};

struct vektor { format form; double r; double phi; double x; double y;};

Zugriff:

v1.form = Rform;v1.vr.x = 10.0;v1.vr.y = 20.0;

v2.form = Pform;v2.vp.r = sqrt(v1.vr.x * v1.vr.x + v1.vr.y * v1.vr.y);v2.vp.phi = atan (v1.vr.y / v1.vr.x);

enum format {Pform, Rform};struct VPform { double r; double phi;};struct VRform { double x; double y;};

struct vektor{ format form; union { VPform vp; VRform vr; };} v1, v2;

Hiermit unterscheiden Sie

Rform von Pform

Zum Vergleich: Struktur

Und jetzt: Union

16Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

struct und union - weitere Hinweise

Abhängig von den Deklarationen werden die Zugriffe• einfacher - bzw. mehr verschachtelt

struct vektor{format form; union {

struct {double r;double phi;

};struct {

double x;double y;

};};

} v1, v2;

Keine Namen für die Strukturen!

Zugriff jetzt so:

v1.form = Rform;v1.x = 10.0;v1.y = 20.0;

Anonyme Struktur!

Anonyme Union!struct vektor{

format form; union {

struct {double r;double phi;

} vp;struct {

double x;double y;

} vr;} uv;

} v1, v2;

Zugriff so:

v1.uv.vr.x = 10.0;

17Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Bitfelder

Bitfelder sind besondere Strukturen in C Zugriff auf einzelne bits oder eine Gruppe von bits

struct Flags {unsigned int CF : 1;unsigned int : 5;unsigned int ZF : 1;unsigned int SF : 1;unsigned int : 3;unsigned int OF : 1;unsigned int : 0;

}

Insbesondere interessieren :CF - CarryOF - OverflowSF - SignZF - Zero

18Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

Bitfelder - Regeln Bitfelder werden als Komponenten einer Struktur

definiert erlaubte Datentypen sind

• int• unsigned int• signed int

hinter der Komponente wird durch : getrennt die Anzahl der bits für diese Komponente angegeben

wird für die Komponente kein Name angegeben, so werden soviele „ungenutzte“ bits reserviert wie durch den Doppelpunkt angegeben

wird als Breite 0 angegeben, so wird das nachfolgende Element im nächsten 16bit Wort abgelegt (alignment).

Ansonsten wird auf die Komponenten wie auf eine normale Strukturkomponente zugegriffen.

Bitfelder sind implementationsabhängig

struct Flags {unsigned int CF : 1;unsigned int : 5;unsigned int ZF : 1;unsigned int SF : 1;unsigned int : 3;unsigned int OF : 1;unsigned int : 0;

} flag;

if (flag.OF) printf ("Overflow\n");

19Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

typedef

Mit typedef wird ein neuer Name für einen bestehende Typ vereinbart.

• Es wird kein Datentyp damit deklariert!• Es wird auch kein Speicher reserviert.

SYNTAX: typedef existierenderTyp neuerTypName

Beispiele:• typedef unsigned int size_t; (aus der <stdio.h>)• typedef struct {float re; float im;} complex;

Es können nun Variablendeklarationen mit dem neuen Namen erfolgen:

• size_t z = 10;• complex c1, c2;

20Fachhochschule Frankfurt am MainUniversity of Applied Sciences FB2

Programmiersprache(n) für technische Anwendungen Dipl.math Gerd H. Neugebauer

und eine kleine Anwendung mit einem kleinen Würfel

#include <stdio.h>

typedef struct {

int side[6];

}cube;

cube cub[1];

enum seiten {FRONT, BACK, LEFT, TOP, RIGHT, BOTTOM};

int main() {

int ret;

int rot_y_right(cube*);

int show_cube(cube*);

int init_cubes(cube*);

ret=init_cubes(&cub[0]);

printf("\nShow Initial Configuration\n\n");

ret=show_cube(&cub[0]);

ret=rot_y_right(&cub[0]);

printf("\nShow Configuration after turning\n\n");

ret=show_cube(&cub[0]);

return 0;

}

int rot_y_right(cube *c) { int tmp;

tmp = c->side[FRONT];

c->side[FRONT] = c->side[LEFT];

c->side[LEFT] = c->side[BACK];

c->side[BACK] = c->side[RIGHT];

c->side[RIGHT] = tmp;

return 0; }

int show_cube(cube *c) {

char *col[4] = {"red","green","blue","white"};

printf("Show sides for Cube:\n");

printf("Front\tBack\tLeft\tRight\tTop\tBottom\n");

printf("%s\t%s\t%s\t%s\t%s\t%s\n",col[c->side[FRONT]],

col[c->side[BACK]], col[c->side[LEFT]],

col[c->side[RIGHT]], col[c->side[TOP]],

col[c->side[BOTTOM]]);

return 0; }

int init_cubes(cube *c){

/* Initialize Cube */

enum farbe {RED, GREEN, BLUE, WHITE};

c->side[FRONT] = WHITE;

c->side[BACK] = BLUE;

c->side[LEFT] = RED;

c->side[TOP] = GREEN;

c->side[RIGHT] = RED;

c->side[BOTTOM] = RED;

return 0; }