User Tools

Site Tools


c:basic_arrays

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
c:basic_arrays [2020/07/20 19:32] – old revision restored (2016/08/05 15:21) 62.138.2.243c:basic_arrays [2021/04/28 08:49] (current) peter
Line 1: Line 1:
 ====== C - Basic Arrays ====== ====== C - Basic Arrays ======
  
-**NOTE**:  This tutorial assumes you've already gone through the [[c:pointers|pointers]] tutorial.  If you haven't, please start there.  This tutorial draws from insights gained in that tutorial and includes terms and phrases that won't make sense if you haven't already gone through that tutorial.+<WRAP info> 
 +**NOTE**:  This tutorial assumes you are comfortable with [[c:pointers|pointers]]. 
 +</WRAP>
  
-Array basics+----
  
-Let's start by looking at a single variable used to store a person's age.+===== A single variable is used to store the age of a person =====
  
-C Code Listing 1+==== C Code Listing 1 ==== 
 + 
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 17: Line 21:
   8:   return 0;   8:   return 0;
   9: }   9: }
-C++ Code Listing 1+</code> 
 + 
 +---- 
 +   
 +==== C++ Code Listing 1 ==== 
 + 
 +<code cpp>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 27: Line 37:
   8:   return 0;   8:   return 0;
   9: }   9: }
-Not much to it. The variable age is created at line (5) as a short. A value is assigned to age. Finally, age is printed to the screen.+</code> 
 +   
 +<WRAP info> 
 +**NOTE:**  The variable **age** is created at line (5) as a short. 
 + 
 +  * A value is assigned to age. 
 +  * Finally, age is printed to the screen. 
 + 
 +</WRAP>
  
 Image: A simple variable in memory Image: A simple variable in memory
  
-Now let's keep track of 4 ages instead of just one. We could create 4 separate variables, but 4 separate variables have limited appeal. (If using 4 separate variables is appealing to you, then consider keeping track of 93843 ages instead of just 4). Rather than using separate variables, we'll use an array.+{{:c:c_address_age_as_var.jpg?400|}} 
 + 
 +---- 
 + 
 +===== Keep track of 4 ages instead of just one ===== 
 + 
 +4 separate variables could be used, but this does not scale easily if the number to track moves into the thousands. 
 + 
 +Instead of using separate variables to store each ageit is better to use an array.
  
-Here's how to create an array and one way to initialize an array:+==== C Code Listing 2 ====
  
-C Code Listing 2+<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 47: Line 73:
  10:   return 0;  10:   return 0;
  11: }  11: }
-C++ Code Listing 2+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 2 ==== 
 + 
 +<code cpp>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 59: Line 91:
  10:   return 0;  10:   return 0;
  11: }  11: }
-On line (5), an array of 4 short'is created. Values are assigned to each variable in the array on line (6) through line (9).+</code> 
 + 
 +<WRAP info> 
 +**NOTE:**  This creates and initializes an array. 
 + 
 +  * On line (5), an array of 4 shorts is created. 
 +  * Values are assigned to each variable in the array on line (6) through line (9). 
 + 
 +</WRAP>
  
 Image: Array with 4 elements Image: Array with 4 elements
  
-Accessing any single short variable, or element, in the array is straightforward. Simply provide a number in square braces next to the name of the array. The number identifies which of the 4 elements in the array you want to access.+{{:c:c_address_age_as_arr.jpg?400|}} 
 + 
 +---- 
 + 
 +<WRAP info> 
 +**NOTE:**  Accessing any single short variable, or element, in the array is straightforward. 
 + 
 +Simply provide a number in square braces next to the name of the array.  The number identifies which of the 4 elements in the array you want to access. 
 + 
 +The program above shows that the first element of an array is accessed with the number 0 rather than 1. 
 + 
 +</WRAP> 
 + 
 +---- 
 + 
 +===== Printing arrays =====
  
-The program above shows that the first element of an array is accessed with the number 0 rather than 1. Later in the tutorial, We'll discuss why 0 is used to indicate the first element in the array. +Print the array to the screen:
-Printing arrays+
  
-Our program is a bit unrevealing in that we never print the array to screen. Here is the same program with an attempt to print the array to the screen:+==== C Code Listing 3 ====
  
-C Code Listing 3+<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 84: Line 138:
  12:   return 0;  12:   return 0;
  13: }  13: }
-C++ Code Listing 3+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 3 ==== 
 + 
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 98: Line 158:
  12:   return 0;  12:   return 0;
  13: }  13: }
-Line (11) is meant to print the 4 ages to the screen. But instead of printing out the four short variables, what appears to be nonsense prints out instead.+</code>
  
-What the "nonsense" output actually is and why the 4 array values were not printed will be addressed later in the tutorial. For now, the important point to come away with is that simply providing the name of the array in an output statement will not print out the elements of the array. +<WRAP info> 
-How about printing out each of the values separately? Try this:+**NOTE:**  Line (11) is meant to print the 4 ages to the screen.
  
-C Code Listing 4+But instead of printing out the four short variables, what appears to be nonsense prints out instead. 
 + 
 +What the "nonsense" output actually is and why the 4 array values were not printed will be addressed later. 
 + 
 +For now, the important point to come away with is that simply providing the name of the array in an output statement will not print out the elements of the array. 
 + 
 +</WRAP> 
 + 
 +---- 
 + 
 +How about printing out each of the values separately?  Try this: 
 + 
 +==== C Code Listing 4 ==== 
 + 
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 119: Line 193:
  14:   return 0;  14:   return 0;
  15: }  15: }
-C++ Code Listing 4+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 4 ==== 
 + 
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 135: Line 215:
  14:   return 0;  14:   return 0;
  15: }  15: }
-Lines (10) through line (13) produce the output we are expecting.+</code> 
 + 
 +<WRAP info> 
 +**NOTE:**  Lines (10) through line (13) produce the output we are expecting. 
 + 
 +There is no single statement in the language that says "print an entire array to the screen"
 + 
 +Each element in the array must be printed to the screen individually. 
 + 
 +</WRAP> 
 + 
 +----
  
-There is no single statement in the language that says "print an entire array to the screen". Each element in the array must be printed to the screen individually.+===== Copying arrays =====
  
-Copying arrays+Suppose that after filling our 4 element array with values, we need to copy that array to another array of 4 short's?  Try this:
  
-Suppose that after filling our 4 element array with values, we need to copy that array to another array of 4 short's? Try this:+==== C Code Listing 5 ====
  
-C Code Listing 5+<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 163: Line 254:
  18:   return 0;  18:   return 0;
  19: }  19: }
-C++ Code Listing 5+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 5 ==== 
 + 
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 183: Line 280:
  18:   return 0;  18:   return 0;
  19: }  19: }
-Line (12) tries to copy the age array into the same_age array. What happened when you tried to compile the program above?+</code> 
 + 
 +<WRAP info> 
 +**NOTE:**  Line (12) tries to copy the age array into the same_age array.  What happened when you tried to compile the program above? 
 + 
 +The point here is that simply assigning one array to another will not copy the elements of the array.  The hard question to answer is why the code doesn't compile.  Later in the tutorial this example will be re-examined to explain why line (12) doesn't work.  This code should not compile on either C or C++ compilers.  However, some older C++ compilers may ignore the ISO C++ standard and allow line 12 to compile.  If it does compile on your C++ compiler, make a mental note that it is incorrect behavior. 
 + 
 +</WRAP> 
 + 
 +----
  
-The point here is that simply assigning one array to another will not copy the elements of the array. The hard question to answer is why the code doesn't compile. Later in the tutorial this example will be re-examined to explain why line (12) doesn't work. This code should not compile on either C or C++ compilers. However, some older C++ compilers may ignore the ISO C++ standard and allow line 12 to compile. If it does compile on your C++ compiler, make a mental note that it is incorrect behavior. 
 Let's try copying arrays using a technique similar to the technique used to print arrays (that is, one element at a time): Let's try copying arrays using a technique similar to the technique used to print arrays (that is, one element at a time):
  
