Programmieren - alles kontrollieren 4.941 Themen, 20.708 Beiträge

mein C-pointer ist nicht auf den Punkt zu Bringen

B-Hoernchen / 6 Antworten / Baumansicht Nickles

das Probelem ist ich habe eine pointer-structur und einen
normale strctur wie bringen ich die beiden dazu wie
zwei normale structuren daten auszutauschen. Also nicht
jede Variable für sich sonder so wie in dem 20 zeilen Programm
weiter unten in dem esel_copy function.
danke von mir

20 zeilen Beispiel von mir
struct esel {
int t1;
bool t2;
;};
typedef esel esel_all;
//****
void esel_copy(esel_all von,esel_all *nach)
{
nach=von; // *********** hier ist das Problem ***********
}
//*****
void main (void)
{
esel_all a1,a2;
a1.t1=10; a1.t2=true;
esel_copy(a1,&a2);
}; (B-hoernchen)

Antwort:
Es ist zwar schon einige Zeit her, dass ich das letzte Mal C programmiert habe, aber ich glaube du hast in der Deklaration der Funktion esel_copy das Referenzzeichen hinter dem ersten Argument esel_all vergessen.
Hoffe, ich konnte helfen!
Tschau! Heiko
(hgue)

Antwort:
erste moeglichkeit:
struct aStruct { int foo; int bar; };
aStruct a;
aStruct b;
void CopyStruct( const aStruct* pSource, aStruct* pDest)
{
*pDest = *pSource;
}
das geht aber nur dann, wenn aStruct keine zeiger als member
hat. dies gilt auch fuer die zweite moeglichkeit:
memcpy( pDest, pSource, sizeof(aStruct));
fuer den fall das aStruct einen zeiger enthaelt bleibt dir in c nichts
andere uebrig als die daten memberweise zu kopieren - zumindest die
daten auf die der zeiger zeigt muessen haendisch kopiert werden. dies liegt daran das sowohl bei der zuweisung (als auch im wesentlichen beim memcopy) das bitmuster von source nach dest kopiert wird: der zeiger-member, so definiert, zeigt dann zwar auf die gleiche adresse, aber die daten auf die gezeigt wird werden natuerlich nicht mit kopiert.)
(in c++ wuerde man einen copy ctor bzw. einen assignment operator definieren.)
WM_HOPETHISHELPS
thomas woelfer
(thomas woelfer)

Antwort:
Deinen Einwand mit den Member-Pointern halte ich für nicht praxisrelevant - jedenfalls in C. Es wird doch gar nicht erwartet, daß bei einer Struktur die Daten, auf die ein Pointer zeigt, mit kopiert werden - oder kannst Du an einem Beispiel aufzeigen, wo das der Fall ist. In C++ ist das anders, da ist es sozusagen postuliert, daß die Kopie eines Objektes ein komplettes Abbild darstellt.
benno
(benno)

Antwort:
void esel_copy(esel_all von,esel_all *nach)
{
nach=von; // *********** hier ist das Problem ***********
}
void schlaumeier_copy(esel_all von,esel_all *nach)
{
*nach = von; // --- das ist die Lösung --- das Sternchen fehlt!
}
Übrigens übergibt kein Mensch eine Struktur 'by value' an eine Funktion, weil sie dazu komplett auf den Stack kopiert muß. Es wird immer mit Referenzen - also Pointern - gearbeitet, einer der Gründe, warum C schnell ist.
benno
(benno)

Antwort:
kommt drauf an was man will - nehmen wir an du hast eine string implementierung die so aussieht:
typedef struct string
{
void* pData;
long cbData;
} String;
wenn man nun eine instanz einer solchen struktur kopiert: will man dann eine komplette kopie des strings oder will man nur eine kopie der struktur. meiner ansicht nach ist das eine frage der betrachtungsweise... nehmen wir dazu mal an es gaebe eine funktion
String* copy_string( const String* pSource);
erwartet man nun eine kopie des strings zurückzubekommen oder erwartet man eine kopie der struktur zurueckzubekommen die den string implementiert?
WM_MY0.02$
thomas woelfer
(thomas woelfer)

Antwort:
Exakt das macht den Unterschied zwischen C und C++ in der Behandlung von "Variablen" aus!
In C wirken die Operatoren nur für die in der Sprachdefinition festgelegten Datentypen vollständig, während man in C++ durch das operator overloading auch für selbstdefinierte Datentypen (Objekte) ein solches Verhalten erreichen kann.
In C also bekommt man bei der Zuweisung eines Aggregattyps definitionsgemäß nur eine bitgenaue Kopie der Variablen, in C++ dagegen ein eigenständiges Duplikat des Objekts. Daher muß das Objekt selbst "wissen", durch was es konstituiert wird und seine eigene Kopieroperation aufweisen - üblicherweise der copy constructo

