More a C question, passing variables

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lets say I have my main program, inside the main forever loop:

while(1)		//main loop
	{//Main loop------------------------------------
		
		while( position < 1 ){
			calcPosition();}

		if( position )
			stopGearbox();

	}//Main loop------------------------------------

The functions are prototyped in the main program before the loop in entered where position and f1 are declared.

The functions are as follows:

calcPosition(){	
	cli();
	if( f1!= TS )
		if(TS){
			position = position + 1;
			f1 = TS;}
	sei();	}

stopGearbox(){
	cli();
		position = 0;
		PORTD &= ~(1<<6);
	sei();	}	

Now I realize these functions are not setup up correctly, that's what I don't clearly understand. I know that passing by variable passes a "copy" of the variable and passing by reference passes the value itself so it can be altered. To pass more than 1 value I would have to pass by reference. But what I am not clear on is the what goes before the function(such as char, void) and what goes in the parenthesis and what exactly those mean for the function. From what I understand is if I said char stopGearbox();, that means the function stop gearbox will return a char. If I said stopGearbox(char x); that means a char is passed into the function which can be defined in the main program? Its a little fuzzy, so I'm looking for clarification.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while( position < 1 ){
     calcPosition(&position);
}
void calcPosition(type * ptr_to_position){    
   cli(); 
   if( f1!= TS ) 
      if(TS){ 
         *ptr_to_position = *ptr_to_position + 1; 
         f1 = TS;
      } 
   sei();   
}

replace 'type' with whatever type 'position' is defined as.

This is passing by reference - where it's not what's in 'position' that is passed to the routine but the address of (&) the variable.

Then within the routine it does not deal with position itself but a pointer to it (ptr_to_position) and the * operator tells it to then access what's at that address so it's reading and updating the copy that the caller was using.

Cliff

PS I think you got your "by value" and "by reference" interpretation the wrong way round above

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
To pass more than 1 value I would have to pass by reference.

You can pass as many variables as you want. You can only pass back one variable without passing by reference. However, the variable that you pass back can contain many values since you can pass back arrays and structs.

Quote:
PS I think you got your "by value" and "by reference" interpretation the wrong way round above

Not the wrong way round, just not really with the correct terminology.
Quote:
I know that passing by variable passes a "copy" of the variable and passing by reference passes the value itself so it can be altered.

I would state that as: Passing value passes a copy of the variable and passing by reference passes the address of the variable so it can be altered.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:

You can pass as many variables as you want. You can only pass back one variable without passing by reference. However, the variable that you pass back can contain many values since you can pass back arrays and structs.

You can return structs but you can't return arrays. Not directly at least. You can return an array in a struct though.

/* Struct wrapping array */
struct array_t {
    int a[5]; /* Fixed length array */
};

/* Function returns structure */
struct array_t foo()
{
    struct array_t tmp;
    int n;

    for(n=0;n<5;n++)
    {
        /* Have to access array via struct */
        tmp.a[n] = n;
    }

    return tmp;
}

int main(int argc, char *argv[])
{
    int n;
    struct array_t rval;
    rval = foo();

    for(n=0;n<5;n++)
    {
        /* again, have to access array via struct */
        printf("rval.a[%d] =  %d",n,rval.a[n]);
    }

    return 0;
}

The above however is somewhat ugly.

If you need to return an array the easiest way is to simply pass it in. Arrays in C are passed by reference by default so any changes made to the array will be visible from the caller.

void foo(int a[5])
{
    int n;

    for(n=0;n<5;n++)
    {
        a[n] = n;
    }
}

int main(int argc, char *argv[])
{
    int n;
    int a[5];

    foo(a);

    for(n=0;n<5;n++)
    {
        printf("a[%d] = %d \n",n,a[n]);
    }

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

but you can't return arrays

But you can easily return a pointer which can be used via array access. For example:

char string[] = {"Hello World"};

char * p;
char c;

p = strchr(string, 'W');
c = p[2]; // c gets 'r'

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP needs to pass some money to get a C textbook in return. :wink:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

But you can easily return a pointer which can be used via array access.

Yep, for sure, but I was trying to avoid pointers for the sake of the OP (or at least hide the pointer stuff) :)

Returning pointers have a few nuances I didn't want to confuse the OP with. For instance a common newbie mistake is this:

char *foo()
{
    char str[] = "Hello, World!";
    return str;
}

This looks like it should return the array but we both know it won't. At least not safely.

Pointers, both the blessing and curse of C.