-C Code Listing 6+==== C Code Listing 6 ==== 
 + 
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 212: Line 319:
  22:   return 0;  22:   return 0;
  23: }  23: }
-C++ Code Listing 6+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 6 ==== 
 + 
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 236: Line 349:
  23:   return 0;  23:   return 0;
  23: }  23: }
-This technique for copying arrays works fine. Two arrays are created: age and same_age. Each element of the age array is assigned a value. Then, in order to copy of the four elements in age into the same_age array, we must do it element by element.+</code> 
 + 
 +<WRAP info> 
 +**NOTE**  This technique for copying arrays works fine. 
 + 
 +  * Two arrays are created: age and same_age. 
 +  * Each element of the age array is assigned a value. 
 +  * Then, in order to copy of the four elements in age into the same_age array, we must do it element by element. 
 + 
 +</WRAP>
  
 Image: Copy element 1 Image: Copy element 1
 +
 Copy first element Copy first element
 +
 +{{:c:c_address_arr_copy_first.jpg?400|}}
 +
  
 Image: Copy element 2 Image: Copy element 2
 +
 Copy second element Copy second element
  
-Like printing arrays, there is no single statement in the language that says "copy an entire array into another array". The array elements must be copied individually.+{{:c:c_address_arr_copy_second.jpg?500|}}
  
-The technique used to copy one array into another is exactly the same as the technique used to copy 4 separate variables into 4 other variablesSo what is the advantage to using arrays over separate variables?+Like printing arrays, there is no single statement in the language that says "copy an entire array into another array" The array elements must be copied individually.
  
-One significant advantage of an array over separate variables is the name. In our examples, using four separate variables requires unique names. The 4 short variables in our array have the same name, ageThe 4 short's in the array are identical except for an index number used to access them. This distinction allows us to shorten our code in a way that would be impossible with 4 variables, each with unique names:+The technique used to copy one array into another is exactly the same as the technique used to copy 4 separate variables into other variables.  So what is the advantage to using arrays over separate variables?
  
-C Code Listing 7+One significant advantage of an array over separate variables is the name.  In our examples, using four separate variables requires 4 unique names. The 4 short variables in our array have the same name, age.  The 4 short's in the array are identical except for an index number used to access them.  This distinction allows us to shorten our code in a way that would be impossible with 4 variables, each with unique names: 
 + 
 +==== C Code Listing 7 ==== 
 + 
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 270: Line 401:
  18:   return 0;  18:   return 0;
  19: }  19: }
-C++ Code Listing 7+</code> 
 + 
 +---- 
 + 
 +==== C++ Code Listing 7 ==== 
 + 
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 290: Line 427:
  18:   return 0;  18:   return 0;
  19: }  19: }
-Since the only difference between each of the short's in the arrays is their index, a loop and a counter can be used to more easily copy all of the elements. The same technique is used to shorten the code that prints the array to the screen.+</code>
  
-Even though arrays give us some convenience when managing many variables of the same type, there is little difference between an array and variables declared individually. There is no single statement to copy an array, there is no single statement to print an array.+Since the only difference between each of the short's in the arrays is their index, a loop and a counter can be used to more easily copy all of the elements.  The same technique is used to shorten the code that prints the array to the screen. 
 + 
 +Even though arrays give us some convenience when managing many variables of the same type, there is little difference between an array and variables declared individually.  There is no single statement to copy an array, there is no single statement to print an array.
  
 If we want to perform any action on an array, we must repeatedly perform that action on each element in the array. If we want to perform any action on an array, we must repeatedly perform that action on each element in the array.
  
-Array Internals+---- 
 + 
 +===== Array Internals =====
  
 To understand what exactly is happening inside of arrays, first recall the behavior of variables from the pointer tutorial: To understand what exactly is happening inside of arrays, first recall the behavior of variables from the pointer tutorial:
  
 Try: Try:
-C++ C+ 
 +^C++^C
 +
 +<code c++>
  1: #include <iostream>  1: #include <iostream>
  2: int main()  2: int main()
