Forum: Compiler & IDEs C-Code Kleinste Zahl ausgeben


von Tobias (Gast)


Lesenswert?

Guten Abend,
ich habe eine Frage. Ich muss für die Uni ein Programm schreiben bei dem 
der Anwender erst auswählt wie viele Zahlen er eingibt und dann diese 
eingibt. danach kann er wählen ob er die summe der zahlen möchte. Die 
größte Zahl. Die kleinste Zahl. Oder die zahlen nach der größe sortiert.

Bei mir funktioniert soweit alles nur wenn ich die kleinste Zahl 
ausgeben lassen will kommt immer 0 raus. Obwohl die 0 gar nicht mit 
eingegeben wurde.

Das mit dem sortieren habe ich nocht nicht.
Hier mein Code. Das mit dem Sortieren ist ab Zeile 52.
1
#include "stdafx.h"
2
#include "stdio.h"
3
#include "stdlib.h"
4
5
6
int main()
7
{
8
  int n = 0, anzahl = 0, max = 0, min = 0, a, i, b, *zahlen = NULL, summe = 0;
9
  printf("Wie viele Zahlen moechten Sie eingeben?\n");
10
  scanf_s("%d", &anzahl, 1);
11
  zahlen = (int *)calloc(anzahl, sizeof(int)); //Wir reservieren Speicher für "Anzahl" int-Werte mit calloc
12
  for (i = 0; i < anzahl; i++)
13
  {
14
    printf("Zahl eingeben: ", n + 1);
15
    scanf_s("%d", &a, 1);
16
    zahlen[n++] = a;
17
  }
18
  
19
  printf("\nFolgende Zahlen wurden eingegeben:\n");
20
  for (i = 0; i < n; i++)
21
  {
22
    printf("%d ", zahlen[i]);
23
    printf("\n");
24
  }
25
26
  printf("\nWaehlen Sie eine Anwendung:\nDruecken Sie 1 --> Summe aller Zahlen\nDruecken Sie 2 --> Groesste Zahl ausgeben\nDruecken Sie 3 --> Kleinste Zahl ausgeben\nDruecken Sie 4 --> Zahlen aufsteigend sortieren\n");
27
  scanf_s("%d", &b, 1);
28
29
  switch (b)
30
  {
31
  case 1:
32
    for (i = 0; i < anzahl; i++)
33
    {
34
      summe = summe + zahlen[i];
35
    }
36
    printf("Die Summe lautet:\n%d", summe);
37
    break;
38
  case 2:
39
40
    for (i = 0; i<anzahl; i++)
41
    {
42
      if (zahlen[i]>max)
43
      {
44
        max = zahlen[i];
45
      }
46
    }
47
    printf("Die groesste Zahl lautet %d", max);
48
    break;
49
  case 3:
50
    for (i = 1; i<anzahl; i++)
51
    {
52
      if (zahlen[i]<min)
53
      {
54
        min = zahlen[i];
55
      }
56
    }
57
    printf("Die kleinste Zahl lautet:\n%d\n", min);
58
  break;
59
  }
60
61
62
  system("pause");
63
  return 0;
64
}

Ich hoffe ihr könnt mir weiter helfen. Schon einmal Danke dafür. :)
Grüße

: Verschoben durch User
von Teo D. (teoderix)


Lesenswert?

Tobias schrieb:
> Das mit dem sortieren habe ich nocht nicht.

Da sollte aber Deine Prio liegen, damit hast Du doch auch alles Andere!

von Hans Ulli K. (Gast)


Lesenswert?

Ich gebe dir nur einen Tipp, weil alles andere schon die Lösung 
darstellen würde ...

Die Suche nach der größten Zahl ist schon mal richtig.
Obwohl eigentlich auch schon falsch, weil es werden nur positive Zahlen 
genommen.
Nur leider ist die Suche nach der kleinesten Zahl falsch und das nur ein 
einer Stelle.

Der Rest steht glaube ich in K&R

von Tobias (Gast)


Lesenswert?

Für das sortieren kann ich ja einen Bubble sort verwenden?
Gibt es eine Seite wo das gut erklärt wird. Ich habe nämlich keine 
Ahnung ie ich diesen anwenden muss...

Gruß

von OldMan (Gast)


Lesenswert?

Tobias schrieb:
> max = 0, min = 0, a,


Tobias schrieb:
> case 3:
>     for (i = 1; i<anzahl; i++)
>     {
>       if (zahlen[i]<min)
>       {
>         min = zahlen[i];
>       }
>     }

min ist mit 0 initialisiert. Somit ist das Ergebnis immer 0!
Ausserdem beginnt Deine for-Schleife mit dem Index 1 und nicht 0, wie
es sein sollte.

Jetzt sollte bei Dir der Groschen fallen.....

von Tobias (Gast)


Lesenswert?

Ja das mit der initialisierung hatte ich auch schon im Kopf. Aber ich 
muss min ja irgendeinen wert zuweisen. Wie mache ich es das es nicht 0 
ist?

von Hans Ulli K. (Gast)


Lesenswert?

OldMan schrieb:
> Tobias schrieb:
>> max = 0, min = 0, a,
>
>
> Tobias schrieb:
>> case 3:
>>     for (i = 1; i<anzahl; i++)
>>     {
>>       if (zahlen[i]<min)
>>       {
>>         min = zahlen[i];
>>       }
>>     }
>
> Ausserdem beginnt Deine for-Schleife mit dem Index 1 und nicht 0, wie
> es sein sollte.

Dann schau dir mal calloc an. Da werden "anzahl" Elemente alloziert.

In C zählt man immer von 0

Und für die Initierlasierung gibt es "vordefinierte" defines

Alles andere in nicht portabel

von chris (Gast)


Lesenswert?

Tobias schrieb:
> Wie mache ich es das es nicht 0
> ist?

Indem du es nicht mit 0 initialisierst, sondern mit dem maximal 
auftretenden Wert. Dann findest du auf jeden Fall eine Zahl, die kleiner 
ist.
D.h. je nach Architektur ist ein int 16, 32 oder 64bit breit. Am PC 
wahrscheinlich 32bit, also Wertebereich -2147483648..2147483647

--> init mit 2147483647

von Hans Ulli K. (Gast)


Lesenswert?

#include <limits.h>

von Tobias (Gast)


Lesenswert?

Hans Ulli Kroll schrieb:
> #include <limits.h>

Was meinst du damit?


Und zu chris: Habe das gerade so getestet dann kommt aber immer noch 0 
raus. Kann mir vielleicht jemand ne Lösung präsentieren. Ich mach schon 
ewig rum...

Grüße

von Matthias (Gast)


Lesenswert?

Hans Ulli Kroll schrieb:
> In C zählt man immer von 0

In dem Fall macht es aber Sinn, mit 1 zu beginnen:
1
   min = zahlen[0];
2
   for (i = 1; i<anzahl; i++)
3
      ...

von Tobias (Gast)


Lesenswert?

Matthias schrieb:
> Hans Ulli Kroll schrieb:
>> In C zählt man immer von 0
>
> In dem Fall macht es aber Sinn, mit 1 zu beginnen:   min = zahlen[0];
>    for (i = 1; i<anzahl; i++)
>       ...

so:

    min = zahlen[0];
    for (i = 1; i<anzahl; i++)
    {
      if (zahlen[i]<min)
      {
        min = zahlen[i];
      }
    }


??

von Matthias (Gast)


Lesenswert?

Ja, so. Du musst jetzt jedoch überprüfen, ob anzahl==0 (ist das in der 
Aufgabe zulässig?)

von PVA (Gast)


Lesenswert?

Initialisiere min doch einfach mit zahlen[0].

von PVA (Gast)


Lesenswert?

Oh...zu spät ;-)

von Tobias (Gast)


Lesenswert?

In der Aufgabe ist alles zulässig ;)
In wie fern meinst du die Überprüfung?
Die Anzahl ist nie Null, da der Anwender ja eine bestimmte anzahl an 
zahlen eingibt.
anzahl ist dann zum beispiel 2 oder 10 oder 15 oder 20...

von Tobias (Gast)


