3

I was referring to the book, "C Programming Just the FAQs" by Paul S R Chisholm. According to the author, "Because the array is being passed by value, an exact copy of the array is made and placed on the stack. The called function then receives this copy of the array and can print it. Because the array passed to byval_func() is a copy of the original array, modifying the array within the byval_func() function has no effect on the original array"

But I thought if we pass array as given in his example, it will alter the array even in calling portion. I even tried and it was as per my expectation. Please correct me if I am wrong.

Below is the example given in the text book.

void byval_func(int[]);

void main(void)
{
    int x[10];
    int y;
    /* Set up the integer array. */
    for (y=0; y<10; y++)
    x[y] = y;
    /* Call byval_func(), passing the x array by value. */
    byval_func(x);
}

/* The byval_function receives an integer array by value. */
void byval_func(int i[])
{
    int y;
    /* Print the contents of the integer array. */
    for (y=0; y<10; y++)
    printf(“%d\n”, i[y]);
}
isaias-b
  • 2,255
  • 2
  • 25
  • 38
Jon Wheelock
  • 263
  • 3
  • 16
  • must be a mighty old book, because in modern C, main() ALWAYS has an 'int' return type. – user3629249 Sep 27 '15 at 18:50
  • in C, the name of an array degrades to the address of the first byte of the array. so a pointer to the array is being passed, not the contents of the array – user3629249 Sep 27 '15 at 18:52
  • this function parameter: `(int i[])` is defining a 'pointer to integer array' not the contents of the array – user3629249 Sep 27 '15 at 18:53
  • The question is implicit on your text, I think you should do it explicitly. If you think that the author is wrong and are asking for a confirmation, you are right, the author is wrong. He shows that he was not only confused, but completely misunderstands how arrays are passed to functions, as the name of the function begins with 'byval'. – fbiazi Sep 27 '15 at 18:58
  • Bad book. My initial experience with C was plagued with "references" (including books) and code that were plain wrong. The author(s) is/are either incompetent or careless. In one place they correctly say: "IX.4: Can the sizeof operator be used to tell the size of an array passed to a function? Answer: No. There’s no way to tell, at runtime, how many elements are in an array parameter just by looking at the array parameter itself. Remember, passing an array to a function is exactly the same as passing a pointer to the first element". But then somehow they screw it up elsewhere in the text. – Alexey Frunze Sep 27 '15 at 22:31
  • Bad book cont'd. The author(s) incorrectly say(s) that `byval_func(int i[])` " will take one argument—an array of integers", but `const_func(const int*)` "receives an integer array by reference". Both receive a pointer to an int, which could be a pointer to the first element of an array. The only difference is that that int (in case it's just one number and not an array element) or the elements of the array can't be modified in`const_func(const int*)`. Burn that book. – Alexey Frunze Sep 27 '15 at 22:35

2 Answers2

3

Sounds like the author of that book doesn't know C.

  • Arrays aren't "passed by value" because there are no array values in C. The value of an array is effectively a pointer to its first element.
  • That means a function can modify the caller's array (the array itself is never copied).
  • void main is wrong. main must return int.

Rule of thumb: If a C book contains void main, it's probably bad.

melpomene
  • 84,125
  • 8
  • 85
  • 148
0

I think the author made a confusion there. What's happening on your code is that the address of the first element in the array is passed by value, but not the "data structure" array in its whole.

Passing by value and by reference is a topic of much confusion. People tend to think that because the modifications to the value passed to a function are reflected outside its scope, it mean the argument was passed by reference. This is just wrong. You can't pass anything by reference in C, only by value, and this value can be a referece.

In C++, for instance, you can pass by/declare a reference using the & operator.

Further explanation:

In C, in some contexts (as noted by M.M)* when you only express the name of the array, it is the same as expressing the address of its the first element:

int x[10]; // you can call func(x) OR func(&x[0]);

As I said, you pass a reference by value, and this value is the address of the first element.

An interesting note:

x[0] is the same as *(x + 0)
x[1] is the same as *(x + 1)

And because [] results in an addition operation, you can also write

0[x], and it will be translated to *(0 + x) which results in the same address, making a call such as int a = 9[x]; 100% valid C.

*Is an array name a pointer?

Community
  • 1
  • 1
victor
  • 1,532
  • 1
  • 13
  • 32
  • The `&` operator does the same thing in C and C++: take the address of the object you give it as argument. Maybe you are thinking of the `&` symbol used as part of a reference declarator in C++ (in that context it is not an operator). – M.M Sep 27 '15 at 22:52
  • "In C, when you only express the name of the array, it is the same as expressing the address of its the first element" - not quite right, in *some contexts* expressing the name of an array *creates* a pointer to the address of the first element. `sizeof x` is an example of a context where this does not happen. You also suggest the same problem by saying "the array pointer". There is no "array pointer" ; a temporary pointer is created when needed, the array doesn't inherently contain a pointer. – M.M Sep 27 '15 at 22:53
  • @M.M & has 2 uses in C++ 1. To declare a variable as a reference 2. To take the address of a variable 1 is is not part of C Isn't & considered an operator when declaring a reference? Can you provide a reference that says & is not an operator in such case? Im not aware of that I will adapt the answer. Thanks – victor Sep 27 '15 at 23:14
  • The definition of "operator" is something that operates on expression(s) , yielding another expression. Section 5.3.1/3 of the C++ standard describes the behaviour of the unary `&` operator. Section 8.3.2 describes the behaviour of `&` in declarators. – M.M Sep 27 '15 at 23:41