[C++] Assoziativarray + Verständnisproblem

New C´ler

Cadet 2nd Year
Registriert
Apr. 2006
Beiträge
29
Bon soir...

hab mal wieder nen problem...also, mein lieber prof hat uns das hier vorn latz geknallt...un ich check des einfach nich so richtig...bräuchte da ma bissl hilfe

Das Programm hat keinen höheren sinn. Es wird einfach nur die Häufigkeit von eingegebenen Namen geprüft...

Meine Komilitonen können mir da auch nich weiterhelfn, die verstehn noch weniger als ich und die höheren Semstler zu fragn, hat mir auch nich den erhofften erfogl gebracht :rolleyes:

ich fang einfach mal an, zu schreiben, was ich denke, was die zeilen machen und hoffe, dass mir dann jmd sagt ob ich richtig liege ;)
Zeile 14 macht mir besonder zu schaffn....!

PHP:
1.#include <stdio.h>
2.#include <stdlib.h>
3.#include <string.h>
4.
5.#define large 1024
6.
7.  struct pair{
8.    
9.    char* name;
10.    int val;
11.  };
12.      struct pair vec[large+1];
13.      
14.      struct pair* find(const char*p){
15.        int i;
16.        for (i=0; vec[i].name; i++)
17.             if(strcmp(p, vec[i].name)==0)
18.             
19.             return &vec[i];
20.              
21.            if (i==large)
22.            return &vec[large-1];
23.             return &vec[i];
24.      }
25.           
26.        int* value(const char* p){
27.          struct pair* res = find(p);
28.          if (res->name==0){
29.            res->name = malloc(strlen(p)+1);
30.          strcpy(res->name,p); 
               }
31.          return &res->val;
32.        }
33.        
34.  int main () {
35.  char buf [256];
34.  int i;
35.  printf("Haeufigkeit eingegebener Woerter (Abschliessen mit \".\")\n");  
36.  
37.  scanf("%s", buf);
38.  
39.  while (buf[0]!='.'){
40.    (*value(buf))++, scanf("%s",buf);
41.  }
42.  
43. printf("\n");
44. for (i=0; vec[i].name; i++) 
45.  printf("%s: %u\n", vec[i].name, vec[i].val);
46.
47.  return EXIT_SUCCESS;
48.}

7 es wird eine Struktur angelegt mit typName pair un den nachfolgenden variablen

zeile 9, is das ein pointer mit bezeichnung name, die einen character wert zurückgibt?...ich kenn das nur so char *name und nicht char* name ?!?

12 Struktur mit Variablenbezeichner vec wird angelegt, ist ein Array mit größe 1025
14 Pointervariable find, vom Typ pair.....was macht * nach pair ??
16 for schleife, mit abbruchbedingung, eingegebener name gefundn
17 vergleicht ob p mit vec.name übereinstimmt, liefert bei gleichheit eine 0
19 adresse von vec wird zurückgegeben (die an der name steht ??? )
22/23 so, das peil ich dann auch nich, wieso will er large-1 zurückgebn? für sentinel?
26 hier hab ich wieder das proble,dass ich nich weiß, wo das * hingehört... ERKLÄRUNG :(
27 res zeigt auf Adresse von dem eingegeben name, auf den p zeigt, res ist ein pointer vom typ pair
28 neues paar anlegen, es wird genauso so viel Speicheplatz reserviert wie benötigt
30 das strcpy is mir auhc nich so ganz klar...
31 res, welches auf die struktur val zeigt, wird zurückgegeben
37 wieso kann hier dasn & vor buf weggelassn werdn...?
39 solange kein "." eingegeben wird, ist das eine endlosschleife
40 ?????? gibt einen zeiger zurück auf Zeile in Tabelle wo value steht ?
was wird da erhöhr...könnte mir bitte einer da ne explizite erklärung geben, zu dieser zeile?

44 was ist die Abbruchbedingung dieser Schleife?
45 name un dessen häufigkeit werden ausgegeben

so...ich hoffe, irgendwer checkt dsa hier, un bringt mir das en bissl näher :freak:

dickn dank im voraus
 
AW: Assoziativarray + Verständnisproblem

Spricht nicht gerade für die Hochschule ;)