Line 309: Line 453:
  6:   return 0;  6:   return 0;
  7: }  7: }
 +</code>
 +|
 +<code c>
  1:#include <stdio.h>  1:#include <stdio.h>
  2:int main()  2:int main()
Line 316: Line 463:
  6:   return 0;  6:   return 0;
  7: }  7: }
-At line (4) in the program above, the computer reserves memory for fl. In our examples, we'll assume that a float requires 4 bytes. Depending on the computer's architecture, a float may require 2, 4, 8 or some other number of bytes.+</code> 
 +
 + 
 +At line (4) in the program above, the computer reserves memory for fl.  In our examples, we'll assume that a float requires 4 bytes.  Depending on the computer's architecture, a float may require 2, 4, 8 or some other number of bytes.
  
 Image: Variable fl allocated Image: Variable fl allocated
 +
 +{{:c:c_address_float.jpg?400|}}
  
 When fl is used in line (5), two distinct steps occur: When fl is used in line (5), two distinct steps occur:
  
-The program finds and grabs the address reserved for fl--in this example 924. +  * The program finds and grabs the address reserved for fl--in this example 924. 
-The contents stored at that address are retrieved+  The contents stored at that address are retrieved
 To generalize, whenever any variable is accessed, the above two distinct steps occur to retrieve the contents of the variable. To generalize, whenever any variable is accessed, the above two distinct steps occur to retrieve the contents of the variable.
-So, how is this related to referring to arrays without providing an index number (e.g. age, not age[2])?+ So, how is this related to referring to arrays without providing an index number (e.g. age, not age[2])?
  
 Here's the program from earlier in the tutorial that was our first crude attempt at printing out the contents of an array: Here's the program from earlier in the tutorial that was our first crude attempt at printing out the contents of an array:
  
 C Code Listing 8 C Code Listing 8
 +
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 343: Line 498:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 C++ Code Listing 8 C++ Code Listing 8
 +
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 357: Line 516:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 Line (11) prints out nonsense, not the contents of our array. Line (11) prints out nonsense, not the contents of our array.
  
Line 363: Line 524:
 Image: Array with 4 elements Image: Array with 4 elements
  
-On line (11), The program finds and grabs the address reserved for age. Simple enough. According to the image, age starts at address 924 so it is address 924 that is grabbed. +{{:c:c_address_age_as_arr.jpg?400|}}
-The contents stored at that address are retrieved (Oops!). +
-Step 2 is the problem. Our array has four values, not just one. To retrieve the contents at 924 would be inappropriate because 924 is the address of the first value in the array, not all values in the array.+
  
-As a result, step 2 isn't performed on arrays, just step 1. The output from line (11) is the address of the array: step 2 has not occurredIn order to get a value from an array, the programmer must "manually" do step 2 to retrieve the contents.+  * On line (11), The program finds and grabs the address reserved for age Simple enough.  According to the image, age starts at address 924 so it is address 924 that is grabbed. 
 +  * The contents stored at that address are retrieved (Oops!).
  
-Accessing elements in an array+Step 2 is the problem.  Our array has four values, not just one.  To retrieve the contents at 924 would be inappropriate because 924 is the address of the first value in the array, not all values in the array.
  
-From the pointer tutorial, we know that in order to get the contents at an address we use the * operator. Let's try it on our printing example:+As a result, step 2 isn't performed on arrays, just step 1.  The output from line (11) is the address of the array: step 2 has not occurred.  In order to get a value from an array, the programmer must "manually" do step 2 to retrieve the contents. 
 + 
 + 
 +===== Accessing elements in an array ===== 
 + 
 +From the [[c:pointer|pointer]] notes, we know that in order to get the contents at an address we use the * operator.  Let's try it on our printing example:
  
 C Code Listing 9 C Code Listing 9
 +
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 387: Line 554:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 C++ Code Listing 9 C++ Code Listing 9
 +
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 401: Line 572:
  12:   return 0;  12:   return 0;
  13: }  13: }
-On line (11) the * operator has been added. When this code is compiled and executed, 23 prints to the screen. When just the array's name is provided, only step 1 occurs with an array. We then manually do step 2 to get the contents at that address--namely the value of the first element of our array.+</code>
  
