probleme mit pointern in C |
|
probleme mit pointern in C |
|
guten abend ich hab ein problem (ich denke das es eins ist, vll bin ich auch einfach nur zu müde um die offensichtliche lösung zu sehen)
ich hab hier ein stück code
Zitat: |
/* das ermitteln von adressen einer stringvariablen */
#include <stdio.h>
int main()
{
char test[18]="Dies ist ein Test"; //string erzeugen
char *pointer=&test[0]; //pointer auf das erste zeichen im string setzen
int change;
char ch;
for(;*pointer;pointer++) //solange der wert von *pointer != NULL ist adresse von pointer ++
{
printf("%c\n",*pointer); //schreib den inhalt der adresse von *pointer als zeichen
}
printf("Welche Stelle wollen sie verändern(0-17) ");
scanf("%d",&change);
printf("\nWelchen Buchstaben wollen sie stattdessen einsetzen "); //neuen buchstaben eingeben, abfrage eines einzelnen char zeichens
scanf("%c",&ch);
pointer=&test[0]; //pointeradresse auf den anfang des arrays setzen
pointer+=change; //pointeradresse von dort an die gewünschte stelle schieben
*pointer=ch; //inhalt der pointeradresse mit dem neuen wert füllen
for(pointer=&test[0];*pointer;pointer++) //und nochmal ausgeben..weils so schön war
{
printf("%c\n",*pointer);
}
return 0;
} |
|
gut der ist ja kommentiert bis zum umfallen, man sollte ersichten können um was es geht (hier wird einfach nur der umgang mit pointern geübt, d.h. anstatt des variablenaufrufs (test[n] ) wird hier halt der pointer benutzt)
das problem das ich hab: ich kompiliere das programm ohne fehler/warnungen, es gibt mit den string aus, macht die abfrage zum thema welche stelle aber die abfrage welcher neue buchstabe wird übersprungen, es setzt von alleine einen wert in die variable ch ein und beendet sich ...könnte mir jemand erklären warum?!
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
18.08.2007 03:05 |
|
|
|
Unter Windows: nach jedem Aufruf von scanf () den Eingabepuffer mit fflush (stdin) leeren.
Unter Linux: das Newlinezeichen nicht mit in den Puffer wandern lassen. Das machste so:
php: |
1:
|
<?php do { scanf ("%c", &dein_char); } while ( getchar () != '\n' ); ?> |
|
Ansonsten viel Spaß beim Weiterüben.
|
|
18.08.2007 03:26 |
|
|
|
... naja ... eigentlich wandert das newline schon in den puffer, nur holt getchar() im gegensatz zu scanf() auch newlines aus dem puffer ...
wichtig ist hier aber nur das da als nächstes zeichen kein '\n' in stdin steht wenn du scanf aufrufst ... wie du dafür sorgst, ist deine sache ...
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
18.08.2007 03:34 |
|
|
|
Ah, wieder was dazugelernt. Thx.
Muss mich mal genauer mit Streams auseinandersetzen.
greetz
|
|
18.08.2007 03:50 |
|
|
|
Vielleicht lernst noch n bissel was raus...
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
|
<?php #include <stdio.h>
int read_int (char w00t []) {
int tmp;
printf (w00t);
do {
scanf ("%d", &tmp);
} while (getchar () != '\n');
return tmp;
}
char read_char (char w00t []) {
char tmp;
printf (w00t);
do {
scanf ("%c", &tmp);
} while (getchar () != '\n');
return tmp;
}
int main () {
char test [] = "Die Groeße passt sich automatisch an.";
char *pointer = test; /* test == &test [0] */
int change;
char ch;
for(; *pointer; ++pointer)
printf ("%c", *pointer);
printf ("\n");
printf ("Welche Stelle moechten Sie veraendern? \n");
change = read_int ("Stelle: ");
printf("Welchen Buchstaben wollen Sie stattdessen einsetzen? \n");
ch = read_char ("Buchstabe: ");
pointer = test;
*(pointer+change) = ch;
for(pointer=test; *pointer; ++pointer)
printf("%c",*pointer);
printf ("\n");
return 0;
} ?> |
|
|
|
19.08.2007 04:30 |
|
|
|
jo danke dir, hab jetzt grade n programm geschrieben, das den inhalt eines integer arrays ordnet, angefangen mit dem größten Wert...
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
|
/*************************************************
* Script zum Sortieren der Werte in einem Array *
* 18.08.2007 by Singh *
*************************************************/
#include <stdio.h>
#include <string.h>
#define ANZAHL 100
int main()
{
int int1[ANZAHL],int2[ANZAHL],hilfe,index,durchlauf,anzahl;
printf("Wie viele Elemente wollen sie eingeben (max 100) ");
scanf("%d",&anzahl);
printf("Bitte geben sie nacheinander %d Zahlen ein\n",anzahl);
/* Auffüllen des Arrays mit Werten */
for(index=0;index<=anzahl-1;index++)
{
printf("\nden %d. Wert eingeben ",index+1);
/* Die Windows-Variante */
scanf("%d",&int1[index]);
fflush(stdin);
int2[index]=int1[index]; /* Den zweiten Array mit dem Inhalt vom ersten füllen, um die beiden nachher zu vergleichen Vorher / Nachher */
}
printf("\nDer Array ist wie folgt aufgefuellt:\n");
for(index=0;index<=anzahl-1;index++)
{
printf("%d",int1[index]);
}
/* Die äußere Schleife, diese ändert den Wert des ersten zeigers um eins */
for(durchlauf=0;durchlauf<=anzahl-1;durchlauf++)
{
/* Die innere Schleife, diese ändert den Wert des Vergleichzeigers */
for(hilfe=0,index=0;index<=anzahl;index++)
{
if(int1[durchlauf]>int1[index])
{
hilfe=int1[durchlauf];
int1[durchlauf]=int1[index];
int1[index]=hilfe;
}
}
}
printf("\nDer alte Array\n");
for(index=0;index<=anzahl-1;index++)
{
printf("%d",int2[index]);
}
printf("\nDer sortierte Array\n");
for(index=0;index<=anzahl-1;index++)
{
printf("%d",int1[index]);
}
getchar();
}
|
|
Nein, ich benutze absichtlich NICHT die funktion qsort...
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Schatten: 19.08.2007 05:40.
|
|
19.08.2007 05:36 |
|
|
|
Nett.
Hab aber noch n kleinen Bug gesehen:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
<?php for(durchlauf=0;durchlauf<=anzahl-1;durchlauf++)
{
for(hilfe=0,index=0;/*GEHT1*/index<=anzahl/*ZUWEIT;)*/;index++)
{
if(int1[durchlauf]>int1[index])
{
hilfe=int1[durchlauf];
int1[durchlauf]=int1[index];
int1[index]=hilfe;
}
}
} ?> |
|
|
|
19.08.2007 06:30 |
|
|
|
wie wäre es mit dynamischer speicherverwaltung? (also nix mit ner festen maximalvorgabe für die array größe)
was sowas anbelangt gilt "viele wege führen nach rom" ...
eine simple möglichkeit wäre zwecks laufzeit effizienz am anfang abzufragen wie viele elemente gebraucht werden, und entsprechend zu allozieren... da du in diesem fall den speicher als einen block zur verfügung bekommst, kannst du auf die daten wie in einem array zugreifen.
wenn du keine ahnung hast wieviele elemente eingegeben werden, ist das auch kein großes problem... in diesem fall musst du aber recht genau wissen wie du mit den daten danach arbeiten willst ... soll ein array artiger zugriff möglich sein gäbe es da noch diese idee:
man alloziere in paketen von X elementen, und speichere die startadressen der blöcke in einer verketteten liste (man kann natürlich auch gleich die daten in so eine liste schreiben, aber das kann, sehr abhänig von dem was man mit den daten machen will, zu laufzeitverzögerungen führen)
ein index läuft für den letzten allozierten block mit, und wird nach jeder eingabe incrementiert... bei überschreiten der blockgröße X wird ein neuer block alloziert...
nach abschluss der eingabe, oder beim ersten zugriff auf die daten wird dann ein index über alle blöcke gebildet:
dieser index ist ein array von int pointern (sofern es sich bei den eingaben um ints handelt) und wird erst bei bedarf alloziert. anschließend werden die pointer auf die elemente gesetzt (laufzeit O(n)... also noch relativ harmlos)
anschließend kann man über diesen index dereferenzieren und auf die daten ähnlich einem array zugreifen... beim sortieren empfiehlt es sich dann das pointer array zu sortieren, und nicht die eigentlichen daten...
hat folgenden näheren sinn: stell dir mal vor du sortierst keine integer, sondern datenblöcke zu +1MB ... was kann man schneller im speicher durch die gegend schieben? +1MB daten oder einen 32/64 bit pointer?
wenn du im allgemeinen nicht auf die laufzeit achten musst, oder das verarbeitende verfahren nicht auf ein array angewiesen ist (... oder du unter cpp einfach den [] operator überlädst...) kannst du auch gleich deine datenelemente als verkettete liste speichern. es wird erst speicherplatz alloziert, wenn er auch für daten benötigt wird.
eine verkettete liste in C besteht in allen üblichen fällen aus einem struct wie diesem hier:
code: |
1:
2:
3:
4:
5:
|
struct myLinkedList {
int data;
myLinkedList *prev;
myLinkedList *next;
}; |
|
wahlweise kann man auch den prev pointer weglassen, wenn man sich nur in einer richtung durch die liste hangeln möchte...
ein solches struct lässt sich dann wie folgt nutzen:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
struct myLinkedList *x,*anfang;
x=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
x->data=0x0815;
x->next=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
anfang=x;
x=x->next;
x->data=0xF00;
/*
...etc...
*/ |
|
man kann natürlich für das struct noch ein typedef machen, so dass man nicht immer "struct myLinkedList" schreiben muss, aber das ist reine optik für den code...
und wo wir schon bei optik sind:
definition:
code: |
1:
2:
3:
4:
5:
6:
7:
|
struct IPaddr
{
unsigned int d:8;
unsigned int c:8;
unsigned int b:8;
unsigned int a:8;
}; |
|
nutzung:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
|
struct IPaddr *eineIP;
unsigned int *langeIP;
eineIP=(struct IPaddr*)calloc(1,sizeof(struct IPaddr ));
langeIP=(unsigned int)eineIP;
eineIP->a=192;
eineIP->b=168;
eineIP->c=1;
eineIP->d=1;
printf("%u\n",*langeIP);
*langeIP=3232235778;
printf("%u.%u.%u.%u\n",eineIP->a,eineIP->b,eineIP->c,eineIP->d); |
|
... umwandlung von 3-dotted-number in langzahldarstellung und andersrum nur mit zuweisungen
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
20.08.2007 01:35 |
|
|
|
Hab jetzt eine dynamische Version programmiert. Mit der Liste werde ich es später mal probieren.
Ich hab mich damit bemüht und möchte jetzt mal unverschämte Kritik ernten. Also was ist schlecht, kann man besser machen, dumm, etc. Einfach die Wahrheit. Wahrscheinlich ein guter weg um besser zu werden.
Hier der Code:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
|
<?php #include <stdio.h>
#include <stdlib.h>
void read_int (int *);
void my_sort (int *, int);
int main () {
int i, n, *to_sort = NULL;
printf ("Wieviele Werte möchten Sie sortieren? \n\n");
printf ("Anzahl: ");
read_int (&n);
to_sort = calloc (n, sizeof (int));
if (to_sort == NULL) {
fprintf (stderr, "calloc (): konnte nicht genügend Speicher reservieren \n");
return 1;
}
for (i=0; i<n; ++i) {
printf ("Wert %d: ", i+1);
read_int (to_sort+i);
}
my_sort (to_sort, n);
printf ("\n");
printf ("Werte: \n");
for (i=0; i<n; ++i)
printf ("Wert %d: %d \n", i+1, *(to_sort+i));
printf ("\n");
return 0;
}
void read_int (int *free_mem) {
do {
scanf ("%d", free_mem);
} while (getchar () != '\n');
return;
}
void my_sort (int *to_sort, int n) {
int i, j, tmp;
for (i=0; i<n; ++i)
for (j=0; j<n; ++j)
if (to_sort [i] > to_sort [j]) {
tmp = to_sort [j];
to_sort [j] = to_sort [i];
to_sort [i] = tmp;
}
return;
} ?> |
|
greetz
|
|
20.08.2007 07:11 |
|
|
|
14: calloc liefert (void*) ... benötigt wird (int*) ... implict cast sollte vermieden werden
35: hier fehlt ein free(to_sort); ... dynamisch allozierter speicher sollte wieder freigegeben werden wenn er nicht mehr benötigt wird, auch wenn man sich auf das cleanup am prozessende verlassen könnte ...
ansonsten ist die sortierfunktion nicht laufzeit effizient, aber das war ja auch nicht die intention...
wenn du fehlermeldungen ausgibts, tu dir selbst den gefallen sie in einer art liste zu führen, dass bringt ein wenig mehr ordnung in den code wenn das prog größer wird....
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
|
#define _ERR_ALLOC_FAIL "konnte nicht genügend Speicher reservieren(%s)\n"
#define _ERR_SOMETHING_ELSE "blah (%s)\n"
void err(const char msg, const char param)
{
fprintf (stderr, msg, param);
abort();
}
/*
.
.
.
*/
/*fehlerfall*/
if (to_sort == NULL)
err(_ERR_ALLOC_FAIL,"main():5"); |
|
alternativ, wenns keine eigene meldung sein muss, gäbe es da noch assert()
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
20.08.2007 11:56 |
|
|
|
Danke dafür. Werde die Sachen beherzigen.
Und...
Zitat: |
Original von DarkSquirrel
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
struct myLinkedList *x,*anfang;
x=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
x->data=0x0815;
x->next=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
anfang=x;
x=x->next;
x->data=0xF00;
/*
...etc...
*/ |
|
|
|
sizeof(myLinkedList ) != sizeof (struct myLinkedList) *hrhr* *fehler gefunden*
greetz
|
|
20.08.2007 15:19 |
|
|
|
nochma ne frage unabhängig von dem von auch angeschnittenen Thema. wenn ich mein sortieren.c unter linux ausführe, mit
code: |
1:
|
do{ scanf("%d",&int1[index]);}while(getchar()!='\n'); |
|
anstelle vom einfachen scanf()
dann ignoriert der programm immer die letzte arraystelle (d.h. die niedrigste Zahl) und setzt stattdessen ne 0 ein.
d.h bei einer eingabe von zB 5,8,9,2,4 bekomm ich als sortierten array 9,8,5,4,0..liegt das an ner anderen arrayverwaltung unter Linux oder dergleichen?
edit: okay das problem lässt sich lösen, wenn man das -1 in der Zeile
code: |
1:
2:
|
/* Die äußere Schleife, diese ändert den Wert des ersten zeigers um eins */
for(durchlauf=0;durchlauf<=anzahl-1;durchlauf++) |
|
auskommentiert...aber warum das so ist interessiert mich trotzdem
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Schatten: 20.08.2007 18:55.
|
|
20.08.2007 18:43 |
|
|
|
Zitat: |
Original von green
Danke dafür. Werde die Sachen beherzigen.
Und...
Zitat: |
Original von DarkSquirrel
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
|
struct myLinkedList *x,*anfang;
x=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
x->data=0x0815;
x->next=(myLinkedList*)calloc(1,sizeof(myLinkedList ));
anfang=x;
x=x->next;
x->data=0xF00;
/*
...etc...
*/ |
|
|
|
sizeof(myLinkedList ) != sizeof (struct myLinkedList) *hrhr* *fehler gefunden*
greetz |
|
hab zwischen dem rumschreiben und posten noch nen typedef drinne gehabt... ich sollte auch das kopieren was ich anschließend da stehen hatte ...
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
20.08.2007 23:27 |
|
|
|
Und hier wieder ein Stück code, welches im Zuge meines Lernprozesses entstanden ist. Es dreht nen String einfach rum
wenn ich lust habe schreibe ich es noch so um, das man den String manuell eingeben kann
hier erst ma die derz. variante
unter verwendung von pointern
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
|
/************************************************************
* ein script, das den inhalt einer stringvariablen umdreht *
* (ja, ich hab was gegen orthographie) *
* (arbeitet hauptsaechlich mit zeigern) *
* 21.08.2007 by Singh *
************************************************************/
#include <stdio.h>
/* Wir benötigt, wenn man den String manuell eingeben will
#define LENGTH 100
*/
/*Prototyp*/
void turn_text(char *);
int main()
{
/* Die Stringvariable, mit [LENGHT] deklarieren, falls man sie manuell eingeben will */
char txt[]/*[LENGTH]*/="Fischers Fritz faengt frische Fische";
/* Die Funktion aufrufen, mit der startadresse der Stringvariablen txt == &txt[0] */
turn_text(txt);
/* Da die Stringvariable mit hilfe ihrer Adresse geändert wird, kann sie global benutzt werden */
printf("%s",txt);
}
void turn_text(char *pt_txt/*Der Pointer zeigt auf den Anfang des Strings*/)
{
char hilfe,*pt_end;
pt_end=pt_txt;
/*Und deiser wird ans Ende geschoben */
for(;*pt_end;pt_end++) {}
/* Jetzt tauschen jeweils zwei Arrayelemente die Plätze, bis sich die beiden Pointer in der Mitte treffen */
for(pt_end-=3;pt_txt<pt_end ;pt_txt++,pt_end--)
{
hilfe=*pt_txt;
*pt_txt=*pt_end;
*pt_end=hilfe;
}
} |
|
unter verwendung von nem index
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
|
/************************************************************
* ein script, das den inhalt einer stringvariablen umdreht *
* (ja, ich hab was gegen orthographie) *
* *
* 21.08.2007 by Singh *
************************************************************/
#include <stdio.h>
//#define LENGTH 100
int main()
{
int index,len,index2;
char txt[]/*[LENGTH]*/="Fischers Fritz faengt frische Fische",hilfe,*pt_anfang,*pt_ende;
for(pt_ende=txt;*pt_ende!='\n';pt_ende++){ }
pt_anfang=txt;
len=(--pt_ende)-pt_anfang;
for(index=0,len-=3;index<len;index++,len--)
{
hilfe=txt[index];
txt[index]=txt[len];
txt[len]=hilfe;
}
printf("\n%s",txt);
} |
|
kurze verständnissfrage: wo ist eig der hauptsächliche unterschied/vorteil eines pointers gegenüber einem array-index?
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Schatten: 21.08.2007 14:34.
|
|
21.08.2007 14:32 |
|
|
|
Guten abend...endlich sitze ich ma vor nem richtigen problem^^ also ich beschäftige mich gerade mit strukturen...für nen anfänger wie mich echt nicht leicht (die grundlagen schon...aber das mit den zeigern nciht)
so ich hab hier n stück code geschrieben, welches die eigentschaften von beliebig vielen Autos speichert und ausgibt
(halt nur zu laufzeit
)
hier ist erstma der code
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
|
/**************************************************************
* Ein Programm welches Daten in einer Struktur speichert *
* Dient zur Übung des Umganges mit der "struct" anweisung *
* 21.08.2007 by Singh *
**************************************************************/
#include <stdio.h>
#define MAXLEN 20
/******************************
Definition der Struktur
******************************/
struct wagen {
char name[MAXLEN]; /* Name des Autos */
float speed; /* Geschwindigkeit */
int zylinder; /* Anzhl der Zilynder */
int ps; /* Anzahl der PS */
char gas; /* Art des Benzins S=Super, N=Normal, D=Diesel */
};
/********************************************************************************
Prototypen eingabe um den struct-array zu füllen, ausgabe um ihn auszulesen
********************************************************************************/
void eingabe(struct wagen *,short);
void ausgabe(struct wagen *,short);
int main()
{
short anzahl;
struct wagen pkws[anzahl];
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
printf("Bitte machen sie Eingaben fuer %d Autos",anzahl);
eingabe(pkws,anzahl);
printf("\nSie haben folgende Daten angegeben");
ausgabe(pkws,anzahl);
}
/*******************************************
Die Eingabe der 4 Autos in den Array
*******************************************/
void eingabe(struct wagen pkw[],short anzahl)
{
short index;
printf("\nBitte machen sie ihre Eingaben");
printf("\nnach dem Syntax name,temp,anzahl zylinder,ps und benzing");
printf("\nzB Audi a3 350.0 4 300 S\n");
for(index=0;index!=anzahl;index++)
{
printf("\nMachen sie ihre eingabe fuer das %d. Auto\n",index+1);
/* Hier kann es unter Linux zu kl. Problemen kommen */
do{scanf("%s %f %d %d %c",&pkw[index].name,&pkw[index].speed,&pkw[index].zylinder,&pkw[index].ps,&pkw[index].gas); } while(getchar()!='\n');
}
}
/****************************************
Ausgabe der eingetragenen Daten
****************************************/
void ausgabe(struct wagen pkw[],short anzahl)
{
short index;
for(index=0;index!=anzahl;index++)
{
printf("\nDie Daten des %d. Autos ",index+1);
printf("Name %s Tempo %f Zylinder %d PS %d Benzin %c",pkw[index].name,pkw[index].speed,pkw[index].zylinder,pkw[index].ps,pkw[index].gas);
}
}
|
|
so, wie man sieht, wuchtet das programm jedesmal den ganzen array von funktion zu funktion...das geht ja auch schöner...mit zeigern zB..kann mir jemand zeigen wie man das mit zeigern macht? ich komm da nciht wirklich weiter, iwie ein wenig undurchsichtig das mit den zeigern zusammen mit strukturen
und mir evtl nochmal erklären, wann es am geschicktesten ist, mit ziegern zu arbeiten und wann mit dem ganzen array
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Schatten: 21.08.2007 17:41.
|
|
21.08.2007 17:38 |
|
|
|
sry für die vielen doppelposts aber ihr wisst ja...30mins...
also ich hab die ausgabe funktion jetzt mit nem pointer zum laufen bekommen. musste nur folgendes abändern.
main sieht jetzt so aus:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
int main()
{
short anzahl;
struct wagen pkws[anzahl+1];
struct wagen *pointer;
pointer=&pkws[0];
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
printf("Bitte machen sie Eingaben fuer %d Autos",anzahl);
eingabe(pkws,anzahl);
printf("\nSie haben folgende Daten angegeben");
ausgabe(pointer,anzahl);
} |
|
und die funktion ausgabe so
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
|
void ausgabe(struct wagen *pointer,short anzahl)
{
for(;pointer->abbruch!=-1;pointer++)
{
printf("\nDie Daten der Autos");
printf("Name %s Tempo %f Zylinder %d PS %d Benzin %c",pointer->name,pointer->speed,pointer->zylinder,pointer->ps,pointer->gas);
}
} |
|
ich stand nur ein wenig aufm schlauch
ist es eig sinnvoll, jetzt für die eingabe auch nen pointer zu benutzen? denn in meinem lehrbuch werden für eingaben nie pointer benutzt...
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
21.08.2007 18:20 |
|
|
|
php: |
1:
2:
3:
4:
|
<?php short anzahl;
struct wagen pkws[anzahl];
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n'); ?> |
|
Das ist schon mal totaler Nonsens.
Du brauchst hier einen Zeiger vom Typ "struct wagen". Dann reservierst du Speicherplatz für anzahl struct wagen. Den Zeiger kannst du dann an deinen Funktionen übergeben.
php: |
1:
|
<?php eingabe(pkws,anzahl); ?> |
|
Ja, man könnte denken, dass hier das ganze Array übergeben wird, aber es wird nur die Anfangsadresse übergeben. Also nicht so happig.
Ahja, das beste deutsche Lehrbuch zu C: http://www.pronix.de/pronix-4.html
Da findest du dann auch, wie man Speicher reserviert, alle Einzelheiten zum Unterschied Zeiger - Array und und und... eben alles, was man dazu wissen muss.
greetz
|
|
21.08.2007 18:37 |
|
|
|
das hab ich bei meinem zweiten post doch so gemacht
code: |
1:
2:
3:
4:
5:
6:
7:
8:
|
short anzahl;
struct wagen pkws[anzahl+1];
struct wagen *pointer;
pointer=&pkws[0];
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
printf("Bitte machen sie Eingaben fuer %d Autos",anzahl);
eingabe(pkws,anzahl); |
|
reserviert speicher, setzt dann den pointer an den anfang des speichers und überigbt den pointer...
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
21.08.2007 18:43 |
|
|
|
Zitat: |
Original von Schatten
das hab ich bei meinem zweiten post doch so gemacht
php: |
1:
2:
3:
4:
5:
6:
7:
8:
|
<?php short anzahl; /* Hat einen zufälligen Wert */
struct wagen pkws[anzahl+1]; /* Array für zufällig viele Werte */
struct wagen *pointer;
pointer=&pkws[0]; /* Pointer auf Array, bei dem nicht sicher ist, ob er genügend Platz für "anzahl" "struct wagen" hat */
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
printf("Bitte machen sie Eingaben fuer %d Autos",anzahl);
eingabe(pkws,anzahl); ?> |
|
reserviert speicher, setzt dann den pointer an den anfang des speichers und überigbt den pointer... |
|
Kurz gesagt: Du hast jetzt zwar den Pointer, aber er zeigt nicht auf genügend freien Speicherplatz.
|
|
21.08.2007 19:03 |
|
|
|
das mit anzahl+1 war falsch, da hatte ich was mit der abbruchbedingung probiert...
das mit calloc war mir neu
ich bin grde erst bei der funktion malloc angekommen...
mal schauen wann das buch dann calloc behandelt..danke für die erklärung
edit: muha ich glaub ich habs verstanden^^ ich denke mal malloc und calloc machen ungefähr das selbe.
also wenn du sagst ich soll den speicher zu laufzeit anfordern...dann geht das doch so oder?
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
|
int main()
{
struct wagen *pointer; /*zeigt iwo ins niwo */
int anz;
printf("Wie viele Wagen ");
scanf("%d",&anz);
/* Und jetzt forder ich so viel Speicher an wie benötigt, in form eines arrays, und setzte den pointer an dessen anfang */
pointer=malloc(anz*sizeof(struct wagen));
/* Wenn nicht genug Speicher da ist */
if(!pointer)
{
printf("Tot und verderben");
return 0;
}
/* dann übergebe ich den pointer an die funktion */
eingabe(pointer,anz);
/* und am ende */
free(pointer);
return 0;
} |
|
ich weis nicht obs 100% richtig ist...aber wo ist der vorteil, wenn ich statt struct wagen pkw[anz];
die malloc funktion benutz?
bzw wo ist der unterscheid zwisch. malloc und calloc
(sry das ich vll öfters das gleiche frag, aber ich wills verstehn und nicht einfach was abrschreiben)
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Schatten: 21.08.2007 23:04.
|
|
21.08.2007 22:34 |
|
|
|
char fritz[100];
... das holt dir einen speicherbereich von 100 zeichen... aber wann holt es diesen? ... beim compiler lauf steht bereits fest wieviel speicher da reserviert wird ...
char *ptr;
... hier wird ebenfall speicher beim compilerlauf reserviert... und zwar genug speicher um eine hauptspeicheradresse abzulegen ... 32 oder 64 bit auf heute üblichen systemen ...
wo ist dieser speicher? ... grundsätzlich lassen sich im hauptspeicher 2 bereiche unterscheiden ... heap und stack ... so deklarierter speicher liegt auf dem stack...
malloc reserviert zur laufzeit speicher auf dem heap ...
calloc tut das selbe, aber calloc initialisiert den speicher den es reserviert mit 0
beide funktionen geben einen pointer auf die erste adresse des allozierten speichers zurück, oder im fehlerfall null
da in deinem code "anzahl" zum compilerlauf nicht definiert ist, wundert es mich das du das programm übersetzt bekommen hast ... mit dem +1 dahinter könnte man es ja noch als nicht definierte konstante 0 ansehen und einfach ein element allozieren, aber... normalerweise beschwert sich ein compiler lautstärk wenn er sowas sieht ...
__________________ Gräten auf dem Sofakissen wird man wohl entfernen müssen.
|
|
22.08.2007 03:54 |
|
|
|
soo ich denke ich hab jetzt sämtliche mängel entfernt. das programm arbeitet jetzt komplett nurnoch mit zeigern, fordert seinen speicher zu laufzeit mit malloc an und...joa des wars eig.
aber ich denke ihr findet trotzdem noch was
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
|
/**************************************************************
* auto.c *
* Speichert die Daten von Autos in einer Struktur. *
* Bentuzt ausschließlich Zeiger auf Variablen und *
* reserviert den benötigten Speicher mit der funktion *
* malloc zu laufzeit nach "benutzerdefinierten kriterien" *
* erstellt am 21.08.2007 by Singh *
**************************************************************/
#include <stdio.h>
#define MAXLEN 20
/******************************
Definition der Struktur
******************************/
struct wagen {
char name[MAXLEN]; /* Name des Autos */
float speed; /* Geschwindigkeit */
int zylinder; /* Anzhl der Zilynder */
int ps; /* Anzahl der PS */
char gas; /* Art des Benzins S=Super, N=Normal, D=Diesel */
int abbruch;
};
/********************************************************************************
Prototypen eingabe um den struct-array zu fuellen, ausgabe um ihn auszulesen
********************************************************************************/
void eingabe(struct wagen *);
void ausgabe(struct wagen *,struct wagen *);
int main()
{
short anzahl;
/**********************************************************************************************************
der zeiger pkws der als adresse benutzt wird anstatt einem variablenname
der zeiger control, der immer auf den anfang des strukturarrays zeigt, dient zum zurücksetzten von *pkws
**********************************************************************************************************/
struct wagen *pkws,*control;
printf("Wie viele Autos wollen sie speichern ");
do{scanf("%d",&anzahl); } while(getchar()!='\n');
/***************************************************************
reserviert speicher für jeden datensatz der eingegeben wird
**************************************************************/
pkws=malloc(anzahl*sizeof(struct wagen));
if(!pkws)
{
printf("\nNicht genug freier Speicher verfuegbar");
return 0;
}
/******************************************************************
gibt der variablen abbruch des letzten datensatzes den wert -1.
dieser stellt die abbruchbedingung für die scheifen da
******************************************************************/
control=pkws;
pkws+=anzahl;
pkws->abbruch=-1;
pkws=control;
printf("Bitte machen sie Eingaben fuer %d Autos",anzahl);
eingabe(pkws);
printf("\nSie haben folgende Daten angegeben");
ausgabe(pkws,control);
}
/*******************************************
Die Eingabe der Auto-Daten in den Speicher
*******************************************/
void eingabe(struct wagen *pkws)
{
short index=1;
printf("\nBitte machen sie ihre Eingaben");
printf("\nnach dem Syntax name,temp,anzahl zylinder,ps und benzing");
printf("\nzB Audi a3 350.0 4 300 S\n");
for(;pkws->abbruch!=-1;pkws++,index++)
{
printf("\nMachen sie ihre eingabe fuer das %d. Auto\n",index);
gets(pkws->name);
do{scanf(" %f %d %d %c",&pkws->speed,&pkws->zylinder,&pkws->ps,&pkws->gas); } while(getchar()!='\n');
}
}
/****************************************
Ausgabe der eingetragenen Daten
****************************************/
void ausgabe(struct wagen *pointer,struct wagen *control)
{
for(pointer=control;pointer->abbruch!=-1;pointer++)
{
printf("\nDie Daten der Autos\n");
printf("Name %s | Tempo %f | Zylinder %d | PS %d | Benzin %c\n\n",pointer->name,pointer->speed,pointer->zylinder,pointer->ps,pointer->gas);
}
system("PAUSE");
} |
|
die nächste stufe ist jetzt, das programm mit ner dateiverarbeitung auszustatten...
aber ne kurze frage noch, warum läuft dieses programm unter windows einwandfrei, linux mekert aber immer rum?
ich bekomm zu laufzeit den fehler segmentaton fault core dumped
ich denke das hat was mit der speicheraddressierung zu tun oder?
ist die speicherverwaltun unter linux anderst als die unter windows bzw wie mach ich das progamm auch unter linux lauffähig
__________________ Alle sagten, es geht nicht, da kam einer, der wusste das nicht und tat es einfach...
|
|
22.08.2007 20:59 |
|
|
|