Lesenswert?

PVA schrieb:
> Initialisiere min doch einfach mit zahlen[0].

Das funktioniert trotdem nicht. Es kommt immer noch  0 raus. Hier mal 
mein aktueller stand:

  case 3:
    min = zahlen[0];
    for (i = 1; i<anzahl; i++)
    {
      if (zahlen[i]<min)
      {
        min = zahlen[i];
      }
    }
    printf("Die kleinste Zahl lautet:\n%d\n", min);
  break;

von kann kein c (Gast)


Lesenswert?

Tobias schrieb:
> int n = 0, anzahl = 0, max = 0, min = 0, a, i, b, *zahlen = NULL,
> summe = 0;

besser
int n = 0, anzahl = 0, max = 0, min = maxint, a, i, b, *zahlen = NULL,
 summe = 0;

von Martin H. (Gast)


Lesenswert?

Warum machst du es dir so schwer? Du brauchst nur eine Funktion 
wirklich, nämlich die Sortierung. Danach nimmst du einfach entweder das 
erste oder das letzte Element oder du gibst alle aus. Fertig.

von Tobias (Gast)


Lesenswert?

Martin H. schrieb:
> Warum machst du es dir so schwer? Du brauchst nur eine Funktion
> wirklich, nämlich die Sortierung. Danach nimmst du einfach entweder das
> erste oder das letzte Element oder du gibst alle aus. Fertig.

Die Sortierung bekomm ich nicht hin...

von Joe F. (easylife)


Lesenswert?

http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort

1
#include <stdio.h>
2
#include <stdlib.h>
3
int comp (const void * elem1, const void * elem2) 
4
{
5
    int f = *((int*)elem1);
6
    int s = *((int*)elem2);
7
    if (f > s) return  1;
8
    if (f < s) return -1;
9
    return 0;
10
}
11
int main(int argc, char* argv[]) 
12
{
13
    int x[] = {4,5,2,3,1,0,9,8,6,7};
14
15
    qsort (x, sizeof(x)/sizeof(*x), sizeof(*x), comp);
16
17
    for (int i = 0 ; i < 10 ; i++)
18
        printf ("%d ", x[i]);
19
20
    return 0;
21
}

von Karl H. (kbuchegg)


Lesenswert?

Tobias schrieb:
> PVA schrieb:
>> Initialisiere min doch einfach mit zahlen[0].
>
> Das funktioniert trotdem nicht.

Doch, das funktioniert.

> Es kommt immer noch  0 raus. Hier mal
> mein aktueller stand:

Hast du den auch compiliert?
Hat es beim compilieren Fehler gegeben?

von Karl H. (kbuchegg)


Lesenswert?

Joe F. schrieb:
> http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort
> ##


Joe.
Deine Bemühungen in allen Ehren.

Aber der Zweck der Übung ist NICHT eine besonders clevere oder elegante 
Lösung zu finden. Der Zweck solcher Übungsbeispiele ist es, Übung im 
Umgang mit Arrays zu bekommen.

Klar. Draussen in der Industrie würde man das so machen. Ganz im 
Gegenteil. Aber das hier ist nicht Industrie. Das ist Uni und ein 
Übungsbeispiel für Anfänger, der gerade mal eine Handvoll C 
Schlüsselwörter kennt (von beherrschen reden wir erst mal nicht)

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Es gibt in C bereits eine Standardfunktion namens qsort(), die das 
Sortieren für dich übernehmen kann.

von Tobias (Gast)


Lesenswert?

Also ich habe jetzt gerade ein Mit-studenten gefragt wegen dem bubbel 
sort. Hab das soweit hinbekommen. Und die Ausgabe dann wieder mit einer 
for-schleife.
Danach ist das mit dem Min, und Max wirklich easy. Muss man ja nur 
zahlen[0] und zahlen [anzahl-1] ausgeben und schon hat man die werte.

Ich danke euch für die Bemühungen.

:)

von Norbert Windmann (Gast)


Lesenswert?

Im Studium sollte man aber eine Sortierroutine ohne Sortierfunktion 
aufschreiben können - nein, sogar mehr als eine. Das gehört eigentlich 
zum Grundwissen.

