Solved

Parameter Passings

Posted on 2003-11-01
18
381 Views
Last Modified: 2010-04-15
Can someone explain to me about these? I am kind of confused with these different types of passing parameters. These are what i thought...

Call-By-Value

public int getSum(int n)
{
   int i = n;
   i++;
   return i;
}

// so obviously formal parameter is assigned to be a local variable (is this the right way of saying?) and actual parameter is never changed.


Call-By-Result

public int getSum(int n)
{
   i++;
   n = i;
   return n;
}

//I donno if this is correct...So actual parameter get changed??


Call-By-Result-Value

public int getSum(int n)
{
   int i = n;
   i++;
   n = i;
   return n;
}


// is this correct????



Call-By-Name

Now what is this call-by-name thing???



Also, for Call-By-Reference, to pass an array, do we do like this?

a[1] = 'a';
int *p = &a[0];
getSum(p); //is this the correct way?? Does it mean just passing the address of the first element in?
getSum(a); //what about this? does this mean passing the whole array into the function? or the first element only?

public int getSum(int *n)
{
   int sum = 0;
   sum = sum + n;
   n++; //does this work? since n is a pointer...i tot it would~  
}



0
Comment
Question by:jtcy
18 Comments
 
LVL 4

Assisted Solution

by:brunomsilva
brunomsilva earned 166 total points
ID: 9663356
This sounds like homework...

public int getSum(int n)
{
   int i = n;
   i++;
   return i;
}

Here n is considered to be a local variable as you said, so if you call getSum as getSum(variable), variable will not be affected. You have to assign the result to some variable like: sum = getSum(variable).

public int getSum(int n)
{
   i++;
   n = i;
   return n;
}

This won't work unless you have i defined elsewhere. if it is it will return (i+1)

public int getSum(int n)
{
   int i = n;
   i++;
   n = i;
   return n;
}

This will do the same as the first function since you return the same value. n is a local variable with the same value as i.

Call-By-Name

I have no idea what this is.

Call-by-reference

since an array is a pointer itself you can just pass it as an argument which will be by reference. if you change the value of a inside getSum(a) this will change its global value.

int a[3] = {1,2,3}

void getSum2(int *n)
{
   (*n)++;
}

int main() {
   getSum2(&a[0]);
}

this will increase a[0] to 2.

cheers,
 bruno
0
 
LVL 5

Accepted Solution

by:
snehanshu earned 168 total points
ID: 9663403
>>Call-By-Value
>>// so obviously formal parameter is assigned to be a local variable (is this the right way of saying?) and actual parameter is never changed.
Yes, you could say that.

>>Call-By-Result
//I donno if this is correct...So actual parameter get changed??
No, this is the same as Call-By-Value, but in this case, you are returning the changed value of n. So, if you call getSum as
int myretval, myparam;
myparam = 40;
myretval = getSum(myparam)
then myparam remains unchanged, but myretval becomes 41.


>>a[1] = 'a';
>>int *p = &a[0];
>>getSum(p); //is this the correct way?? Does it mean just passing the address >>of the first element in?
here, a is an array of characters (or integers: whatever).
When you say int *p = &a[0]; you are initializing pointer p to contain the address of the first element of array a.
arrays are continuous blocks of memory location. a is the pointer to (address of) the first memory location assigned for the array. a[n] means the value contained at address (a + n)
& returns the address of a variable. so, &a[0] means the address of the first location of a. so, in effect it is the same as a.
Also, there is nothing like passing a whole array. When you "pass an array", you essentially pass the address of the starting location. This results in "the whole aray" being accessible to the function.

Hope that this makes some sense to you.
...Snehanshu
P.S.
You have too many open questions :-)
0
 
LVL 23

Assisted Solution

by:brettmjohnson
brettmjohnson earned 166 total points
ID: 9663437
> Call-By-Value
>
> public int getSum(int n)
> {
>   int i = n;
>   i++;
>  return i;
> }
>
> // so obviously formal parameter is assigned to be a local variable (is this the right way of saying?)
> and actual parameter is never changed.

Mostly right.  Your understanding is correct, although syntax is a bit off.  Keyword "public" is not ANSI C.
(although it is a C++ keyword).  The local variable is not really necessary.  This is the equivalent:

int getSum(int n)
{
      return n+1;
}


> Call-By-Result
>
> public int getSum(int n)
> {
>   i++;
>   n = i;
>   return n;
> }

