GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 18-May-2009, 13:45
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 802
Howard_L is a jewel in the roughHoward_L is a jewel in the roughHoward_L is a jewel in the rough

Swapping structures


I am confused about swapping defined structures , not so much swapping pointers to structures.
I'll explain within the following:
CPP / C++ / C Code:
#include <stdio.h>
#define MAXLEN 32  

typedef struct Player{ char name[MAXLEN], ngames, avg ; } PLAYER;

int print_players( PLAYER* pl_1, PLAYER* pl_2);

int main(void)
{
  PLAYER pl_1 =  { {"Bill"}, 2, 56 },
         pl_2 =  { {"Bob"},  4, 25 },
         pl_tmp= {     {0},  0,  0 },
         *pl_p;

  printf("\n  init\n");
  print_players( &pl_1 , &pl_2 );

  /* I was suprised to find that I could swap entire structure contents 
     using a third temp defined structure like this:                     */

  pl_tmp = pl_1;
  pl_1 = pl_2;
  pl_2 = pl_tmp;

  printf("  method 1 \n");
  print_players( &pl_1 , &pl_2 );

  /* That indicates to me that I am swapping the address which the 
     identifiers represent, no ???                                          

     ...so I figured I should be able to do the same thing using a pointer, 
     but I have NOT been able to figure how! doggit...  
     This is the most successful so far: */

  pl_p = &pl_1;
  pl_1 = pl_2;
  pl_2 = *pl_p;

  printf("  method 2 \n");
  print_players( &pl_1 , &pl_2 );

  return 0;
}

int print_players( PLAYER* pl_1, PLAYER* pl_2)
{
  printf("pl_1->name= %s  ngames= %d  avg= %d \n", 
                                         pl_1->name, pl_1->ngames, pl_1->avg);
  printf("pl_2->name= %s  ngames= %d  avg= %d \n\n", 
                                         pl_2->name, pl_2->ngames, pl_2->avg);
  return 0;
}
/*  ps: Actually I was trying method 2 first and that's where I noticed 
    that:  pl_1 = pl_2;   did the transfer correctly and led me to method 1.    */
The output from the above is:
Code:
decimal_arithmetic> gcc -Wall -W -pedantic swap_struct-1.c -o swap_struct-1 decimal_arithmetic> ./swap_struct-1 init pl_1->name= Bill ngames= 2 avg= 56 pl_2->name= Bob ngames= 4 avg= 25 method 1 pl_1->name= Bob ngames= 4 avg= 25 pl_2->name= Bill ngames= 2 avg= 56 method 2 pl_1->name= Bill ngames= 2 avg= 56 pl_2->name= Bill ngames= 2 avg= 56
So I'm really not sure about a couple of things.
1) Is method 1 a safe method or is it a quirk, as I said, I was suprised at the results since it's a whole structure instead of a single data like:
int a = 4, b;
b = a;

Like you can't assign an array like that (which to me is similar to a struct):
char s[]="hello', s2[32];
s2 = s;

...so why can I assign a struct, it doesn't seem right, unless it's an address, but so is an array identifier... see I' confused...

2) Is it possible to transfer object name reference addresses like: pl_1 = pl_2; ...using a pointer instead of defining a temp structure as the temporary storage?
(which would keep the code smaller)

I hope I made some kind of sense , the more I learn the stupider I feel..; ) , thanks
Last edited by Howard_L : 18-May-2009 at 14:16.
  #2  
Old 18-May-2009, 14:43
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,218
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: swapping structures


Quote:
Originally Posted by Howard_L
I am confused...

In order to exchange the values of two "somethings," with assignment statements you can do something like:
Code:
somethingelse = something1 something1 = something2 something2 = somethingelse

This, of course, does not work with arrays (Them's the rules of the language, and it is because the name of an array is actually a constant pointer whose value is the address of the first element of the array), but it does work with structs. It is part of the language. Really.

I hate to repeat myself, but unlike arrays, you can assign the entire contents of one struct to another with a simple assignment statement. See Footnote.

Your "method 1" is perfectly valid and works in C and, by default, in C++.

Your so-called "method 2" can't work, since you still only have two structs. You need that third "something" to be a "parking place" for the value of the first one before you assign the other's value to it.

Your code:

CPP / C++ / C Code:
  pl_p = &pl_1; /* Now, anything you do to *pl_p is doing it to pl_1 */
  pl_1 = pl_2;
  pl_2 = *pl_p;

Is equivalent to

CPP / C++ / C Code:
  pl_1 = pl_2;
  pl_2 = pl_1; /* since *pl_p is equal to pl_1 */

Sorry.

Regards,

Dave





Footnote. People always seem to want to do stuff like the following with arrays:

CPP / C++ / C Code:
    int a1[5];
    int a2[5];
    int temp[5];
.
.
.
    /* Fill a1 and a2 with some stuff */
.
..
    /* Now exchange the contents of a1 with the contents of a2 */
    temp = a1; /* But it will not work; can not work; never could work with arrays. */
    a1 = a2;
    a2 = temp;
You can make a loop to copy the elements one element at a time, or you can use something like the standard library function memcpy() to do the deed.

However, what if your arrays were members of a struct? You could have a struct whose only member is an array (or it could have other members as well).

CPP / C++ / C Code:
#include <stdio.h>

typedef struct {
    int x[5];
} intarr;

int main()
{
    intarr a, b, temp;
    int i;
    for (i = 0; i < 5; i++) {
        a.x[i] = i+1;
        b.x[i] = 11*(i+1);
    }
    printf("Initially:\n");
    printf("a = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", a.x[i]);
    }
    printf("\n");
    printf("b = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", b.x[i]);
    }
    printf("\n\n");

    /* Now exchange the contents of the structs */
    temp = a;
    a    = b;
    b    = temp;

    printf("After exchange:\n");
    printf("a = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", a.x[i]);
    }
    printf("\n");
    printf("b = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", b.x[i]);
    }
    printf("\n");
    
    return 0;
}
Output
Code:
Initially: a = 1 2 3 4 5 b = 11 22 33 44 55 After exchange: a = 11 22 33 44 55 b = 1 2 3 4 5

