C can't return references unlike C++. Does that mean if you access A[i]
it will copy the element in evaluating the expression?
For example if A
is an array of 10 int
s, does A[5]+=1;
only increment the temporary copy built when evaluating A[5]
, unlike C++'s vector which will increment the actual sixth element itself?
C always copies an element when reading from an array with A[i]
, that is, when the expression A[i]
is an “rvalue”. However, when considering writes, C has a notion of “lvalue” expressions, which are essentially a restricted subset of expression syntax that are allowed to appear as the destination of an assignment:
X = Y
*X = Y
X[i] = Y
X.n = Y
In these cases, the “expressions” *X
, X[i]
, and X.n
don’t actually evaluate to values—they have the same syntax as expressions, for convenience, but not the same semantics. You can think of these as something more like the following:
memcpy(&X, &Y, sizeof(Y));
memcpy(&*X, &Y, sizeof(Y));
memcpy(&X[i], &Y, sizeof(Y));
memcpy(&X.n, &Y, sizeof(Y));
Or, alternatively, think of C as having multiple different assignment operators:
_ = _ // direct assignment
*_ = _ // indirect assignment
_[_] = _ // special case of indirect assignment
_._ = _ // special case of indirect assignment
Either way, an assignment such as A[5] += 1
will increment the value of the sixth element of A
in place, just as you would expect, which you can verify like so:
int A[1] = { 1 };
A[0] += 5;
printf("%d\n", A[0]); // 6
C has a concept called an 'lvalue' which is sort-of like a reference. It's not a type (not part of the type system), but certain C expressions are 'lvalues', and only such expressions can be the left operand of an assignment (including an op-assign) or an increment/decrement.
Since C has no operator overloading, there's no need to have a distinction in the type system as there's never any need to declare things as rvalues vs lvalues. It was the desire to add operator overloading in C++ that lead to the introduction of reference types to make the rvalue/lvalue distinction clear for overloaded operators.
If that was true, you would be unable to modify arrays at all and the expression A[5]+=1;
would have no effect!
On the opposite, when you pass a scalar argument to a function, it behaves like a copy because it is not modified upon return. But an array, in fact passed as a pointer, is not copied (that would be unbearably costly) and can be different upon return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With