Fundamental C - Simple Arrays |
Written by Harry Fairhead | ||||||
Monday, 09 September 2019 | ||||||
Page 2 of 2
Assigning Arrays - PointersWhen you have two variables, x and y say, then when you assign x to y: y=x; the value in x is copied to y and after this any changes that you make to y don’t affect x. This is value assignment and it is what you generally expect to happen. Now consider assigning variables that are storing arrays: int x[10]={0,1,2,3,4,5,6,7,8,9}; int y=x; If you try this out you will see a warning message and the program won’t do what you expect. The reason is that y has been declared as an int and what is assigned to it is an int array. The way that arrays are implemented is different to the way simple values like ints are implemented. When you create an array, what is stored in the variable is not the array, but a pointer to the start of the array, i.e. to the first element of the array. Arrays are stored somewhere in memory and the variable is just a pointer to the data. Exactly how this all works is described later. What is important for the moment is to understand that the variable stores a pointer to the data. You can think of a pointer as the address of the start of the array. In most cases this is accurate but machines have a range of different addressing mechanisms that can sometimes make the relationship between a pointer and a low-level machine address more complex. However, in the case of the x86 and ARM architecture you are relatively safe in thinking of a pointer as an address. The type of an int array is signified by int* which means “a pointer to int”, more of this in Chapter 10. You can create a pointer to any simple data type by following the type by an asterisk. For example, float * is a pointer to a float and so on. Now if you try: int x[10]={0,1,2,3,4,5,6,7,8,9}; int* y=x; it all works, but it still might not be doing what you expect. It doesn’t copy the array in x into y, i.e. this is not a value assignment, and no new copy of the array data is created. Instead, of course, x doesn’t store the array data, but a pointer to the array data. The assignment is still a value assignment, in the sense that what is stored in x is copied to y, but what is stored in x is a pointer to the start of the array data. Now both x and y point to the same block of data and any changes made using variables x or y change the same block of data. For example: x[0]=1; y[0]=2; both change the first element of the same data. As y is used last, the final value of the first element of the array is now 2. That is, variables that reference arrays are pointers to the start of the array and this results in reference semantics. Notice, however, that when you assigned x to y the value in x was copied to y, value semantics applied, but in this case the values were pointers. When you assign an array variable to another variable it is the reference that is copied and both variables point to the start of the same data. This idea of a pointer is very important in C and Chapter 10 explains it in all its details, but it is important that at this early stage you have an idea of how pointers and arrays work. So what do you do if you want a new copy of an array that you can work on without changing the original? The answer is the for loop yet again: int x[10]={0,1,2,3,4,5,6,7,8,9}; int y[10]; for(int i=0;i<10;i++){ y[i]=x[i]; } Notice that you have to declare y as y[10] to allocate the storage for the copy of the array. If you get the size of y wrong then it is possible that your program will write data into areas of memory that haven’t been allocated to it. This is an array overrun or overflow. For example: int x[10]={0,1,2,3,4,5,6,7,8,9}; int y[5]; for(int i=0;i<10;i++){ y[i]=x[i]; } As y is only five elements long, where is x copied to after the fifth iteration? The answer is whatever area of memory comes after the allocated five elements of y. The GCC compiler will warn you that at iteration five you have undefined behavior, but it will still compile and run the program for you. This is another example of how C is a low-level language that can get you into trouble if you do things incorrectly. Sections that are in the book but not included in this extract
Summary
Fundamental C: Getting Closer To The MachineNow available as a paperback and ebook from Amazon.
Also see the companion volume: Applying C <ASIN:1871962609> <ASIN:1871962463> <ASIN:1871962617> <ASIN:1871962455>
Harry Fairhead is the author of Raspberry Pi IoT in C , Micro:bit IoT in C and Fundamental C: Getting Closer to the Machine. His latest book is Applying C For The IoT With Linux. Related ArticlesRemote C/C++ Development With NetBeans Getting Started With C/C++ On The Micro:bit To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.
Comments
or email your comment to: comments@i-programmer.info
|
||||||
Last Updated ( Monday, 09 September 2019 ) |