struct nicht ändern



  • Wie zwei anlegen.
    ich will doch nur das übergebene kopieren und dann
    das kopierte ändern.

    Das funktioniert aber nicht.



  • struct supi {
      long 1;
      long 2;
      long 3;
    };
    
    struct supi mach_was_mit(struct supi obj) {
      obj.1 = 24;
      obj.2 = 24;
      obj.3 = 24;
    
      return obj;
    }
    
    int main() {
      struct supi edgar;
      struct supi changed;
      edgar.1 = 1;
      edgar.2 = 3;
      edgar.3 = 2; 
    
      changed = mach_was_mit(edgar);
    
      return 0;
    }
    


  • zeig mal source



  • OK habs selber hingekriegt.
    Hab das struct einfach vorher kopiert in der main.
    Hab es vorher immer in der Funktion versucht.
    Trotzdem vielen Dank für die schnellen Antworten.

    Hätte aber noch eine ander Frage:
    Wie kann ich das struct speichern und laden?



  • fopen
    fwrite, fread
    EDIT: fclose 🙂



  • Das kopieren funktioniert doch noch nicht.
    Hier mal mein Code.
    Ich möchte, das die Funktion simplex ausgeführt wird aber das struct nicht verändert wird. Das macht es aber. Da wenn ich danach auf anzeigen gehe das geänderte struct erscheint.
    Hab schon versucht es vorher in ein neues struct y zu kopieren. es ändert aber trotzdem das struct x.

    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <math.h>
    
    struct simplex {
    
    	double *zf;
    	char opt[3];
    	double **A;
    	double *b;
    	int *rel;
    	int gl,var;
    
    }x,y;
    
    void simplex(struct simplex x);
    struct simplex eingeben();
    void anzeigen(struct simplex);
    double minimum (double min[],int length);
    int pivotspalte(double min[],int length);
    
    void main(void) {
    
    char a,c;
    
    	do 	{
    
    	fflush(stdin);
    	printf(">>>>>>>>>>>>>>>>>>>>Simplex - Algorithmus<<<<<<<<<<<<<<<<<<<<\n\a");
    	printf("\nOptimierungsaufgabe eingeben (1) :");
    	printf("\nOptimierungsaufgabe anzeigen (2) :");
    	printf("\nSimplexalgorithmus starten   (3) :");
    	printf("\n\nAuswahl: ");
    	scanf("%c",&c);
    
    	switch(c) 	{
    
    		case '1': 	x=eingeben();
    					break;
    		case '2':	anzeigen(x);
    					break;
    		case '3':	y=x;
    					simplex(y);
    					break;
    
    				}
    
    	fflush(stdin);
    	printf("Moechten sie Weitermachen?");
    	scanf("%c",&a);
    	system("cls");
    
    		}
    
    		while(a=='J');
    }
    
    void simplex(struct simplex x) {
    
    double zfw=0;
    int nbv[x.var];
    int bva[x.gl];
    double g[x.var]; //Formkoeffizienten
    double q[x.gl]; //Formkoeffizienten
    double bv[x.gl]; //Basisvariablen
    int ps;	//Pivotspalte
    int pz;	//Pivotzeile
    
    for(int i=0;i<x.var;i++)
            g[i]=-1*x.zf[i];
    
    for(int i=0;i<x.gl;i++)
    		bv[i]=0;
    
    for(int i=0;i<x.var;i++)
    		nbv[i]=i;
    
    for(int i=0;i<x.gl;i++)
    		bva[i]=x.var+i;
    
    while(minimum(g,sizeof(g)/sizeof(double))<0)
    {
    
    	getchar();
    
    	ps=pivotspalte(g,sizeof(g)/sizeof(double));
    
    	for (int n=0;n<x.gl;n++)
    	{
    		if(x.A[n][ps]>0)
    			q[n]=x.b[n]/x.A[n][ps];
    		else
    			q[n]=10000;
    	}
    	pz=pivotspalte(q,sizeof(q)/sizeof(double));
    
    	printf(" 0  ");
    
    	printf("       NBV |");
    
    	for (int n = 0; n < x.var; n++)
    	printf("     x[%i]  ",nbv[n]);
    	printf("|      b[i]    ");
    	printf("   q[i]");
    
    	printf("\n");
    
    	printf(" BV %+10.3lf |",-1.);
    
    	for (int n = 0; n < x.var; n++)
    	printf("%+10.3lf ",x.zf[n]);
    	printf("|\n\n");
    
     	for (int n = 0; n < x.gl; n++)
    	{
    		printf("x[%i]%+10.3lf |",bva[n],bv[n]);
    
          	for (int m = 0; m < x.var; m++)
             	printf("%+10.3lf ",x.A[n][m]);
    
    		printf("| %+10.3lf ",x.b[n]);
    		printf("%+10.3lf",q[n]);
    		printf("\n");
        }
    
    	printf("\n");
    	printf("g[i]           |");
    
       	for (int n = 0; n < x.var; n++)
    	{
      	 	printf("%+10.3lf ",g[n]);
    	}
    
    	printf("| %+10.3lf ",zfw);
    
    	//Kreisregel
    	for (int j = 0; j < x.var; j++)
    	{
    		if(j!= ps)
    		g[j]=g[j]-x.A[pz][j]*g[ps]/x.A[pz][ps];
    	}
    
    	for (int i = 0; i < x.gl; i++)
    	{
    		if(i!=pz)
    		{
    			x.b[i]=x.b[i]-x.b[pz]*x.A[i][ps]/x.A[pz][ps];
    		}
    	}
    
    	for (int i = 0; i < x.gl; i++)
    	{
        	for (int j = 0; j < x.var; j++)
    		{
    			if(i!=pz && j!= ps)
    			{
    			  x.A[i][j]=x.A[i][j]-x.A[pz][j]*x.A[i][ps]/x.A[pz][ps];
    			}
    		}
    	}
    
    	zfw=zfw-x.b[pz]*g[ps]/x.A[pz][ps];
    
    	//Spaltenelemente
    	for(int i = 0; i < x.gl; i++)
    	{
    		if(i!=pz)
    		{
    			x.A[i][ps]=-x.A[i][ps]/x.A[pz][ps];
    
    		}
    	}
    
    	g[ps]=-g[ps]/x.A[pz][ps];
    
    	//Zeilenelemente
    	for(int i = 0; i < x.var; i++)
    	{
    		if(i!=ps)
    		{
    			x.A[pz][i]=x.A[pz][i]/x.A[pz][ps];
    		}
    	}
    
    	x.b[pz]=x.b[pz]/x.A[pz][ps];
    
    	x.A[pz][ps]=1/x.A[pz][ps]; //Pivotelement
    
    	printf("\n\n");
    
    }
    
    getchar();
    printf("\n");
    printf(" 0  ");
    
    	printf("       NBV |");
    
    	for (int n = 0; n < x.var; n++)
    	printf("     x[%i]  ",nbv[n]);
    	printf("|      b[i]    ");
    	printf("   q[i]");
    
    	printf("\n");
    
    	printf(" BV %+10.3lf |",-1.);
    
    	for (int n = 0; n < x.var; n++)
    	printf("%+10.3lf ",x.zf[n]);
    
    	printf("|\n\n");
    
     for (int n = 0; n < x.gl; n++) {
    	 	printf("x[%i]%+10.3lf |",bva[n],bv[n]);
    
          for (int m = 0; m < x.var; m++)
             printf("%+10.3lf ",x.A[n][m]);
    	 	 printf("| %+10.3lf ",x.b[n]);
    
    		printf("\n");
         }
     	printf("\n");
    
    	printf("g[i]           |");
    
       for (int n = 0; n < x.var; n++){
      	 printf("%+10.3lf ",g[n]);}
    	 printf("| %+10.3lf ",zfw);
    
    }
    
    double minimum (double min[],int length) //gibt das kleinste Elemente eines Arrays zurück
    {
    	double m=min[0];
    	int i=0;
    	for (i=1;i<length;i++)
    		if(min[i]<m)
    			m=min[i];
    
    return m;
    }
    
    double maximum (double max[],int length) //gibt das größte Elemente eines Arrays zurück
    {
    	double m=max[0];
    	int i=0;
    	for (i=1;i<length;i++)
    		if(max[i]>m)
    			m=max[i];
    
    return m;
    }
    
    int pivotspalte(double min[],int length) //gibt den Indize des kleinsten Elementes eines Arrays zurück
    {
    int i;
    int ps=0;
    double m=min[0];
    for (i=1;i<length;i++)
    		if(min[i]<m){
    			m=min[i];
    			ps=i;
    		}
    	return ps;
    }
    
    struct simplex eingeben() {
    
    struct simplex s;
    int i=0,j=0;
    
    printf("Wie viele Variablen benoetigen Sie : ");
       scanf("%d", &s.var);
       fflush(stdin);
       s.zf = (double *)malloc(s.var*sizeof(double));
       if( NULL == s.zf ) {
          printf("Fehler bei malloc....\n");
       }
       while( i < s.var ) {
          printf("Koeffizient fuer x[%d] eingeben : ", i);
          scanf("%lf", &s.zf[i]);
    	  fflush(stdin);
          i++;
       }
       printf("\nDies ist Ihre Zielfunktion\n\n");
       for(i=0; i < s.var; i++)
          printf("+ %.3lf *x[%d] ",s.zf[i],i);
    
     	fflush(stdin);
    
    	printf("\n\nSoll diese maximiert(max) oder minimiert(min) werden?: ");
    	scanf("%c ",&s.opt);
    
    	fflush(stdin);
    
       printf("Wie viele Ungleichungen : ");
       scanf("%i", &s.gl);
    
     	s.b = (double *)malloc(s.gl*sizeof(double)); //Speicher für rechte Seite
    	s.rel=(int *)malloc(s.gl*sizeof(int)); //Speicher für Relation
    
       /* Speicher reservieren für die double-Zeiger (=zeile) */
       s.A = (double **)malloc(s.gl * sizeof(double *));
       if(NULL == s.A) {
          printf("Kein Virtueller RAM mehr vorhanden ... !");
    
       }
       /* Jetzt noch Speicher reservieren für die einzelnen Spalten
        * der i-ten Zeile */
       for(int x = 0; x < s.gl; x++) {
          s.A[x] = (double *)malloc(s.var * sizeof(double));
             if(NULL == s.A[x]) {
                printf("Kein Speicher mehr fuer Zeile %d\n",x);
    
             }
       }
    
      while(j<s.gl){
    
    	  printf("%i. Gleichung:\n",j+1);
    
    	  for(i=0;i<s.var;i++){
    		printf("Koeffizient[%i,%i] ",j,i);
          	scanf("%lf",&s.A[j][i]);
    	}
    		printf(" 1 fuer <= eingeben\n-1 fuer >= eingeben: ");
    		scanf("%i",&s.rel[j]);
    		printf("Rechte Seite eingeben: ");
    		scanf("%lf",&s.b[j]);
    	  j++;
    
    }
    
    return s;
    }
    
    void anzeigen(struct simplex s){
    
        /* Inhalt der Matrix entsprechend ausgeben */
       for (int x = 0; x < s.gl; x++) {
          for (int y = 0; y < s.var; y++)
             printf("%+.3lf *x[%i] ",s.A[x][y],y);
    	 	 printf("<= ");
    		 printf("%+.3lf",s.b[x]);
    
          printf("\n");
       }
    
    }
    


  • Hi mic7781 es wundert mich, dass Dein Compiler das Programm ohne zu murren schluckt!
    Du solltest Dir vielleicht überlegen Funktionen nicht so zu nennen, wie Datentypen, bzw. Strukturen, die Du definiert hast. (struct simplex <-> void simplex( struct simplex x) )
    In der Funktion void simplex(struct simplex x) schreibst Du folgendes:

    void simplex(struct simplex x) {
    
    double zfw=0;
    int nbv[x.var];
    int bva[x.gl];
    double g[x.var]; //Formkoeffizienten
    double q[x.gl]; //Formkoeffizienten
    double bv[x.gl]; //Basisvariablen
    

    Du kannst Arrays nicht mit einer Variablen in der Klammer deklarieren, lediglich mit Konstanten. Wenn Du trotzdem die Größe bei jedem Durchlauf neu definieren willst musst Du malloc benutzen.

    int *nbv;
    nbv = (int *) malloc( x.var * sizeof( int ) );
    if( !nbv )
        /* Fehlerbehandlung durchführen */
    

    Ich bezweifle, dass es mit dem Kopieren nicht funktioniert.

    switch(c)     {
    
            case '1':     x=eingeben();
                        break;
            case '2':    anzeigen(x);
                        break;
            case '3':    y=x;
                        /* HIER AUSGABE!!! */
                        simplex(y);
                        /* HIER AUSGABE!!! */
                        break;
    
                    }
    

    Der Funktion simplex wird ja nicht die Struktur y, sondern eine Kopie der Struktur übergeben. Lass' Dir einfach mal vor und nach dem Funktionsaufruf, die Struktur y ausgeben.Dann wirst Du sehen, dass sich daran gar nichts ändert. DIe Änderungen werden nur an der Kopie gemacht, die die Funktion simplex übergeben bekommt.

    Happy coding



  • Hab das mit dem Anzeigen schon versucht nach dem Kopieren.
    Es funktioniert aber wirklich nicht mit dem kopieren. Es ändert trotztdem
    das andere struct.



  • Sketcher schrieb:

    Du kannst Arrays nicht mit einer Variablen in der Klammer deklarieren, lediglich mit Konstanten.

    Das stimmt seit C99 nicht mehr. Stichwort VLA.

    @ mic7781

    struct simplex * structCopy(struct simplex *src){
        struct simplex *dest;
        dest=malloc(sizeof(struct simplex));
        if(dest){
            memcpy(dest,src,sizeof(struct simplex));
            return dest;
        }
        else return NULL;
    }
    

    So kannst du das Dingens doch einfach kopieren. Du übergibst einen Zeiger auf die Struktur die kopiert werden soll und bekommst einen Zeiger auf die kopierte Struktur zurück (oder evtl. NULL). Nicht vergessen den Speicher wieder mit free() freizugeben.



  • @TactX:
    Da hänge ich wohl etwas hinterher 😮 Ich sollte nicht nur meinen Rechner sondern auch ab und zu meinen Kopf auf den neuesten Stand bringen...

    @mic7781:
    Mir ist eine Sache aufgefallen, an der es liegen könnte. Ich hatte vorher übersehen, dass die Strukturen in der Datei global deklariert sind.
    Probiers mal damit:

    struct simplex {
    
        double *zf;
        char opt[3];
        double **A;
        double *b;
        int *rel;
        int gl,var;
    /* Änderung !!! */
    };
    /* Änderung !!! */
    
    void simplex(struct simplex x);
    struct simplex eingeben();
    void anzeigen(struct simplex);
    double minimum (double min[],int length);
    int pivotspalte(double min[],int length);
    
    void main(void) {
    /* Änderung !!! */
    struct simplex x, y;
    /* Änderung !!! */
    
    char a,c;
    /* ... */
    

    Damit hast Du die Strukturen lokal in der main deklariert und solltest auch keine Probleme mehr damit haben, dass Deine Strukturwerte überschrieben werden. Dann kannst Du Dir das Struktur-kopieren auch sparen.
    Happy coding!


Anmelden zum Antworten