Hello frnds. I want to knw tht how can we send an array by value in c.

Recommended Answers

All 15 Replies

The short answer is you can't. The long answer is you can if you aren't pedantic about it.

An array can be copied by value by wrapping the array in a structure and then passing an instance of that structure. When the structure instance is copied, the array goes with it as a data member. Technically you're not passing the array by value, you're passing the structure instance by value, but the effect is the same:

#include <stdio.h>

struct foo { int a[10]; };

void bar(struct foo arg)
{
    /* Notice how the sizeof trick works */
    for (int i = 0; i < sizeof arg.a / sizeof *arg.a; i++)
    {
        printf("%d ", arg.a[i]);
        ++arg.a[i]; /* Won't affect the original array in main() */
    }
}

int main(void)
{
    struct foo x =
    {
        {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    };

    bar(x);
    putchar('\n');

    for (int i = 0; i < sizeof x.a / sizeof *x.a; i++)
    {
        printf("%d ", x.a[i]);
    }

    putchar('\n');

    return 0;
}

Another possible solution

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void vPassByValue(const void * const vData, int iSizeOfData)
{
   void *vCopyData = NULL;

   vCopyData = malloc(iSizeOfData);
   if(vCopyData != NULL)
   {
      memcpy(vCopyData, vData, iSizeOfData);
      printf("passed by value %s\n",vCopyData);
      memset(vCopyData, 0, iSizeOfData);
   }
   free(vCopyData);

   return;
}

int main()
{
   char pcBuffer[20] = {0};

   sprintf(pcBuffer,"%.12d",1234);
   puts(pcBuffer);
   vPassByValue(pcBuffer, sizeof(pcBuffer));
   puts(pcBuffer);

   return 0;
}

`

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void vIdoPrintArray()
{


}

void vPassByValue(const void * const vData, int iSizeOfElement, int iDataLength)
{
   void *vCopyData = NULL;
   vCopyData = malloc(iSizeOfElement * iDataLength);

   if(vCopyData != NULL)
   {
      int i = 0;
      memcpy(vCopyData, vData, iSizeOfElement * iDataLength);
      //printf("passed by value %s\n",vCopyData);
      while(i < iDataLength)
      {
         //printf("%d",*((int*)vCopyData + i ));
         printf("%d",((int*)vCopyData)[i]);
         i++;
      }
      memset(vCopyData, 0, iSizeOfElement * iDataLength);
   }

   free(vCopyData);
   return;
}



int main()
{
   int  pcBuffer[] = {1,2,3,4,5,6};

   //sprintf(pcBuffer,"%.12d",1234);

   vPassByValue(pcBuffer, sizeof(int), 6);
   //puts(pcBuffer);
   return 0;
}

Bot This could be best solution or best VAR_ARGSClick Here

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void iPassByVal(char *pcBufferToWorkWith)
{
   puts(pcBufferToWorkWith);

   return;
}

int main()
{
   char pcBuffer[20] = {'W','o','r','k','\0'};
   char pcBufferCopyToPass[20] = {0};

   memcpy(pcBufferCopyToPass, pcBuffer, sizeof(pcBuffer));

   iPassByVal(pcBufferCopyToPass);

   return 0;
}

`

@Sokurenko: I'm not the kind of guy who down-votes posts willy-nilly (unless you're being condescending and a complete ass), but your post is... not what the OP is asking for. Pass by value, not reference. Yours is reference. Granted, your code is instructive to new coders and you're not rude, so no down-voting.

@Deceptikon: Back in the days of Turbo C, I remember folks saying never put an array in the arguments, and instead use its pointer AND the same thing about struct's. Back then, passing by value would obliterate the then-miniscule memory stack like no tomorrow. I'm tempted to say that if you pass an array of specific size to a function expecting a specific size, it will pass by value, but I don't know. I'll compile some code as small as I can get it and read the assembly to see. Of course, that'll only prove one compiler for one platform. Meh.

As an aside, in some countries the days of Turbo C seem to be today, tomorrow, and the day after that.

@Deceptikon: Back in the days of Turbo C, I remember folks saying never put an array in the arguments, and instead use its pointer AND the same thing about struct's.

While it's true for struct instances, arrays have always been passed "by pointer", even in the prehistory of C. When you pass an array to a function, a pointer to the first element is created and sent by value, so the only thing that gets copied is an address. Note also that these three declarations of the parameter are completely identical in every functional way:

void foo(int *a);
void bar(int a[]);
void baz(int a[N]);

The latter two declarations are a convenience and under the hood will be treated as if they were the first. In the last declaration, the size of the first dimension is allowed syntactically, but ignored semantically. You can verify this with a simple program that would give at least a warning if the size were meaningful:

void foo(int a[10]) { }

int main(void)
{
    int arg[5];

    foo(arg); /* Size mismatch? */

    return 0;
}

The folks who were saying that an array parameter could be passed by value were mistaken.

I'm tempted to say that if you pass an array of specific size to a function expecting a specific size, it will pass by value, but I don't know.

That's quite impossible if we're talking about a conforming C compiler because passing by value would break the guaranteed semantics wherein the original object could be modified through indexing:

void foo(int a[N])
{
    a[0] = 123; /* This change *must* be reflected in the caller */
}

To meet those requirements and still pass by value would be the height of stupidity for a compiler writer because it's the worst of both worlds. You have the stack overhead of a potentially large object being copied and the risk of aliasing the original object.

The problem here is that arrays don't work the same way as other things. There are special rules involved which essentially amount to: "An array used in value context becomes a pointer to the first element". There are only three non-value contexts:

  1. The array is an operand to the & (address-of) operator.
  2. The array is an operand to the sizeof operator.
  3. Special Case: The array is a string literal initializer to an array of char.

Everything else is value context, including passing an array as a function argument. So this:

int a[123];
foo(a);

Is syntactic sugar for this:

int a[123];
foo(&a[0]);

I'll compile some code as small as I can get it and read the assembly to see. Of course, that'll only prove one compiler for one platform. Meh.

The C standard has the final say, and it says that arrays are passed "by pointer". If a compiler passes arrays by value then it either has to jump through hoops to make it look like it's passed by pointer or it's not a conforming implementation. And as said above, making pass by value look like pass by pointer is stupid. I highly doubt you'll find a serious C compiler that does so.

@DeanMSands3

but your post is... not what the OP is asking for.

I passed by value, i did make copy, look link what it is, passing by value Click Here Please

yes i know the details are that i passed constant pointer to constant data, bot the result is exactly same from outside the function, except it stores data on heap and you can dinamically pass more or less data

Technically the only thing C supports is pass by value. You can simulate pass by reference using a pointer and dereferencing it, but the pointer itself is still passed by value.

Hm... for the moment, I'm going to say I was wrong about everything and leave it at that.
I'm still looking over the assembly (and I'm very rusty with GNU assembler), but being as my job expects me to produce results before the end of the day, I probably need to put this away for now.

Happy coding all.

Thank u all

Inline Code Example Here

int pf(int a,int n)
{
    static int lng=n,i=0;
    static int ar[10];
    int j;
    if(i<n-1)
    {
        ar[i++]=a;
        return(0);
    }
    ar[i]=a;
    for(j=0;j<n;j++)
    {
        printf("%5d",ar[j]);
    }
}
void main()
{
    int a[10],n,i;
    clrscr();
    printf("enter size of arrary  ");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("\n enter array element");
        scanf("%d",&a[i]);
    }
    for(i=0;i<n;i++)
    pf(a[i],n);
    getch();
}

what i understood is that passing the whole array by values is not possible, so i tried to pass the array elements one by one,as in code above. your comments plz

That's certainly one valid way to pass multiple values to a function, but it's not advisable. Your proposed solution is overly complicated, which makes it hard to document, hard to read, and hard to debug.

Furthermore, it seems in your case to be totally unnecessary. Since you're not doing anything with the array elements but printing them out, "pass-by-pointer"[1] would work just fine, and you wouldn't risk causing any side effects by simply passing a pointer to the original array. (If you want to guarantee that you don't change the original object within the function, declare the function parameter const -- that's what it's there for.)

If, on the other hand, you want to use a function that changes the array that's passed to it, without changing the original array, then your most viable option is to make a copy of the array and pass the copy instead of the original. This is not the same as passing an array "by value", but it will usually have the same effect. You can also use the struct trick described earlier to kind-of pass an array by value -- the disadvantage being that it won't work for dynamically sized arrays.

[1]: As opposed to "pass-by-reference", which exists in C++ but not in C. In C, arguments are always passed "by value", but some values happen to be pointers, as deceptikon correctly pointed out.

P. S. What book are you using? void main() and clrscr() are non-standard, and worrisome to see because they're usually symptomatic of poor understanding of C.

@abrarsyed
your program is really sick, bot you did great job if it works, you might learn allot from it :)

I m a beginner to c and n just trying to explore the different solutions for a problem so as to increase my c skills...

Well, congratulations! You found an unconventional solution to a common problem. If you both (a) know why it works and (b) understand why you shouldn't do that in practice, consider yourself to have made great progress today.

I'll still suggest you find a good quality book, though. The C Programming Language is an excellent guide that doesn't teach bad habits like void main().

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.