-That's all fine and good, but what about the rest of the array? What if we want to access the second, third, or fourth element of our array? We know that when we use the name of an array, step 1 occurs and we get the address of the first element of that array. We also know (from the pointers tutorial) that an address is nothing more than an integer. Given that the address is nothing but an integer, we can use addition to access the other array elements!+On line (11) the * operator has been added. When this code is compiled and executed, 23 prints to the screen.  When just the array's name is provided, only step 1 occurs with an array.  We then manually do step 2 to get the contents at that address--namely the value of the first element of our array. 
 + 
 +That's all fine and good, but what about the rest of the array? What if we want to access the second, third, or fourth element of our array?  We know that when we use the name of an array, step 1 occurs and we get the address of the first element of that array.  We also know (from the pointers tutorial) that an address is nothing more than an integer.  Given that the address is nothing but an integer, we can use addition to access the other array elements!
  
 The big question is: How much do we add to age in line (11) above to get the address of the second element in the age array? The big question is: How much do we add to age in line (11) above to get the address of the second element in the age array?
Line 409: Line 582:
 Image: Array with 4 elements Image: Array with 4 elements
  
-Did you answer "2"Two is correct for anyone who's familiar with basic rules of addition--and 2 makes sense if you look at the image. The image shows the first element of age beginning at 924, the second at 926, the third at 928, and so on. However, in this case C and C++ don't follow the rules of arithmetic. C and C++ follow the rules of pointer arithmetic. I'm sorry. Don't blame me. I'm just the storyteller, I didn't invent the darned language.+{{:c:c_address_age_as_arr.jpg?400|}}
  
-In C and C++ you add "1" to age (that is, the address of age) to access the second element, add "2" to age to access the third element, etc. If you hadn't seen the fancy image showing that each element of age (each short variable) had 2 bytes, then you might have said "1" and gotten the correct answer. We'll explain all of this in just a bit. But first let's see what that looks like in code.+Did you answer "2"?  Two is correct for anyone who's familiar with basic rules of addition--and 2 makes sense if you look at the image.  The image shows the first element of age beginning at 924, the second at 926, the third at 928, and so on.  However, in this case C and C++ don't follow the rules of arithmetic. C and C++ follow the rules of pointer arithmetic.  I'm sorry.  Don't blame me.  I'm just the storyteller, I didn't invent the darned language. 
 + 
 +In C and C++ you add "1" to age (that is, the address of age) to access the second element, add "2" to age to access the third element, etc.  If you hadn't seen the fancy image showing that each element of age (each short variable) had 2 bytes, then you might have said "1" and gotten the correct answer.  We'll explain all of this in just a bit.  But first let's see what that looks like in code.
  
 Here is how we can print the value of the second element in the array: Here is how we can print the value of the second element in the array:
  
 C Code Listing 10 C Code Listing 10
 +
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 429: Line 606:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 C++ Code Listing 10 C++ Code Listing 10
 +
 +<code c++>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 443: Line 624:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 Line (11) now shows pointer arithmetic in action: Line (11) now shows pointer arithmetic in action:
  
-Step 1 is done on age--the address 924 is returned. +  * Step 1 is done on age--the address 924 is returned. 
-Using pointer arithmetic, 1 is added to 924 which produces the address of the next element in the array. Looking at the image of our example, the result is 926. +  Using pointer arithmetic, 1 is added to 924 which produces the address of the next element in the array. Looking at the image of our example, the result is 926. 
-Using the * operator ("do step 2 on a number"), the contents at that address are retrieved. The contents at address 926 is the number 34, which is what prints to the screen.+  Using the * operator ("do step 2 on a number"), the contents at that address are retrieved. The contents at address 926 is the number 34, which is what prints to the screen. 
 The parentheses are required to ensure that the * operator and the + operator occur in the correct order. This is due to operator precedence rules. The parentheses are required to ensure that the * operator and the + operator occur in the correct order. This is due to operator precedence rules.
  
-Pointer Arithmetic 
  