Um nicht lange an dem Programm rumzumachen - kurze erklärung was Assoziative Arrays sind:

Bei herkömmlichen Arrays (auch Hash genannt, aufgrund der zurgrundeliegenden Struktur der Datenspeicherung) referenzierst du den Wert an einer Stelle über einen Index der vom Typ integer ist.
z.B.
Array[5] = "foo@bar.org"

Mit einem assoziativen Array, ist man nun nicht mehr auf einen integer als Index beschränkt, sondern greifft mit einem (hier) String auf die Werte zu:
z.B.
Array["E-Mail an"] = "foo@bar.org"

Nützt man sehr oft und ist zum Programmierer einfach übersichtlicher - z.B. wenn du eine Person in einem Array speichern musst (siehe wikipedia):
Code:
map<string,string> person;
person[ "Vorname"    ] = "Hans";
person[ "Name"       ] = "Mustermann";
person[ "Geburtstag" ] = "01.01.01";
person[ "Wohnort"    ] = "Musterstadt";
cout << person["Name"];

Jetzt zu deinem Code: Du legst dir eine ähnliche Struktur an (Pair) die wie folgt aufgebaut ist:
String-Index -> Integer-Wert


Jetzt gibst du Wörter ein - z.B. "hallo" "welt" "!" "hallo"
Dein Programm baut sich jetzt einen vector (vec) wo es die ganzen Werte speichert.
Die Datenstruktur sieht dann so aus:
"hallo" -> 2
"welt" -> 1
"!" -> 1

Jedes mal wenn du ein Wort eingibst, sucht er
Code:
struct pair* res = find(p);
zuerst in allen bisher angelegten Werten in vec[...]->name ob dieser gleich dem Wort ist und erhöht den Wert um eins:
Code:
*value(buf))++

Falls er keins Findet legt er einen neuen Pair an:
Code:
for (i=0; vec[i].name; i++)
#wenn freies gefunden name=null -> return &vec[i]; 
# springt hier rein -> if (res->name==0){ ...


Wenn es jetzt nicht langsam klar wird, meld dich nochmal :)
Aber bevor du dich meldest, kuck dir bitte nochmal im Script/wiki/google an was Pointer, Arrays und C-Strings sind. Das muss man leider kapiert haben, sonst rafft man da gar nix.
 
Zuletzt bearbeitet:
AW: Assoziativarray + Verständnisproblem

Hallo New C´ler,

vorab mal nur ein Kommentar. Wenn das Programm von einem Lehrer/Prof vorgegeben ist, wundere ich mich doch sehr stark über den Programmierstil.

Das das Programm nicht abstürzt, halte ich ich für ziemlich starken Zufall. Und das Du da Verständnissprobleme hast wundert mich nicht. Der Programmierstil ist nicht besonders.

Im folgenden ein kommentiertes Programmlisting. Ich hoffe das hilft Dir weiter:

Code:
1.#include <stdio.h> 
2.#include <stdlib.h> 
3.#include <string.h> 
4. 
5.#define large 1024 
6. 
// Deklaration der Struktur
7.  struct pair{ 
8.     
9.    char* name; // Zeiger auf den Namen
10.    int val;   // Anzahl der Vorkommen
11.  }; 
         // Definition der globalen Variablen mit den Namen
         // Insbesondere ist nicht sichergestellt das der Inhalt dieses Arrays mit 0 initialisiert wird!
12.      struct pair vec[large+1]; 
13.       
         // Deklaration/Definition der Funktion find
14.      struct pair* find(const char*p){ 
15.        int i; // Hier fehlt eine Initialisierung
           // Die Abprüfung der Endebedingung ist fehlerhaft
           // wenn das Array komplett voll ist und im Speicher danach per Zufall Werte != 0 stehen
           // wird fröhlich weiter gesucht bis irgendwann mal eine 0 kommt.
16.        for (i=0; vec[i].name; i++) 
                // Suche nach dem Namen p
17.             if(strcmp(p, vec[i].name)==0) 
18.             
                // Rückgabe des gefundenen Array Eintrags
19.             return &vec[i]; 
20.         
               // Hier fehlt eine Klammerung, wenn das Array komplett gefüllt ist
               // wird über die Arraygrenze hinausgegriffen
               // D.h. die If Abfarge hier ist überflüssig und fehlerhaft.
21.            if (i==large) 
22.               return &vec[large-1]; 
            // Hier kommt eventuell ein Pointer ins Nirwana zurück
23.         return &vec[i]; 
24.      } 
25.      
           // Deklaration/Definition der Funktion value
26.        int* value(const char* p){ 
	         // Aufruf von find
27.          struct pair* res = find(p); 
             // wenn Name nicht gefunden wurde Speicher dafür anlegen
             // und Namen kopieren
             // res könnte auch 0 sein! Daher fehlt hier eine Sicherheitsabfrage
28.          if (res->name==0){ 
	           // Speicher anlegen für neuen Namen
29.            res->name = malloc(strlen(p)+1); 
             // Hier fehlt eine Sicherheitsabfrage auf != 0
             strcpy(res->name,p);  
               } 
             // Auftreten des Namen um eins erhöhen
31.          return &res->val; 
32.        } 
33.         
34.  int main () { 
35.  char buf [256]; // Nicht initialisiert!
34.  int i;          // Nicht initialisiert!
35.  printf("Haeufigkeit eingegebener Woerter (Abschliessen mit \".\")\n");   
36.   
37.  scanf("%s", buf); 
38.   
     // Was ist wenn mehr als 256 Zeichen eingegeben werden? -> Absturz!
39.  while (buf[0]!='.'){ 
	   // Hilfe sowas gehört verboten!
	   // Beim Aufruf einer Funktion kann prinzipiell 0 zurückgegeben werden
	   // in dem Fall -> Absturz
	   // Konkret kann hier aber auf Speicher ausserhalb des Array zugegriffen werden -> Absturz
40.    (*value(buf))++, scanf("%s",buf); 
41.  } 
42.   
     // Ausgabe des Arrays
43. printf("\n"); 
44. for (i=0; vec[i].name; i++)  
45.  printf("%s: %u\n", vec[i].name, vec[i].val); 
46. 
     // Hier kommt dann der Speicherfresser da die allokierten Speicherbereiche mit malloc nicht wieder freigegeben werden!
47.  return EXIT_SUCCESS; 
48.}

MfG

Arnd
 
Zuletzt bearbeitet:
AW: Assoziativarray + Verständnisproblem

Naja, über den Quellcode wollte ich jetzt gar nicht soooo herziehen, da er nur abgetippt ist und fehler deswegen nicht ausgeschlossen sind - gerade in der find().

Aber Verständnisfördernd ist dieser Quellcode alle mal nicht, jedoch finde ich das für das Thema angemessen schwierig - immerhin sollte man voraussetzen, dass einer zu diesem Zeitpunkt C verstanden hat.

Und wie ich nach seinen Fragen sehe, hat er C noch nicht verstanden. Jetzt stellt sich die Frage, ob die Vorlesung fürn arsch ist, oder ein anderes Problem die Ursache ist.

New C´ler, eventuell holst du dir noch vor den Klausuren ein Script einer anderen Hochschule und arbeitest das mal durch.
Ich weis nicht ob du an einer Uni oder Fachhochschule bist - aber ich kann dir mal 2 C-Scripte unserer Dozenten ans Herz legen:
Das C-Script von Prof. Keller - isst sehr ausführlich - eventuell schon fast zu lang.
1 2
Der Foliensatz zu Prof. Zellers Vorlesung. Über diese Scripte hab ich eigentlich auch nur gutes gehört.
 
AW: Assoziativarray + Verständnisproblem

naja, ich sag mal, ich hab den programmcode schon übersichtlich geschriebn, ihr solltet mal den auszug ausm skript sehn...un auch fehlerfrei, denn hab das nich einfach abgetippt, sonder aus meinem compiler rauskopiert

also, wenn ma da nur ausm skript c lernen will, is ma auf jedenfall verloren, deswegen hab ich eigentlihc parallel dazu, noch von galileo_computing c von a-z openbook durchgeackert...un dachte eigentlihc das ich das mit den pointern und strings etc, recht gut verstanden hatte, aba das ding is doch einfach nur mist...

naja, ich werd mcih mal durch die erklärungen ackern, danke schonmal ;)


ps: studier an der hochschule fulda elektrotechnik....un informatik is da eher nur so nen nebenfach ;)...
 
Zuletzt bearbeitet:
AW: Assoziativarray + Verständnisproblem

Ich dachte der Code wäre vom Prof? Da habe ich eben ein bisschen mehr erwartet :-).
Für selbergeschrieben und zum lernen ist er ok. Aber als Vorgabe ist er nicht geeignet.

Ich habe das mal ein bisschen überarbeitet. Für die Eingaberoutine müsste man ein bisschen mehr Aufwand treiben, deshalb habe ich es beim scanf belassen. Aber so sollte man es besser verstehen.

Code:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define large 1024 

struct pair
{
	char* name; 
	int val; 
}; 

struct pair vec[large+1]; 

struct pair* find(const char*p)
{
	struct pair* lpFoundVec = 0;
	int i = 0; 

	if( p )
	{
		for (i=0; i <= large; i++) 
		{
			if( vec[i].name )
			{
				if(strcmp(p, vec[i].name)==0) 
				{
					lpFoundVec = &vec[i]; 
					break;
				}
			} else
			{
				lpFoundVec = &vec[i]; 
				break;
			}
		}
	}

	return lpFoundVec; 
} 

void value(const char* p)
{ 
	struct pair* res = find(p); 

	if( p && res )
	{
		if (res->name==0)
		{ 
			res->name = (char*) malloc(strlen(p)+1); 
			if( res->name )
				strcpy(res->name,p);  
		} 
		res->val++;
	}
} 

int main () 
{
	char buf [256]; 
	int i = 0; 

	memset( buf, 0, sizeof buf );
	memset( vec, 0, sizeof vec );
	
	printf("Haeufigkeit eingegebener Woerter (Abschliessen mit \".\")\n");   

	scanf("%s",buf); 
	while (buf[0]!='.')
	{ 
		value(buf);

		memset( buf, 0, sizeof buf );
		scanf("%s",buf); 
	} 

	printf("\n"); 
	for (i=0; i <= large && vec[i].name; i++)  
	{
		printf("%s: %u\n", vec[i].name, vec[i].val); 
		free( vec[i].name );
		vec[i].name = 0;
	}

	return EXIT_SUCCESS; 
}

MfG

Arnd
 
Zuletzt bearbeitet:
AW: Assoziativarray + Verständnisproblem

nene, das ding is vom prof... :D

ich wollte es nur verstehn, da es eben (jedenfalls für mich) recht kompliziert ist :(

trotzdem danke für eure hilfe, ich denke nämlich, dass ein ausschnitt des programms, in der klausur drankommen könnte und dann erklärt werden soll...

gruß
 
AW: Assoziativarray + Verständnisproblem

Hoffentlich nicht in der Klausur. Denn was das Programm machen soll und was es macht sind eher zwei paar Stiefel :-).
Ausser die Bugs sind mit Absicht eingebaut, dann wäre es eine etwas knifflige Aufgabe :-).
Ist es denn jetzt etwas verständlicher geworden?

MfG

Arnd
 
Zurück
Oben