Never heard of "Call-by-Result".  In this case, the variable i is undefined and uninitialized.
However, in all your questions, you don't touch on the real nature of Call-By-Value.  The
called routine may modify that value all it wants, but the original value (from the caller's
perspective) does not change.  For instance, try this:

#include <stdio.h>

int funcByValue(int a)
{
  a += 5;
  printf("funcByValue changes the value of a to %d\n", a);
  return a;
}


int funcByReference (int *a)
{
  *a += 5;
  printf("funcByReference changes the value of a to %d\n", *a);
  return *a;
}

int main ()
{
  int a = 1, b = 0;
  printf("main initializes the value of a to %d\n", a);
  b = funcByValue(a);
  printf("after calling funcByValue the value of a is %d\n", a);
  printf("after calling funcByValue the value of b is %d\n", b);
  b = funcByReference(&a);
  printf("after calling funcByReference the value of a is %d\n", a);
  printf("after calling funcByReference the value of b is %d\n", b);
  return 0;
}


> Call-By-Name
>
> Now what is this call-by-name thing???

I have never heard of "Call-by-Name"


> Also, for Call-By-Reference, to pass an array, do we do like this?
> a[1] = 'a';
> int *p = &a[0];
> getSum(p); //is this the correct way?? Does it mean just passing the address of the first element in?

Yes, that is correct, although you do not need the intermediate variable p.  The following is sufficient:
getsum ( &a[0] );

> getSum(a); //what about this? does this mean passing the whole array into the function? or the first element only?

A little vocabulary:
An "atomic" data type are the simplest data types in C.  The atomic data types in C are int, short, long, char, float, double, enum and pointer (and their unsigned versions).  This includes any user-defined types that are typedefs of these atomic types (such as size_t, off_t, etc).  ANSI-C implicitly passes all atomic data types by value.
A "complex" data type is constructed of one or more atomic data types and other compex data types.  Complex data types are arrays, structures, and unions.  ANSI-C implicitly passes all complex data types by reference.

Pointers and Arrays: http://www.strath.ac.uk/IT/Docs/Ccourse/subsection3_9_4.html#SECTION0009400000000000000
In ANSI-C pointers and arrays are interchangable.  See the above link or read Chapter 5 in Kernighan & Richie's "The C Programming Language".
So the values of a and &a[0] are identical.  So passing a to a function actually passes the address of the first element of a to that function. The called function can use that address to access all elements of the array.

0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9663523
brettmjohnson,
>>Complex data types are arrays, structures, and unions.  ANSI-C implicitly passes all complex data types by reference.
Aren't structures and unions passed by value?
...Snehanshu
0
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 9663576
> Aren't structures and unions passed by value?

Not in ANSI C.  The called routine gets a pointer to the structure.

0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9663945
brettmjohnson,
For this code:
#include <stdio.h>

struct mystruct
{
  int a;
};

int mytest(mystruct mytmp)
{
  mytmp.a *= 10;
  printf("%d\n", mytmp.a);
  return mytmp.a;
}

int main()
{
  mystruct myvar;
  myvar.a = 10;
  printf("%d\n", myvar.a);
  mytest(myvar);
  printf("%d\n", myvar.a);
  return 0;
}

Which C compiler produces the output
10
100
100
because that should happen if address of structure is passed. I get
10
100
10
in visual studio 2002 .net (after a few tweaks).
Also I couldn't find any mention of structures being passed as addresses in ISO/IEC 9899 (ANSI C standard). It talks only about arays.
6.5.2.2: Function calls note 78 and 6.9.1
...Snehanshu
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 9664977
i agree with snehanshu, structures are passed by value,..arrays  by the address..
if strucures were passed by address by default, then u wouldnt see standard library functions using pointers to structures...and i feel its understood here whats the cost of letting the structures passed by value.
akshay
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 5

Expert Comment

by:snehanshu
ID: 9665082
jtcy,
  A small correction in my earlier explanation of your Call-By-Result (As pointed out by  brunomsilva and brettmjohnson):
I wrote:
>>So, if you call getSum as
>>int myretval, myparam;
>>myparam = 40;
>>myretval = getSum(myparam)
>>then myparam remains unchanged, but myretval becomes 41.

Well, I had not noticed that yoi haven't defined i in getSum. So, if i is a global variable then the explanation would be

If you call getSum as
int myretval, myparam;
i = 40; //assuming i is declared outside main
myretval = getSum(myparam)
then myparam remains unchanged, but myretval becomes 41.

And a reminder: Please keep closing your questions if you expect to get promptly answered :-)

Cheers!
...Snehanshu
0
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 9665243
snehanshu,

I stand corrected.  pre-ANSI C did not specify passing structures by value (although
some compilers supported it, most didn't).
But ANSI-C does specify passing and returning structures by value (Sec. 2.2.3 p. 13).

When I think back 15 years ago I vaguely remember this.  Early compilers (Lattice C?)
would implicitly pass structures by reference. However, as the ANSI spec started to
come together, they started throwing a warning at the construct.  The compiler still
didn't support passing structures, but they would throw a warning when doing the
implicit pointer conversion.  I guess I'm so old that I never considered passing structs
by value.  When I think back, there was probably one or two occasions where passing
structs by value would have been useful.


0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9665265
brettmjohnson,
  It feels great to know I am young in this big bad world :-) Working on C 15 years ago sounds so exciting!
  It seems that lately, Akshay and I have somehow taken up the task of posting our views on every comment that has any thing to do with passing parameters: no offence meant.
  Cheers,
...Snehanshu
P.S.
  It seems we have different ANSI-C manuals: the PDF I downloaded yesterday doesn't have a Sec. 2.2.3 p. 13, but I guess it doesn't matter as long as we all agree :-)
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9719530

It was just a couple of weeks ago that I made the concensus argument regarding passing by value vs passing by reference and ganged up on by theorists claiming that C didn't pass by reference.  (Their argument seemed to be that placing the address of an object on the stack was really passing by value since an address is a value.)  They even argued that K&R made that claim so it must be right....

Where were you guys???    :)

Kent
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 9719931
>> Where were you guys???
Dear Sir,
I have no clue of what's being talked about.
"Take it to the lounge" and post a link (to the lounge question) here.
...Shu
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9732836
In case jtcy's silence is confusion (rather than loss of interest), the following illustrates how arrays are passed by reference and structs are passed by value (i.e. as copies). See how pointers aren't used in this.

--------8<--------
#include <stdio.h>

int x[1];
struct X {int x;} s;

void poke_array(int[1]);
void poke_struct(struct X);

int main()
{
        x[0] = 99;
        printf("x[0] = %d\n",x[0]);
        poke_array(x);
        printf("x[0] = %d\n",x[0]);

        printf("\n");

        s.x = 77;
        printf("s.x = %d\n",s.x);
        poke_struct(s);
        printf("s.x = %d\n",s.x);
}

void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",ref[0]);
        ref[0] = 66;
        printf("ref[0] = %d\n",ref[0]);
}

void poke_struct(struct X cpy)
{
        printf("cpy.x = %d\n",cpy.x);
        cpy.x = 44;
        printf("cpy.x = %d\n",cpy.x);
}
--------8<--------

You're probably thinking that the reference is really a pointer in C and if you rewrite poke_array as follows, you'll see that you are right:
--------8<--------
void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",*ref); /* A pointer?! */
        *ref = 66;
        printf("ref[0] = %d\n",*ref);
}
--------8<--------

You'll find that you can treat ref just like a pointer and (ignoring the fact that we are incrementing beyond the bounds of our array), you'll find that the following compiles OK in C or C++, though it should look very wrong to you:
--------8<--------
void poke_array(int ref[1])
{
        printf("ref[0] = %d\n",*ref); /* A pointer?! */
        *++ref = 66; /* Pre-increment and assign, just as if it was a pointer */
        printf("ref[1] = %d\n",*ref);
}
--------8<--------

Lo and behoold, we can treat the reference to the array just as though it was a pointer. You may as well admit to the fact that your reference is a pointer and prototype it thus:
--------8<--------
void poke_array(int* ref);
--------8<--------

Why then, can't you compile the following code, you might ask yourself:
--------8<--------
int main()
{
    int x[2];
    *++x = 2;
}
--------8<--------

The reason that this doesn't work is that the compiler hasn't stored the address of the array in a variable anywhere (we're not working with a reference) and therefore it is unable to increment a pointer.

Silly language, isn't it?
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10097280
Hi jtcy!

After tons of C-specific pitfalls: Call-by-name is a construct from languages like perl or ruby, where you can explicitly state which parameter you'll set with the following value, like in Perl:

create_human(height=>6,weight=>140,sex=>"M",name=>"Adam");

All other possible parameters have default values. This is basically passing a hash of name/value pairs.

This is for sure possible to implement in C++ (or even C), but the code will look messy.
0
 
LVL 5

Expert Comment

by:snehanshu
ID: 10415372
If the asker is not interested, I am not interested either.
PAQ the question without refunding points as far as I am concerned.
thanks,
...Shu
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now