-"This new learning amazes me, Sir Bedevere! Explain again, how sheep's bladders can be employed to prevent earthquakes."+===== Pointer Arithmetic ===== 
 + 
 +"This new learning amazes me, Sir Bedevere!  Explain again, how sheep's bladders can be employed to prevent earthquakes."
  
 -King Arthur, Monty Python and the Holy Grail -King Arthur, Monty Python and the Holy Grail
-Why is pointer arithmetic different from normal arithmetic? If you recall from the pointers tutorial, pointers in C and C++ are typed. That is, in C and C++ you can have float pointers, int pointers, char pointers, etc. Here's an excerpt from a side note in the pointers tutorial: 
  
-...A primary motivation for having a pointer type for each variable type is to help the compiler. Referring back to an earlier example, when we get the contents at an address ("do step 2 on a number"), the compiler must know how to get the contents at the address.+Why is pointer arithmetic different from normal arithmetic?  If you recall from the pointers tutorial, pointers in C and C++ are typed.  That is, in C and C++ you can have float pointers, int pointers, char pointers, etc.  Here's an excerpt from a side note in the pointers tutorial: 
 + 
 +  ...A primary motivation for having a pointer type for each variable type is to help the compiler.  Referring back to an earlier example, when we get the contents at an address ("do step 2 on a number"), the compiler must know how to get the contents at the address.
  
 The compiler needs to know two things when getting the contents at an address: The compiler needs to know two things when getting the contents at an address:
  
-How many bytes starting at the given address make up the value. For example, does the address refer to a 2 byte short int or a 4 byte float or an 8 byte double? +  * How many bytes starting at the given address make up the value.  For example, does the address refer to a 2 byte short int or a 4 byte float or an 8 byte double? 
-How to convert those bytes into the value. That is, the process for converting 4 bytes into a float is different than the process for converting 2 bytes into a short int. +  How to convert those bytes into the value.  That is, the process for converting 4 bytes into a float is different than the process for converting 2 bytes into a short int. 
-We've seen that when the name of an array is specified all by itself, only step 1 is done, not step 2. After step 1, we have the address to the first element in the array. In other words, it is a pointer! What kind of pointer? The type of the pointer is the same type as the array. In our sample program we created an array of short integers. So, the address is a short pointer (that is, it is a: short*).+ 
 +We've seen that when the name of an array is specified all by itself, only step 1 is done, not step 2.  After step 1, we have the address to the first element in the array.  In other words, it is a pointer! What kind of pointer?  The type of the pointer is the same type as the array.  In our sample program we created an array of short integers.  So, the address is a short pointer (that is, it is a: short*).
  
 The type of the pointer not only allows the compiler to correctly get the contents at an address, but it also allows the compiler to correctly calculate the number of bytes to add when doing pointer arithmetic: The type of the pointer not only allows the compiler to correctly get the contents at an address, but it also allows the compiler to correctly calculate the number of bytes to add when doing pointer arithmetic:
  
 +<code c>
   1: int miles[4];    1: int miles[4]; 
   2: miles[0]=342;   2: miles[0]=342;
Line 473: Line 661:
   5: miles[3]=7;   5: miles[3]=7;
   6: ... *(miles+2) ...   6: ... *(miles+2) ...
 +</code>
 +
 Image: int array Image: int array
  
-In line (4), miles is the address of an integer, or an int*. By the rules of pointer arithmetic, line (4) will get the contents at address 928.+{{:c:c_address_arr_int.jpg?400|}}
  
 +In line (4), miles is the address of an integer, or an int*.  By the rules of pointer arithmetic, line (4) will get the contents at address 928.
 +
 +<code c>
   1: float gpa[4];    1: float gpa[4]; 
   2: gpa[0]=2.3;   2: gpa[0]=2.3;
Line 483: Line 676:
   5: gpa[3]=0.0;   5: gpa[3]=0.0;
   6: ... *(gpa+2) ...   6: ... *(gpa+2) ...
 +</code>
 +  
 Image: float array Image: float array
  
