# Help with a simple function in C



## robrobrob (Apr 29, 2006)

I am having some difficulties writing a simple function for a program I am writing. The program is a card game, and I have a struct defined as follows:

typedef struct {int rank; char suit;} card;

I am trying to write a function that will swap the values of 2 variables of type card.  My efforts so far look like this:

void SwapCards (card *card1, card *card2)
{
	card temp_card;

	temp_card = *card1;
	*card1 = *card2;
	*card2 = temp_card;
}

the problem is that this does not work.

I have tried using it as follows:

card card10, card20;

card10.suit='c';
card10.rank=12;
card20.suit='d';
card20.rank=10;

SwapCards(*card10, *card20);

Please tell me I don't need to declare pointer variables pointing to a variable of type card to make this work.  If I have to assign everything to a new variable just to pass it to a function, it defeats the convenience of the function. I have a number of 'card' variables that are already in use, and I suddenly need to just swap some values for a variant in the game.  It would be a real hassle to not be able to use such a function.

THanks for any help.

rob


----------



## Mikuro (Apr 30, 2006)

It looks like the problem is in the way you call the function. An * is used to resolve a pointer, which isn't what you want here. You want to do exactly the opposite &#8212; get a pointer to an object. To do that, use an &. i.e., _SwapCards(&card10, &card20);_

I think that'll make it work fine.


----------



## robrobrob (Apr 30, 2006)

worked perfectly.  THanks.  

Can you reccommend a good reference on pointers.  I seem to have shaky knowledge there, and I have yet to find a reference.

rob


----------



## Garulfo (May 14, 2006)

This is a better design for your function

```
void SwapCards (card &card1, card &card2)
{
    card temp_card;

    temp_card = card1;
    card1 = card2;
    card2 = temp_card;
}
```

and this is the example

```
card card10, card20;

card10.suit='c';
card10.rank=12;
card20.suit='d';
card20.rank=10;

SwapCards(card10, card20);
```

Note that actual parameters card10 and card20 are not preceed by an * anymore. They are not preceed by an & also. 
It is more esthetic and, therefore, its a better design. QED.


----------



## Mikuro (May 15, 2006)

robrobrob said:
			
		

> worked perfectly.  THanks.
> 
> Can you reccommend a good reference on pointers.  I seem to have shaky knowledge there, and I have yet to find a reference.


Hmm. I can't find anything about pointers in my bookmarks, but some good general-purpose reference sites are http://www.macdevcenter.com and http://www.cocoadev.com

Aside from that, I recommend getting a basic C (not C++) book. I'm really not a book person myself, but I have some old C books that I've found to be useful for learning about basic things like pointers, arrays, etc. since I started using Cocoa. The problem with a lot of Mac development sites is that they don't cover these basics, instead focusing on the new parts of Objective-C and the Cocoa framework.


----------



## Viro (May 15, 2006)

Garulfo said:
			
		

> Note that actual parameters card10 and card20 are not preceed by an * anymore. They are not preceed by an & also.
> It is more esthetic and, therefore, its a better design. QED.



If I had to maintain code like that, I would have the author shot at dawn and strung up in the village square to serve as an example .

You may have removed the pesky * and & notation of pointers, but they are there for a reason. They help you know when you are passing a variable to a function by reference as opposed to when it is being passed by value. This is an important distinction to make, and is not immediately obvious from the code you've just written. Imagine someone coming your function. It isn't obvious that after the call to SwapCards, card10 and card20 will each hold different values. In order to know this, you need to look at the actual definition of the function SwapCards, which can be a very tedious thing to do if you have a lot of other functions lying about. Whereas a function like SwapCards(&card10, &card20) immediately alerts you to the fact that card10 and card20 are passed by reference.

It is generally considered bad practice to pass a variable using C++ references if you are intending to modify the value of that variable. Instead, you should us a pointer. Reference variables are usually used when wanting to pass a variable to a function by reference, but to ensure that the value of that variable isn't modified after the call to the function succeeds.

Long contorted explanation, but it is something you need to get clear about


----------



## Garulfo (May 26, 2006)

Viro said:
			
		

> If I had to maintain code like that, I would have the author shot at dawn and strung up in the village square to serve as an example .
> 
> You may have removed the pesky * and & notation of pointers, but they are there for a reason. [...]Whereas a function like SwapCards(&card10, &card20) immediately alerts you to the fact that card10 and card20 are passed by reference.
> 
> ...



I don't agree with you.
As you could easily find in many manuals (Friedmann or Goodrich or Deitel for example) the more important is not the symbol uses during programmation but the clean explanation you have to do in comments. 
If you use a function named swap, it is your task to read documentation. If the documentation is well-writed there is no problem anymore. If the developper is bad enough to avoid reading documentation and don't know the function he's using, a '&' will not help him.

There is no problem to maintain code write with good documentation and comments. If it is not (well documented) this kind of element is not self-sufficient and the developper could be consider as a bad one.

The reason why the * and the & is there is because c++ is a bad low-level language (ok ok it's my opinion ). However, it is a bad habit to try to distinguished this two levels with syntactic element like '&'. It must stay in a high level. I don't know many manual that recommend to use pointers instead of call by reference for documentation issue. In fact I don't remember anyone. All colleagues I know teach the use of documentation instead of syntactic memo. 

But I understand your point of view.


----------



## lurk (May 26, 2006)

The problem with good documentation and comments is that they are a mythical creatures like the elusive unicorn that have been reported by travelers to exotic lands but never seen in the flesh.

It is almost a universal axiom that if you have time to properly sync-up your code and comments you will be assigned more work until this is no longer true.


----------



## Viro (May 29, 2006)

Garulfo said:
			
		

> I don't agree with you.
> As you could easily find in many manuals (Friedmann or Goodrich or Deitel for example) the more important is not the symbol uses during programmation but the clean explanation you have to do in comments.


Ah... that's the problem . Get some better books as my experience with Deitel&Deitel has been poor to say the least. If you want to be a good C++  programmer, Meyer, Sutter and Alexandrescu are authors you must read. Those books you quoted are good on general problem solving, but they aren't really the books on widely accepted good practices in using C++.



> There is no problem to maintain code write with good documentation and comments. If it is not (well documented) this kind of element is not self-sufficient and the developper could be consider as a bad one.


This assumes that good comments and documentation was written. How often does that ever happen?



> The reason why the * and the & is there is because c++ is a bad low-level language (ok ok it's my opinion ). However, it is a bad habit to try to distinguished this two levels with syntactic element like '&'. It must stay in a high level. I don't know many manual that recommend to use pointers instead of call by reference for documentation issue. In fact I don't remember anyone. All colleagues I know teach the use of documentation instead of syntactic memo.
> 
> But I understand your point of view.


The problem is code needs to be self explanatory. If you are maintaining code, it is much easier to read the code and get an idea of what it does, than to keep on referring back to the documentation. Ever read a novel in a language you weren't familiar with and had to keep referring to the dictionary every few words? Breaks the flow of thought, and greatly reduces your speed. (Poor analogy, I know but it does illustrate the point somewhat)

It doesn't matter if they are heaps of documentation. Having a & in front of a variable name is a much more succinct way of alerting the programmer to the fact that the variables are passed via reference, and the value of the variable will be different after the method call. Contrast that to having to read the comments (assuming they are present!), and then reading through the documentation, which doesn't guarantee that the programmer will pick up on the fact that the value of the variable will change after the function call. Programmers are usually overworked and tired, and anything that makes maintaining that code easier, is usually welcomed.


----------



## Garulfo (Jun 3, 2006)

Viro said:
			
		

> Ah... that's the problem . [...] If you want to be a good C++  programmer[...]



Hum... you should get more information about me, before doing this kind of remarks.
I was a programmer when you were a cute little baby 
(you may be still cute, but you're not a baby anymore)
And now I teach programmers to become better designer and programmer.

However, as i said if i do not completly agree with you I understand your point of view.
And it is clearly not stupid.


----------