von DirkB (Gast)


Lesenswert?

Tobias schrieb:
> Danach ist das mit dem Min, und Max wirklich easy. Muss man ja nur
> zahlen[0] und zahlen [anzahl-1] ausgeben und schon hat man die werte.

Beim Sortieren musst du mehrmals durch das Array laufen.
Summe, Min und Max kannst du zusammen bei einem Durchlauf ermitteln.

von Diek (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Es gibt in C bereits eine Standardfunktion namens qsort(), die das
> Sortieren für dich übernehmen kann.

Das hört sich für mich aber sehr nach Qt an und das wär dann C++ ;)

von operator (Gast)


Lesenswert?

Schlimmer als Threadersteller die nicht selber die suchfunktion 
benützen, sind eigentlich nur Antworter, die ins blaue raten und 
unwissende verwirren.
Qsort: "qsort is a C standard library function that implements..."
http://en.wikipedia.org/wiki/Qsort

von MagnusGehHeim (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Es gibt in C bereits eine Standardfunktion namens qsort(), die das
> Sortieren für dich übernehmen kann.

Super, das ist dann sicher eine tolle Übung um C zu lernen.

von Markus F. (mfro)


Lesenswert?

MagnusGehHeim schrieb:
> Super, das ist dann sicher eine tolle Übung um C zu lernen.

Lernen wird heutzutage allgemein überschätzt.

Es reicht doch, wenn man "Wikipedia" tippen kann.

von Thomas (Gast)


Lesenswert?

Was für eine Uni ist denn das? Das sieht mir doch eher nach Berufschule 
für Fachinformatiker aus.
Bei uns hätte man einfach stillschweigend vorausgesetzt, dass man sowas 
triviales kann, allenfalls hätte man uns als Aufwärmübung gegeben, 
Quicksort oder Heapsort zu programmieren.
Keine Provokation, die Frage ist Ernst gemeint.
Th.

von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

Tobias schrieb:
> Hans Ulli Kroll schrieb:
>> #include <limits.h>
>
> Was meinst du damit?

Tobias schrieb:
> int n = 0, anzahl = 0, max = 0, min = 0, a, i, b, *zahlen = NULL,
> summe = 0;

Das bezog sich darauf, dass in limits.h der grösste int Wert als macro 
definiert wurde, und man diesen min zuweisen könnte. Dafür bevorzuge ich 
volgende macros:
1
#define MIN(T) ((~(T)0)>0?0:(((T)1)<<(sizeof(T)*8-1))) 
2
#define MAX(T) ((~(T)0)>0?(~(T)0):(~MIN(T)))

Da sie mir das Suchen in der limits.h nach dem entsprechenden makro 
ersparen.

Ein Beispiel zu den Macros ist im Anhang.

PS: Das Makro ist nicht auf Bitfields anwendbar, lässt sich jedoch bei 
bedarf einfach modifizieren.

von Hans Ulli K. (Gast)


Lesenswert?

Daniel A. schrieb:
> Tobias schrieb:
>> Hans Ulli Kroll schrieb:
>>> #include <limits.h>
>>
>> Was meinst du damit?
>
> Tobias schrieb:
>> int n = 0, anzahl = 0, max = 0, min = 0, a, i, b, *zahlen = NULL,
>> summe = 0;
>
> Das bezog sich darauf, dass in limits.h der grösste int Wert als macro
> definiert wurde, und man diesen min zuweisen könnte. Dafür bevorzuge ich
> volgende macros:
>
>
1
> #define MIN(T) ((~(T)0)>0?0:(((T)1)<<(sizeof(T)*8-1)))
2
> #define MAX(T) ((~(T)0)>0?(~(T)0):(~MIN(T)))
3
>
>
> Da sie mir das Suchen in der limits.h nach dem entsprechenden makro
> ersparen.

Für dich ist das zwar gut, aber richtig ist es nicht
Was machst du, wenn irgendwo in den Headerfiles
1
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
2
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
auftaucht. Und das ist nicht selten ...

Joe F. schrieb:
> http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort
>
Hoffentlich ist das Array nicht schon sortiert ...

von Daniel A. (daniel-a)


Lesenswert?

Hans Ulli Kroll schrieb:
> Für dich ist das zwar gut, aber richtig ist es nicht
> Was machst du, wenn irgendwo in den Headerfiles
1
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
2
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
> auftaucht. Und das ist nicht selten ...

Ok. Der Name war ungünstig gewählt, können wir uns auf TMAX und TMIN 
einigen? Oder gibt es weitere Namensvorschläge?

von Hans Ulli K. (Gast)


Lesenswert?

Es ist Allgemeinen so, dass man eigene Symbole meistens mit einem oder 
zwei Unterstriche beginnt
also
#define _MIN()
#define __MIN()

von Daniel A. (daniel-a)


Lesenswert?

Hans Ulli Kroll schrieb:
> Es ist Allgemeinen so, dass man eigene Symbole meistens mit einem oder
> zwei Unterstriche beginnt

Sind die nicht schon für den compiler reserviert? Ich hatte da mal 
riesen Probleme beim undefinieren eines macros, finde den thread leider 
nichtmehr...

Ausserdem generieren macros doch garkeine Symbole, und wenn alle 
unterstriche für ihre Makros verwenden löst dass das 
Namenskolisionsproblem auch nichtmehr.

Ich denke, ein Prefix als Namespace könnte die Lösung sein.

von Dirk B. (dirkb2)


Lesenswert?

Daniel A. schrieb:
> der grösste int Wert als macro
> definiert wurde, und man diesen min zuweisen könnte

Das universellste ist immer noch, min und max mit dem ersten Wert 
aus dem Array zu initialisieren.

Da braucht man sich keine Gedanken um den Datentyp zu machen.

von Karl H. (kbuchegg)


Lesenswert?

Daniel A. schrieb:
> Hans Ulli Kroll schrieb:
>> Für dich ist das zwar gut, aber richtig ist es nicht
>> Was machst du, wenn irgendwo in den Headerfiles
>
1
> #define MIN(x, y) (((x) < (y)) ? (x) : (y))
2
> #define MAX(x, y) (((x) > (y)) ? (x) : (y))
3
>
>> auftaucht. Und das ist nicht selten ...
>
> Ok. Der Name war ungünstig gewählt, können wir uns auf TMAX und TMIN
> einigen? Oder gibt es weitere Namensvorschläge?

Die Frage ist doch, warum nicht die Makros aus limit.h nehmen?
Ob du jetzt eigene Makros benutzt oder die aus limits.h - merken musst 
du dir die Makronamen sowieso. Da kannst du dir auch gleich die aus 
limits.h merken.

Das ist ungefähr so, wie man sich natürlich eigene typedefs für einen 
Datentyp mit bestimmten Bitzahlen machen kann. Man kann aber auch ganz 
einfach die aus stdint.h nehmen. Das eine ist so gut wie das andere. Nur 
das es die aus stdint.h auf jedem C System gibt und die vom 
Compilerhersteller schon für dich angepasst wurden.

von spontan (Gast)


Lesenswert?

@tobias:  Was studierst Du eigentlich?

von Route_66 (Gast)


Lesenswert?

Hallo!

Tobias schrieb:
> Die Anzahl ist nie Null, da der Anwender ja eine bestimmte anzahl an
> zahlen eingibt.

Tipp:
Das ist ganz schlechter Programmierstil. User-Eingaben müssen IMMER 
auf Zulässigkeit, Plausibilität und Bereichsüberschreitung geprüft 
werden. Diesen Grundsatz muss man von Anfang an beherzigen.

von Dirk B. (dirkb2)


Lesenswert?

Daniel A. schrieb:
> Dafür bevorzuge ich
> volgende macros:

Diese Makros schränken die Portabilität von C ein.
Du gehst von Zweierkomplement und CHAR_BIT == 8 aus.

von Daniel A. (daniel-a)


Lesenswert?

Karl Heinz schrieb:
> Die Frage ist doch, warum nicht die Makros aus limit.h nehmen?

limits.h hat für jeden Datentyp 2 makros, exclusive benutzerdefinierter 
Datentypen.
Ich habe 2 makros für alle Integer datentypen, inklusive 
benutzerdefinierte.

Eine einfache rechnung:
1
n = anzahl datentypen, für die limits.h makros hat
2
wobei gilt: ∞ > n > 1 und  n ∈ N
3
Anzahl Makros MIN/MAX macros von limits.h: 2n
4
Anzahl meiner makros: 2
5
Schlussfolgerung: 
6
  2n - 2 = Weniger zu merkende makros
7
  n = Anzahl unterstützte integertypen von limit.h
8
  ∞ = Anzahl von meinem makro Unterstützten typen

> Ob du jetzt eigene Makros benutzt oder die aus limits.h - merken musst
> du dir die Makronamen sowieso. Da kannst du dir auch gleich die aus
> limits.h merken.

Das sind aber viel mehr Makros! Und nicht jeder Integer datentyp (z.B. 
benutzerdefinierte) sind abgedekt.

von Daniel A. (daniel-a)


Lesenswert?

Dirk B. schrieb:
> Diese Makros schränken die Portabilität von C ein.
> Du gehst von Zweierkomplement und CHAR_BIT == 8 aus.
1
#define MIN(T) ((~(T)0)>0?0:(((T)1)<<(sizeof(T)*CHAR_BIT-1)

Damit bleibt nurnoch dass Zweierkomplement-Problem, welches ich nicht in 
einem Makro lösen kann.

Ich werde mir eine C++ universallösung mit templates ausdenken, die 
immer funltioniert.

von Daniel A. (daniel-a)


Lesenswert?

Daniel A. schrieb:
> Ich werde mir eine C++ universallösung mit templates ausdenken, die
> immer funktioniert.

Hat ne weile gedauert, folgendes ist zwar vollkommen unbrauchbar, würde 
aber immer funktionieren. Mit c++11, gcc 4.8.3, char und short 
Datentypen getestet. Grössere Datentypen füren zu einem Stack Overflow 
während dem Kompilieren. Eine äquivalente Lösung ohne C++11 zur 
Compiletime ist theoretisch möglich, praktisch aber nicht 
funktionsfähig.
1
template<typename T>
2
class IntInfo {
3
private:
4
  static constexpr T calc_min(T x=0){
5
    return ((T)(x-1)<x)?calc_min((T)(x-1)):x;
6
  }
7
8
  static constexpr T calc_max(T x=0){
9
    return ((T)(x+1)>x)?calc_max((T)(x+1)):x;
10
  }
11
public:
12
  static constexpr T min = calc_min();
13
  static constexpr T max = calc_max();
14
};
15
16
int main(){
17
  std::cout << (int)IntInfo<char>::min << std::endl;
18
  std::cout << (int)IntInfo<char>::max << std::endl;
19
  std::cout << IntInfo<short>::min << std::endl;
20
  std::cout << IntInfo<short>::max << std::endl;
21
  std::cout << IntInfo<unsigned short>::min << std::endl;
22
  std::cout << IntInfo<unsigned short>::max << std::endl;
23
}

Jetzt besteht noch die Möglichkeit die Werte mit einer Formel ohne 
Zuhilfenahme des Datentyps direkt zu berechnen.

von Hans Ulli K. (Gast)


Lesenswert?

Vor 30 Jahren konntest du den Code dort

http://www.ioccc.org/

einreichen und vielleicht einen Preis gewinnen :-)
Leider ist der C++ ...

von Markus F. (mfro)


Lesenswert?

Hans Ulli Kroll schrieb:
> Vor 30 Jahren konntest du den Code dort
>
> http://www.ioccc.org/
>
> einreichen und vielleicht einen Preis gewinnen :-)
> Leider ist der C++ ...

Ich verstehe das als "ist mir zu kompliziert"?

Find' ich nämlich nicht, ich find's sogar sehr elegant. Rekursive 
Template-Metaprogramme. Respekt für die Idee!

Bloß: wenn's nicht funktioniert, ist's auch nicht sehr viel wert ;).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.