-In line (4), gpa is the address of a floating point number, or a float*. By the rules of pointer arithmetic, line (4) will get the contents at address 932.+{{:c:c_address_arr_float.jpg?400|}}
  
 +In line (4), gpa is the address of a floating point number, or a float*.  By the rules of pointer arithmetic, line (4) will get the contents at address 932.
 +
 +<code c>
   1: char letter[4];    1: char letter[4]; 
   2: letter[0]='M';   2: letter[0]='M';
Line 493: Line 691:
   5: letter[3]='k';   5: letter[3]='k';
   6: ... *(letter+2) ...    6: ... *(letter+2) ... 
 +</code>
 +  
 Image: char array Image: char array
  
-In line (4), letter is the address of an character, or a char*. By the rules of pointer arithmetic, line (4) will get the contents at address 926.+{{:c:c_address_arr_char.jpg?400|}}
  
-Array Basics Revisited+In line (4), letter is the address of an character, or a char*.  By the rules of pointer arithmetic, line (4) will get the contents at address 926.
  
-Now that we have some insight about C and C++ array quirks, let's take another look at how we started accessing array elements. Prior to diving into this whole step 1 step 2 business with arrays we were initializing, printing, copying, and in general accessing array elements using square braces:+ 
 +===== Array Basics Revisited ===== 
 + 
 +Now that we have some insight about C and C++ array quirks, let's take another look at how we started accessing array elements.  Prior to diving into this whole step 1 step 2 business with arrays we were initializing, printing, copying, and in general accessing array elements using square braces:
  
 C Code Listing 11 C Code Listing 11
 +
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 515: Line 720:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 C++ Code Listing 11 C++ Code Listing 11
 +
 +<code cpp>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 529: Line 738:
  12:   return 0;  12:   return 0;
  13: }  13: }
-On lines (6-9) we are using square braces to access elements for initialization. On line (11) we are using square braces to print out the third element of the array. From the previous section you might have been led to believe that you would print out the third element by putting something like *(age+2). As it turns out, the *(age+2) syntax is the "correct" syntax, in terms of how the language handles arrays (and pointers). The square braces syntax is nothing more than a shorthand for the pointer syntax. When you type age[2], the compiler internally converts it to: *(age+2). In fact, whenever you use the square braces, the compiler just blindly substitutes the first term into the left-hand side of the addition and the second term into the right-hand side of the addition:+</code> 
 + 
 +On lines (6-9) we are using square braces to access elements for initialization.  On line (11) we are using square braces to print out the third element of the array.  From the previous section you might have been led to believe that you would print out the third element by putting something like *(age+2).  As it turns out, the *(age+2) syntax is the "correct" syntax, in terms of how the language handles arrays (and pointers).  The square braces syntax is nothing more than a shorthand for the pointer syntax.  When you type age[2], the compiler internally converts it to: *(age+2). In fact, whenever you use the square braces, the compiler just blindly substitutes the first term into the left-hand side of the addition and the second term into the right-hand side of the addition:
  
 Image: blind substitution from array syntax to pointer arithmetic syntax Image: blind substitution from array syntax to pointer arithmetic syntax
  
-This is actually what happens. If you type +{{:c:c_address_arr_template.jpg?300|}} 
-monkey[ crackers ], the compiler tries to compile+ 
 +This is actually what happens.  If you type 
 + 
 +<code c> 
 +monkey[ crackers ] 
 +</code> 
 + 
 +, the compiler tries to compile 
 + 
 +<code c>
 *(monkey + crackers) *(monkey + crackers)
 +</code>
  
 I'm not kidding! Let's prove it. I'm not kidding! Let's prove it.
  
