Does C copy an element every time you access an array?

C cannot return links unlike C ++. Does this mean that when accessing A[i] it will copy the element when evaluating the expression?

For example, if A is an array of 10 int s, then only A[5]+=1; only increases the temporary copy created by rating A[5] , in contrast to the C ++ vector, which will increase the sixth element itself?

+8
c ++ c arrays
source share
5 answers

C has a concept called "lvalue" that looks like a link. This is not a type (not part of the type system), but some C expressions are "lvalues", and only such expressions can be a left assignment operand (including op-assign) or an increment / decrement.

Since C does not have operator overloading, there is no need to have a difference in type system, since you never need to declare things as rvalues ​​vs lvalues. It was the desire to add operator overloading in C ++, which led to the introduction of reference types to make the rvalue / lvalue distinction understandable for overloaded operators.

+12
source share

If so, you cannot modify arrays at all, and the expression A[5]+=1; will have no effect!

In contrast, when you pass a scalar argument to a function, it behaves like a copy, because it does not change after returning. But the array actually passed as a pointer is not copied (it would be unbearably expensive) and may be different when returning.

+5
source share

there is A [5] + = 1; only enlarge the temporary copy created by rating A [5]

Not. A[5]+=1; will cause the 6th element of A be increased by 1.

This can be achieved by copying A[5] to the register in the CPU, increasing it and copying it back.

Here is the program:

 int main(){ int A[10]; A[5]+=1; return 0; } 

Here gcc generated assembler x86-64 for A[5]+=1;

  mov eax, DWORD PTR [rbp-28] add eax, 1 mov DWORD PTR [rbp-28], eax 

This moves the DWORD PTR [rbp-28] to the EAX 32-bit battery, adds 1 to it, and moves it back to the same place.

DWORD PTR [rbp-28] identifies the 6th element of A by its position relative to the (end) of the stack frame ( rbp ).

The link point is a red herring. Both C and C ++ are compiled into machine code (possibly through assembler). What other functions do languages ​​not affect how A[5]+=1; interpreted or compiled.

+4
source share

C always copies an element when reading from an array with A[i] , that is, when the expression A[i] is "rvalue". However, when considering a notation, C has the concept of an β€œlvalue” of expressions, which are essentially a limited subset of the syntax of expressions that can appear as a destination:

 X = Y *X = Y X[i] = Y Xn = Y 

In these cases, the β€œexpressions” *X , X[i] and Xn do not actually evaluate the values ​​- they have the same syntax as the expressions, for convenience, but not for the same semantics. You can think of it 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 that C has several different assignment operators:

 _ = _ // direct assignment *_ = _ // indirect assignment _[_] = _ // special case of indirect assignment _._ = _ // special case of indirect assignment 

In any case, an assignment such as A[5] += 1 will increase the value of the sixth element of A in place, as you would expect, you can check like this:

 int A[1] = { 1 }; A[0] += 5; printf("%d\n", A[0]); // 6 
+2
source share

no, the index i of the array is just a pointer, so instead of the whole array, only the location is passed, and the value of the actual location affects it.

try the following code:

 #include<stdio.h> void function(int[]); int main() { int a[] = {0,1,2,3,4,5,6,7,8,9}; int i; for(i = 0; i < 10; i++) printf("%d, ",a[i]); function(a); printf("\n"); for(i = 0; i < 10; i++) printf("%d, ",a[i]); return 0; } void function(int b[]) { int i; for(i = 0; i < 10; i++) b[i] *= 10; } 

OUTPUT

0
source share

All Articles