Array über Funktion ändern



  • Hallo Leute,
    ich habe ein Array und möchte über eine Funktion,in Abhängigkeit des Array, ein neues Array erstellen und Werte zuweisen. Hier der Code:

    #include <iostream>         // for using cout/cin
    
    using namespace std;
    
    // functions
    int *encode(int* data,int elements) {
    	static int output[2*elements];
    	for(int i=0;i<elements;i++) {
    		if(data[i]==1) {
    			output[i]=0;
    			output[i+1]=1;
    		}
    		else {
    			output[i]=1;
    			output[i+1]=0;
    		}
    	}
    	return output;
    }
    
    // main
    
    int main(){
    	int data_array[] = {1,0,1,0,1,0,1};
    	int* manchester = encode(data_array,sizeof(data_array)/sizeof(data_array[0]));
    
    	}
    

    Wenn ich die einzelnen Elemente des Manchester Arrays ausgebe, bekomme ich falsche Werte. Kann mir jemand sagen warum?! Bin Anfänger. Falls noch Infos fehlen bitte schreiben.

    Viele Grüße



  • ist das Absicht, dass du nur die erste Hälfte von output[] mit Werten belegst?



  • Wenn ich die einzelnen Elemente des Manchester Arrays ausgebe

    Du zeigst also nicht den aktuellen Code.

    bekomme ich falsche Werte.

    Du hältst es aber nicht für nötig zu sagen, was die falsche Ausgabe ist und was du erwartest

    Kann mir jemand sagen warum?

    Nein

    Benutze std::vector statt array, dann kannst du dir auch den Quatsch mit dem static sparen.



  • vielleicht sollten die "output[i]=..." durch "output[2*i]=..." ersetzt werden, und die "output[i+1]=..." durch "output[2*i+1]=..."



  • Nimm bestenfalls nen Vector, oder nimm die Multipel, wie mein Vorposter schon erwähnt.



  • Danke für die vielen Antworten.
    @manni66 Sorry für den unverständlichen Post, ich versuche es nochmal besser zu erklären. Für jede 1 die von meinem Daten_Array ankommt will ich eine 01 und für jede 0 eine 10 in einen neues Array schreiben. Also verdoppelt sich die Größe meines ursprünglichen Arrays. Habe das Problem auch schon gelöst, so sieht jetzt mein Code aus.

    /*  Date	-- 22.12.2017
    	Author	-- M. Rickers
    	Name	-- Manchester Code Encoding/Decoding --> a 1 is expressed by a low-to-high transition, a 0 is expressed by a high-to-low transition
    */
    #include <iostream>         // for using cout/cin
    
    using namespace std;
    
    // functions
    
    int *encode(int* data,int elements) {
    	int* output = new int[2*elements];
    	int bit = 0;
    	int nbit = bit+1;
    	for(int i=0;i<elements;i++) {
    		if(data[i]==1) {
    			output[bit]=0;
    			output[nbit]=1;
    		}
    		else {
    			output[bit]=1;
    			output[nbit]=0;
    		}
    		bit+=2;
    		nbit=bit+1;
    	}
    	for(int i=0;i<14;i++) {
    		cout << output[i]<< endl;
    	}
    	return output;
    }
    
    // main
    
    int main(){
    	int data_array[] = {1,0,1,0,1,0,1};
    	int* manchester = encode(data_array,sizeof(data_array)/sizeof(data_array[0]));
    
    	}
    

    Muss ich in meinem Beispiel nachdem ich die encode Funktion aufgerufen habe das output Array löschen, da dynamisch aufgerufen?!
    Was ist der Vorteil bei einem vector?! Kenne diesen Typ nicht.

    Frohe Weihnachten



  • Riebers schrieb:

    Muss ich in meinem Beispiel nachdem ich die encode Funktion aufgerufen habe das output Array löschen, da dynamisch aufgerufen?!
    Was ist der Vorteil bei einem vector?! Kenne diesen Typ nicht.

    Frohe Weihnachten

    Ja, musst/solltest du.
    Vector macht genau das, was du fragst. Es ist ein dynamisches array und sorgt selbst für die Speicherverwaltung.
    http://en.cppreference.com/w/cpp/container/vector



  • Was ist der Vorteil bei einem vector?!

    Du musst dich um den Speicher nicht kümmern.

    Kenne diesen Typ nicht.

    Warum nicht?



  • Naja habe mir das mit den Vektoren mal angeschaut und geändert. Hier der Code:

    /*  Date	-- 22.12.2017
    	Author	-- M. Rickers
    	Name	-- Manchester Code Encoding/Decoding --> a 1 is expressed by a low-to-high transition, a 0 is expressed by a high-to-low transition
    */
    #include <iostream>         // for using cout/cin
    #include <vector>
    using namespace std;
    
    // functions
    std::vector<int> encode(std::vector<int>& data, int elements) {
    	// Ausgabe Array
    	std::vector<int> output(14);
    	// Indizes für output Array
    	int bit = 0;
    	int nbit = bit+1;
    
    	for(int i=0;i<elements;i++) {
    		if(data[i]==1) {
    			output[bit]=0;
    			output[nbit]=1;
    		}
    		else {
    			output[bit]=1;
    			output[nbit]=0;
    		}
    		bit+=2;
    		nbit=bit+1;
    	}
    	return output;
    }
    
    std::vector<int> decode(std::vector<int>& data, int elements) {
    	// Ausgabe Array
    	std::vector<int> output(elements/2);
    	// Index für output Array	
    	int bit = 0;
    
    	for(int i=0;i<elements;i+=2) {
    		if(data[i]==0 && data[i+1]==1) {
    			output[bit]=1;
    		}
    		else {
    			output[bit]=0;
    		}
    		bit++;
    	}
    	return output;
    }
    // main
    
    int main(){
    
    	typedef std::vector<int> vec_t;
    	// Unencoded Data
    	int data_array[] = {1,1,1,1,1,0,1};
    	vec_t vec(data_array,data_array+7);
    	vec_t encode_data = encode(vec,7);
    	for(int i=0;i<14;i++) {
    		cout << encode_data[i] << endl;
    	}
    	vec_t decode_data = decode(encode_data,14);
    	cout << "\nGroesse von encode/decode Vektoren>" << endl;
    	cout << encode_data.size() << endl << decode_data.size() << endl << endl;
    
    	for(int i=0;i<7;i++) {
    		cout << decode_data[i] << endl;
    	}
    }
    

    Habt ihr Tipps, wie man den Code verbessern kann bzw. ist das so richtig?!
    Der output Vektor wird ja, nachdem die Funktion ausgeführt wurde, wieder gelöscht oder?



  • Ein vector kennt seine Größe. Es ist kontraproduktiv diese nochmal separat zu übergeben.
    Das array ist überflüssig, du kannst den vector direkt mit den Werten initialisieren.
    Die ganze Indexrechnerei ist überflüssig, benutze push_back (ohne den vector vorher auf eine Größe zu setzen).

    Der output Vektor wird ja, nachdem die Funktion ausgeführt wurde, wieder gelöscht oder?

    Wenn er nicht vom Compiler wegoptimiert wurde...



  • manni66 schrieb:

    Die ganze Indexrechnerei ist überflüssig, benutze push_back (ohne den vector vorher auf eine Größe zu setzen).

    Dann sag ihm doch wenigstens, dass er mit .reserve() vorher den Speicherplatz für alle Elemente besorgen kann und somit der ganze Kram nicht immer hin und her geschoben wird...

    EDIT: und das er sich für die Zukunft besser an emplace_back gewöhnen soll und push_back besser ignoriert. Macht zwar hier keinen wirklichen Unterschied, aber sags ihm doch einfach!



  • anti-freak schrieb:

    manni66 schrieb:

    Die ganze Indexrechnerei ist überflüssig, benutze push_back (ohne den vector vorher auf eine Größe zu setzen).

    Dann sag ihm doch wenigstens, dass er mit .reserve() vorher den Speicherplatz für alle Elemente besorgen kann

    Das ist hier völlig sinnlos.

    EDIT: und das er sich für die Zukunft besser an emplace_back gewöhnen soll und push_back besser ignoriert.

    Das ist deine Meinung, warum sollte ich die vertreten?



  • manni66 schrieb:

    Das ist deine Meinung, warum sollte ich die vertreten?

    Was spricht denn deiner Meinung nach für push_back?



  • Das Einzige, das dagegen sprechen KANN, ist, dass die falsche Größe zugewiesen wird (wie im Code 14 statt 2*elements). Mit push_back gäbe es dieses Problem nicht.

    Riebers, da du nach Verbesserungen fragst: Warum ist der Parameter denn nun auch ein std::vector? Die Übergabe in deinem ersten Code schon okay, data sollte nur per const übergeben werden, da data nicht verändert wird (und von einem Encoder, gleich welcher Komplexität, auch nicht verändert werden sollte/werden darf).
    Auch die if-Bedingungen sind nicht geschickt gewählt (wenn data [fälschlicherweise] nicht nur aus Nullen und Einsen bestehen sollte), ebenso die beiden (!) Zählvariablen. Wie "Zufallswert" schon geschrieben hat, könnte die Indexberechnung (2*i bzw. 2*i+1) direkt erfolgen. Oder du könntest eine Variable nehmen.
    Am Bsp. encode:

    std::vector<int> encode(const int* data, size_t elements) // Zeiger auf const, Anzahl unsigned
    {
        std::vector<int> output(2*elements);
        for(size_t i=0,bit=0;i<elements;i++) { // i ebenfalls unsigned, bit hier deklarieren & initialisieren, immer alles so lokal wie möglich
            output[bit++]=!data[i];  // data[i]: 0, dann 1, sonst 0
            output[bit++]=!!data[i]; // data[i]: 0, dann 0, sonst 1
        }
        return output;
    }
    

    Beachte auch das Postinkrement (bit++), das Präinkrement (++bit) wäre in diesem Fall falsch.



  • fasfa schrieb:

    Das Einzige, das dagegen sprechen KANN, ist, dass die falsche Größe zugewiesen wird (wie im Code 14 statt 2*elements). Mit push_back gäbe es dieses Problem nicht.

    Und emplace_back verhält sich in diesem Punkt anders als push_back? Wäre mir neu...

    EDIT: Nur der Vollständigkeit halber. Man sollte die typedefs des globalen namespace nicht nutzen. Also statt size_t -> std::size_t oder uint32_t -> std::uint32_t. Genauso wie die die header mit c präfix genutzt werden sollen, statt der .h header (Beispiel: cassert vs assert.h oder cmath vs math.h).


Anmelden zum Antworten