-When as a youngster you were asked to add 5+3, no problem. But what about when the numbers were switched and you were asked to add 3+5? Still no problem because of the commutative property of addition. The commutative property of addition holds in C and C++ just like it did when you were a youngster. So, *(age+2) produces exactly the same result as *(2+age). That is, the number of bytes equivalent to two short integers is added to age and then the contents are retrieved at that address. OK, so what? In the previous paragraph I said that when you write something like age[2] the compiler blindly substitutes it into its pointer syntax and compiles *(age+2). So, let's turn it around and prove that all of this array stuff is nothing but simple pointer access with a little addition:+When as a youngster you were asked to add 5+3, no problem.  But what about when the numbers were switched and you were asked to add 3+5? Still no problem because of the commutative property of addition.  The commutative property of addition holds in C and C++ just like it did when you were a youngster.  So, *(age+2) produces exactly the same result as *(2+age).  That is, the number of bytes equivalent to two short integers is added to age and then the contents are retrieved at that address.  OK, so what?  In the previous paragraph I said that when you write something like age[2] the compiler blindly substitutes it into its pointer syntax and compiles *(age+2).  So, let's turn it around and prove that all of this array stuff is nothing but simple pointer access with a little addition:
  
 C Code Listing 12 C Code Listing 12
 +
 +<code c>
   1: #include <stdio.h>   1: #include <stdio.h>
   2:    2: 
Line 555: Line 778:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 C++ Code Listing 12 C++ Code Listing 12
 +
 +<code cpp>
   1: #include <iostream>   1: #include <iostream>
   2:    2: 
Line 569: Line 796:
  12:   return 0;  12:   return 0;
  13: }  13: }
 +</code>
 +
 Image: blind substitution from array syntax to pointer arithmetic syntax is equivalent to Image: reversed--blind substitution from array syntax to pointer arithmetic syntax Image: blind substitution from array syntax to pointer arithmetic syntax is equivalent to Image: reversed--blind substitution from array syntax to pointer arithmetic syntax
-The commutative property of addition is being taken advantage of in lines (6-9) and line (11). Don't just stare at the code above, type it in, compile it, and run it! Again, this is nothing but simple pointer arithmetic. For example, on line (11), the third element of the age array is accessed. Before compiling 2[age], the compiler first blindly converts it into *(2+age). Pretty cool, eh? 
  
-We now have more than enough information to answer the question: "Why do arrays in C and C++ start at zero instead of one?". We know that the name of the array produces the address of the beginning of the array; and we know that the beginning of the array is also the address of the first element of the array. So, all of these are exactly the same:+|{{:c:c_address_arr_template1.jpg?%300|}}|is equivalent to|{{:c:c_address_arr_template2.jpg?300|}}| 
 + 
 + 
 +The commutative property of addition is being taken advantage of in lines (6-9) and line (11).  Don't just stare at the code above, type it in, compile it, and run it!  Again, this is nothing but simple pointer arithmetic.  For example, on line (11), the third element of the age array is accessed.  Before compiling 2[age], the compiler first blindly converts it into *(2+age).  Pretty cool, eh? 
 + 
 +We now have more than enough information to answer the question: "Why do arrays in C and C++ start at zero instead of one?" We know that the name of the array produces the address of the beginning of the array; and we know that the beginning of the array is also the address of the first element of the array.  So, all of these are exactly the same: 
 + 
 +  * *age 
 +  * *(age+0) 
 +  * age[0] 
  
-*age 
-*(age+0) 
-age[0] 
 The bottom line: Arrays are nothing more than a bunch of variables of the same type using the same name--that name is the address of the beginning of the bunch of variables. The bottom line: Arrays are nothing more than a bunch of variables of the same type using the same name--that name is the address of the beginning of the bunch of variables.
  
 Re-summarizing, to access any element in an array provide: Re-summarizing, to access any element in an array provide:
  
-The name of the array. This gets the address of the first element of the array. +  * The name of the array. This gets the address of the first element of the array. 
-A number. Pointer arithmetic is used to add this number to the address resulting in the address of one of the elements in the array. Of course if zero is added the address is unchanged (it remains the address of the first element). +  A number. Pointer arithmetic is used to add this number to the address resulting in the address of one of the elements in the array. Of course if zero is added the address is unchanged (it remains the address of the first element). 
-Use the * operator to get the contents at that address. Alternately use the square bracket syntax and the compiler will do the addition and content retrieval for you.+  Use the * operator to get the contents at that address. Alternately use the square bracket syntax and the compiler will do the addition and content retrieval for you.
  
c/basic_arrays.1595273574.txt.gz · Last modified: 2020/07/20 19:32 by 62.138.2.243

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki