C-Code Kleinste Zahl ausgeben

Gast #3996706
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
Gast #3996714
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
Gast #3996726
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
Gast #3996727
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
Gast #3996756
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...
Gast #3996758
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;
Gast #3996782
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.
#3996855
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
}
#3996863
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)
Gast #3996872
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.

:)
Gast #3999010
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.
Gast #3999064
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.
#3999080
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.
Angehängte Dateien:
Gast #3999095
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 ...
#3999104
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?
#3999228
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.
#3999328
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.
Gast #3999360
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.
#3999443
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.
#3999469
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.
#3999664
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.
#4000073
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 ;).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren