2

my code is

#include <stdio.h>
#define MAXVAL 100
int getCharsMethod(char s[],int);

main(){
   char foo[MAXVAL];
   int len;
   len=getCharsMethod(foo,5);
   printf("value of foo is -- %s and len is %d",foo,len);

}

int getCharsMethod(char s[],int lim){
   int i;
   for(i=0;i<lim;++i)
       s[i]=getchar();

   return i;
}

now i havent inserted any value inside the array foo[]. but the values that are inserted in the array s[] inside the function is reflected in the foo[] array.

I just passed an empty foo[] array with length MAXVAL into the function getCharsMethod() how does the chars inserted in the array s[] inside the function is reflected in the foo[] array.

10
  • 1
    You invoked undefined behavior by using value of uninitialized variable having automatic storage duration, which is indeterminate. Do not forget to null-terminate the buffer before passing its pointer to %s. Commented Jun 2, 2016 at 13:33
  • Get a good C book, and look up pass by reference. Commented Jun 2, 2016 at 13:34
  • 3
    @RishikeshRaje: there are no references in C ;) Commented Jun 2, 2016 at 13:36
  • 2
    @MichałWalenciak pass by reference is a terminology used to indicate that you are passing pointers. It is used to distinguish it by pass by value. Commented Jun 2, 2016 at 13:38
  • 2
    @RishikeshRaje: The pointer is still passed by value! C does not support references and the term is typically used for implicit references only, thus not for C. Commented Jun 2, 2016 at 13:51

4 Answers 4

6

When you pass an array to a function, it (basically) just gets the address of the array's first element.

So the arrays s and foo are using the same memory, which is why writes inside the function will be seen from the outside.

One would think this has to be obvious from your code, else what would char s[] even mean? It has no length, so how can it accept storing elements using assignment to s[i] inside the function. Did you expect C to automatically create and manage a magical growing array? If so, then please read up more on the language. It doesn't work like that.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you @unwind. I read a book saying that passing an array to a function will get the address of the array's first element. but, I was not aware that the array in the function would take up the same memory. I'm just a beginner.
2

In C arguments passed to functions by coping their values.

Consider for example

#include <stdio.h>

void f( int x )
{
    x += 10;
    printf( "Inside f x = %d\n", x );
}

int main(void) 
{
    int x = 5;

    printf( "Before call of f x = %d\n", x );
    f( x );
    printf( "After  call of f x = %d\n", x );
}   

The program output is

Before call of f x = 5
Inside f x = 15
After  call of f x = 5

That is the function deals with a copy of the value of the original variable x. The original variable x itself is not changed.

Now consider a modified program

#include <stdio.h>

void f( int *px )
{
    *px += 10;
    printf( "Inside f x = %d\n", *px );
}

int main(void) 
{
    int x = 5;

    printf( "Before call of f x = %d\n", x );
    f( &x );
    printf( "After  call of f x = %d\n", x );
}

The program output is

Before call of f x = 5
Inside f x = 15
After  call of f x = 15

In this case the argument is passed by reference that is the function gets the address of the original variable x and consequently it changes the variable.

Arrays could be also passed by value as arguments to functions. That is functions could deal with copies of arrays. But creating a copy of a whole array is a very expensive and time-consuming operation.

So in C when an array is passed to a function then its designator is implicitly converted to pointer to its first element. And correspondingly the parameter is adjusted to pointer.

For example these function declarations are equivalent and declare the same one function

void f( int a[] );
void f( int a[10] );
void f( int a[100] );
void f( int *a );

Thus the elements of the array in fact are passed by reference. You can change any element of an array the same way as it is shown in the second demonstrative program in my post.

For example

#include <stdio.h>

void f( int *a, size_t n )
{
    for ( size_t i = 0; i < n; i++ ) *( a + i ) = i;

    printf( "Inside f array a is " );

    for ( size_t i = 0; i < n; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );
}

int main(void) 
{
    int a[] = { 0, 0, 0, 0, 0 };
    const size_t N = sizeof( a ) / sizeof( *a );

    printf( "Before call of f array a is " );
    for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );

    f( a, N );

    printf( "After  call of f array a is" );
    for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );
}   

The program output is

Before call of f array a is 0 0 0 0 0 
Inside f array a is 0 1 2 3 4 
After  call of f array a is0 1 2 3 4 

1 Comment

thank you, @Vlad. I understood the concept of passing the arrays to a function clearly. your answer was very useful.
2

I just passed an empty foo[] array with length MAXVAL into the function getCharsMethod()

No, you didn't. In fact, you can't. In C, no function parameter or return value is an array. In almost all contexts, the value of an expression of array type "decays" to a pointer to the first element of the array, and the argument lists of functions and the value provided in a return statement are not exceptions. You passed a pointer to the first element of main()'s array foo.

Additionally, declaring a function parameter via array syntax, with or without a length, in fact declares that parameter as a pointer, of exactly the same pointer type to which an array of the nominal type given in the parameter list would decay. This is a syntactic convenience made possible by the fact that, again, function arguments cannot ever be arrays. Again, this not a prohibition, but rather a consequence of C semantics for expression evaluation.

Thus, these declarations are semantically identical:

int getCharsMethod(char s[], int lim);

and

int getCharsMethod(char *s, int lim);

and even

int getCharsMethod(char s[MAXVAL], int lim);

how does the chars inserted in the array s[] inside the function is reflected in the foo[] array.

There is no array s in function getCharsMethod(). There is only a pointer, which during your particular call points to the first element of main()'s foo. Thus, for any i between 0 (inclusive) and the length of foo (exclusive), s[i] in designates the same char in getCharsMethod() that foo[i] designates in main() -- not just the same value, but the same actual object.

1 Comment

Thank you for your answer @John. I can't understand some of the technical terms that you used in the post. But i came to know that a function argument cannot be an array and its jus a pointer. I have just started learning C. I don't have much knowledge on pointers. I just know pointers point to a address.Thank you once againg for your answer.
1

When any array is sent from a function, the receiving argument if array; then it gets the base address.

This means,

  • both the main parameter and argument arrays hold the same address.
  • So this implicitly acts as a call by reference mechanism.
  • Finally, any changes done to argument in the function effects the main parameter.

So, Why does foo[] reflect s[]?

Here, in your code, s gets the base address of foo so this implicitly becomes as a call by reference mechanism and hence any change to s affects foo.

4 Comments

I understand what you're saying, but I don't care much for describing the situation as call by reference. It isn't -- it is call by value, where the value is a pointer. Describing it otherwise opens the door to various misconceptions.
@JohnBollinger so should i remove the call by reference part?
@JohnBollinger what i meant was eventhough it is a call by value in the code of OP, it instead acts as a call by re.ference mechanism
As I said, I understand. I just think it's counterproductive to characterize the situation that way. For example, how does the OP understand what happens when the function's actual argument is declared specifically as a pointer? Is that pointer passed by reference? No, of course not, because there is no pass-by-reference in C.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.