bei Antwort benachrichtigen
hgue B-Hoernchen „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

Es ist zwar schon einige Zeit her, dass ich das letzte Mal C programmiert habe, aber ich glaube du hast in der Deklaration der Funktion esel_copy das Referenzzeichen hinter dem ersten Argument esel_all vergessen.
Hoffe, ich konnte helfen!
Tschau! Heiko
(hgue)

bei Antwort benachrichtigen
thomas woelfer B-Hoernchen „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

erste moeglichkeit:
struct aStruct { int foo; int bar; };
aStruct a;
aStruct b;
void CopyStruct( const aStruct* pSource, aStruct* pDest)
{
*pDest = *pSource;
}
das geht aber nur dann, wenn aStruct keine zeiger als member
hat. dies gilt auch fuer die zweite moeglichkeit:
memcpy( pDest, pSource, sizeof(aStruct));
fuer den fall das aStruct einen zeiger enthaelt bleibt dir in c nichts
andere uebrig als die daten memberweise zu kopieren - zumindest die
daten auf die der zeiger zeigt muessen haendisch kopiert werden. dies liegt daran das sowohl bei der zuweisung (als auch im wesentlichen beim memcopy) das bitmuster von source nach dest kopiert wird: der zeiger-member, so definiert, zeigt dann zwar auf die gleiche adresse, aber die daten auf die gezeigt wird werden natuerlich nicht mit kopiert.)
(in c++ wuerde man einen copy ctor bzw. einen assignment operator definieren.)
WM_HOPETHISHELPS
thomas woelfer
(thomas woelfer)

this posting contains no tpyos.
bei Antwort benachrichtigen
benno thomas woelfer „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

Deinen Einwand mit den Member-Pointern halte ich für nicht praxisrelevant - jedenfalls in C. Es wird doch gar nicht erwartet, daß bei einer Struktur die Daten, auf die ein Pointer zeigt, mit kopiert werden - oder kannst Du an einem Beispiel aufzeigen, wo das der Fall ist. In C++ ist das anders, da ist es sozusagen postuliert, daß die Kopie eines Objektes ein komplettes Abbild darstellt.
benno
(benno)

bei Antwort benachrichtigen
thomas woelfer benno „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

kommt drauf an was man will - nehmen wir an du hast eine string implementierung die so aussieht:
typedef struct string
{
void* pData;
long cbData;
} String;
wenn man nun eine instanz einer solchen struktur kopiert: will man dann eine komplette kopie des strings oder will man nur eine kopie der struktur. meiner ansicht nach ist das eine frage der betrachtungsweise... nehmen wir dazu mal an es gaebe eine funktion
String* copy_string( const String* pSource);
erwartet man nun eine kopie des strings zurückzubekommen oder erwartet man eine kopie der struktur zurueckzubekommen die den string implementiert?
WM_MY0.02$
thomas woelfer
(thomas woelfer)

this posting contains no tpyos.
bei Antwort benachrichtigen
benno thomas woelfer „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

Exakt das macht den Unterschied zwischen C und C++ in der Behandlung von "Variablen" aus!
In C wirken die Operatoren nur für die in der Sprachdefinition festgelegten Datentypen vollständig, während man in C++ durch das operator overloading auch für selbstdefinierte Datentypen (Objekte) ein solches Verhalten erreichen kann.
In C also bekommt man bei der Zuweisung eines Aggregattyps definitionsgemäß nur eine bitgenaue Kopie der Variablen, in C++ dagegen ein eigenständiges Duplikat des Objekts. Daher muß das Objekt selbst "wissen", durch was es konstituiert wird und seine eigene Kopieroperation aufweisen - üblicherweise der copy constructor -, die dann durch den Zuweisungsoperator aufgerufen wird.
Dein Beispiel zeigt sehr schön, wie mühsam es werden kann, in C objektorientiert zu programmieren.
Gruß
benno
(benno)

bei Antwort benachrichtigen
benno B-Hoernchen „mein C-pointer ist nicht auf den Punkt zu Bringen“
Optionen

void esel_copy(esel_all von,esel_all *nach)
{
nach=von; // *********** hier ist das Problem ***********
}
void schlaumeier_copy(esel_all von,esel_all *nach)
{
*nach = von; // --- das ist die Lösung --- das Sternchen fehlt!
}
Übrigens übergibt kein Mensch eine Struktur 'by value' an eine Funktion, weil sie dazu komplett auf den Stack kopiert muß. Es wird immer mit Referenzen - also Pointern - gearbeitet, einer der Gründe, warum C schnell ist.
benno
(benno)

bei Antwort benachrichtigen