Hmmm...

Bottom line: Maybe "to you" an array is similar to a struct, but to a C (or C++) compiler they are different.

How about some post-bottom-line pedantry? Is that allowed?

If it is not allowed, then stop reading.

If anyone is still interested (and awake):

OK, here goes: (Got those No-Doz tablets ready? Or some of those great new Butterfinger candy bars that are laced with caffeine?)

Actually, all variable names are symbolic identifiers, and the variable name is associated with a memory address.

CPP / C++ / C Code:
int x;
.
.
.
x = 10;
The compiler allocates some memory, somewhere, that can hold an int.

The compiler lets you use the identifier "x" to refer to the contents of that memory location. No de-referencing is required (or allowed). That assignment statement tells the compiler to generate code that stores the integer "10" into the memory location associated with the identifier "x".

CPP / C++ / C Code:
int  *y = &x

Now, the variable y is a pointer whose value is the address of the variable x. If you do something with *y, it's doing it with x. The value of y can be changed so that it is equal to something other than the address of the variable x.

CPP / C++ / C Code:
int z[10]

Now the variable z is a pointer whose value is the address of the first element in the array of 10 ints. In this case z is a constant. In C and C++, it is absolutely forbidden, now and forevermore, to assign some other value to that instance of the variable z. Period. Full stop.

CPP / C++ / C Code:
struct some_struct xxx;

Now the identifier xxx is associated with the address in memory that holds the values of the elements of that struct. You can assign the value of another struct of the same type with an assignment statement.

So, as far as the language is concerned, the statement
CPP / C++ / C Code:
struct some_struct xxx;

Is more similar to
CPP / C++ / C Code:
int x;
than it is to
CPP / C++ / C Code:
int z[10];


Maybe a struct is similar to an array in some respects, but the statements that declare them and use them have quite different semantics.

And that really is the bottom line (for now).
Last edited by davekw7x : 18-May-2009 at 15:57.
  #3  
Old 18-May-2009, 20:39
TurboPT's Avatar
TurboPT TurboPT is offline
Senior Member
 
Join Date: Feb 2006
Location: Atlanta, GA
Posts: 1,140
TurboPT is a jewel in the roughTurboPT is a jewel in the roughTurboPT is a jewel in the rough

Re: swapping structures


Quote:
Originally Posted by davekw7x
...
OK, here goes: (Got those No-Doz tablets ready? Or some of those great new Butterfinger candy bars that are laced with caffeine?)
...
Lace, hell! I like to "fuel-up" with six snicker bars, a six pack of Jolt cola, with coffee, AND 357 magnum caffeine pills to 'boost' the effect. [just in case the Jolt+coffee doesn't quite cut it!]
__________________
Use the force...read the source!!
WYCIWYG -- what you code is what you get!
  #4  
Old 18-May-2009, 22:31
Howard_L Howard_L is offline
Regular Member
 
Join Date: Apr 2007
Location: Maryland/PA, USA
Posts: 802
Howard_L is a jewel in the roughHoward_L is a jewel in the roughHoward_L is a jewel in the rough

Re: Swapping structures


Quote:
Maybe "to you" an array is similar to a struct , but to a C (or C++) compiler they are different.
I said that because I think of a struct as a contiguous area of memory , like an array is. Different indeed, I am seeing that now.

I don't remember knowing that you could assign a struct. Maybe I did and it got pushed way back on the brain stack because usually I am manipulating values of a struct passed to a function for which we DO need to use address referencing. So this is all an awakening for me ...and a pleasant one at that. I find I can do this:
CPP / C++ / C Code:
int do_intarrstuff( intarr t ) /* creates local copy with identicle values! */
{
  int i ;

  printf("\nIn do_intarrstuff()  ...local copy: \n");
  for(i = 0; i < 5; i++)
  {
    printf(" %3d", t.x[i]);
    t.x[i] = 5;
  }
  printf("\nlocal changed values: \n");
  for(i = 0; i < 5; i++)
  {
    printf(" %3d", t.x[i]);
    t.x[i] = 7;
  }
  return 0;
}
...and call it from the end of your program:
CPP / C++ / C Code:
   ...
    printf("b = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", b.x[i]);
    }
    printf("\n");

    do_intarrstuff(b);

    printf("\n\nback in main() (note values are unchanged) \nb = ");
    for (i = 0; i < 5; i++) {
        printf("  %3d", b.x[i]);
    }
    printf("\n");
    return 0;
}
and it works fine and gives this output:
Code:
b = 1 2 3 4 5 In do_intarrstuff() ...local copy: 1 2 3 4 5 local changed values: 5 5 5 5 5 back in main() (note values are unchanged) b = 1 2 3 4 5
So this is good to know. In fact I can put it to work right away!. Thanks for straightening me out.,
Howard++;
 
 

Recent GIDBlogAccepted for Ph.D. program by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Help needed with structures moody C Programming Language 4 08-Mar-2008 10:52
Strings, Pointers, and Printing Alphabetically NeRdHeRd C Programming Language 6 25-Dec-2007 13:37
How Do I Create a Function that returns a usable array of pointers to structures? UncleRic C Programming Language 2 03-Sep-2007 12:17
Could anyone suggest an easy to read book on Data Structures aijazbaig1 C Programming Language 1 06-Oct-2006 12:31
DMA for Structures wu_weidong C Programming Language 1 05-Apr-2005 05:18

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 13:05.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.