User Tools

Site Tools


c:pointers

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:pointers [2016/08/05 13:58] peterc:pointers [2020/07/15 09:30] (current) – external edit 127.0.0.1
Line 277: Line 277:
 The address of fl is stored in addr The address of fl is stored in addr
  
 +{{:c:c_address_float_addr1.jpg?500|}}
  
 +  * The function somefunc is called at line (11) and fl's address is passed as an argument.
 +  * The function somefunc begins at line (2), fptr is created and fl's address is copied into fptr.
  
-The function somefunc is called at line (11) and fl's address is passed as an argument. 
-The function somefunc begins at line (2), fptr is created and fl's address is copied into fptr. 
 The argument addr is copied to fptr The argument addr is copied to fptr
-The * operator is used on fptr at line (4) -- do step 2, the contents stored in an address are retrieved. In this example, the contents at address 924 are retrieved. + 
-The contents at address 924 are assigned the value 99.9.+{{:c:c_address_float_addr1_fptr1.jpg?500|}} 
 + 
 +  * The * operator is used on fptr at line (4) -- do step 2, the contents stored in an address are retrieved.  In this example, the contents at address 924 are retrieved. 
 +  The contents at address 924 are assigned the value 99.9. 
 99.9 is assigned to fl 99.9 is assigned to fl
-The function finishes. Control returns to line (12). 
-The contents of fl are printed to the screen. 
-Pointer Variables 
  
-Even though we have shown that an address is nothing more than a simple integer, the creators of the language were afraid we might confuse variables in our programs. We might confuse integers we intend to use for program values (e.g. variables storing ages, measurements, counters, etc.) with integers we intend to use for holding the addresses of our variables.+{{:c:c_address_float_addr1_fptr2.jpg?500|}}
  
-The language creators decided the best way to eliminate confusion was to create a different type of variable for holding addressesA first attempt at this might have looked something like this:+  * The function finishes. Control returns to line (12). 
 +  * The contents of fl are printed to the screen.
  
 +
 +
 +===== Pointer Variables =====
 +
 +Even though we have shown that an address is nothing more than a simple integer, the creators of the language were afraid we might confuse variables in our programs.  We might confuse integers we intend to use for program values (e.g. variables storing ages, measurements, counters, etc.) with integers we intend to use for holding the addresses of our variables.
 +
 +The language creators decided the best way to eliminate confusion was to create a different type of variable for holding addresses.  A first attempt at this might have looked something like this:
 +
 +<code c>
 1:... 1:...
 2:  float fl=3.14; 2:  float fl=3.14;
 3:  float Ptr addr = &fl; 3:  float Ptr addr = &fl;
 4:... 4:...
-On line (3), here is how to describe the addr variable:+</code> 
 + 
 +  * On line (3), here is how to describe the addr variable: 
 addr is a pointer to a float  addr is a pointer to a float 
-(A) addr is an integer. (B) However, it is a special integer designed to hold the address of a (C) float 
  
-In the code above, line (3) is close to what the creators of the language wanted except for one thing: using Ptr would require introducing another keyword into the language. If there is one thing that all C instructors like to brag about, it is how there are only a very small number of keywords in the language. Well, using line (3) as shown above would mean adding Ptr as another keyword to the language.+{{:c:c_address_ptr_desc1.jpg?500|}} 
 + 
 + 
 +  * (A) addr is an integer.  (B) However, it is a special integer designed to hold the address of a (C) float. 
 + 
 +In the code above, line (3) is close to what the creators of the language wanted except for one thing: using Ptr would require introducing another keyword into the language.  If there is one thing that all C instructors like to brag about, it is how there are only a very small number of keywords in the language. Well, using line (3) as shown above would mean adding Ptr as another keyword to the language.
  
-To avoid this threat to the very fabric of the universe, the creators cast about for something already being used in the language that could do double duty as Ptr shown above. What they came up with was the following:+To avoid this threat to the very fabric of the universe, the creators cast about for something already being used in the language that could do double duty as Ptr shown above.  What they came up with was the following:
  
 +<code c>
 1:... 1:...
 2:  float fl=3.14; 2:  float fl=3.14;
 3:  float * addr = &fl;  3:  float * addr = &fl; 
 4:... 4:...
-Even with the * instead of Ptr, addr is described the same way:+</code> 
 + 
 +  * Even with the * instead of Ptr, addr is described the same way: 
 addr is a pointer to a float  addr is a pointer to a float 
-(A) addr is an integer. (B) However, it is a special integer designed to hold the address of a (C) float+ 
 +{{:c:c_address_ptr_desc2.jpg?500|}} 
 + 
 +  * (A) addr is an integer.  (B) However, it is a special integer designed to hold the address of a (C) float
  
 These variables are described this way, regardless of the type: These variables are described this way, regardless of the type:
  
 addr is a pointer to a char  addr is a pointer to a char 
-(A) addr is an integer. (B) However, it is a special integer designed to hold the address of a (C) char+ 
 +{{:c:c_address_ptr_desc3.jpg?500|}} 
 + 
 +  * (A) addr is an integer.  (B) However, it is a special integer designed to hold the address of a (C) char.
  
 addr is a pointer to an int  addr is a pointer to an int 
-(A) addr is an integer. (B) However, it is a special integer designed to hold the address of an (C) int+ 
 +{{:c:c_address_ptr_desc4.jpg?500|}} 
 + 
 + 
 +  * (A) addr is an integer. (B) However, it is a special integer designed to hold the address of an (C) int.
  
 This "...special integer..." way of describing these variables is a mouthful, so we shorten it and just say "addr is a float pointer" or "addr is a pointer to a float" (or char, or int, etc.). This "...special integer..." way of describing these variables is a mouthful, so we shorten it and just say "addr is a float pointer" or "addr is a pointer to a float" (or char, or int, etc.).
  
-Unfortunately, the language creators chose the * character to replace Ptr. The * character is confusing because the * character is also used to get the contents at an address ("do step 2 on a number"). These two uses of the * character have nothing to do with each other.+Unfortunately, the language creators chose the * character to replace Ptr.  The * character is confusing because the * character is also used to get the contents at an address ("do step 2 on a number").  These two uses of the * character have nothing to do with each other.
  
-What is all that "syntax sugar" anyway? (Casting)+ 
 +===== What is all that "syntax sugar" anyway? (Casting) =====
  
 Let's take one last look at our original code that illustrates the utility of separating out steps 1 & 2. Let's take one last look at our original code that illustrates the utility of separating out steps 1 & 2.
  
 C Code Listing 7 C Code Listing 7
 +
 +<code c>
  1: #include <stdio.h>  1: #include <stdio.h>
  2: void somefunc(unsigned long int fptr)  2: void somefunc(unsigned long int fptr)
Line 344: Line 381:
 13:   return 0; 13:   return 0;
 14: } 14: }
 +</code>
 +
 C++ Code Listing 7 C++ Code Listing 7
 +
 +<code c++>
  1: #include <iostream>  1: #include <iostream>
  2: void somefunc(unsigned long int fptr)  2: void somefunc(unsigned long int fptr)
Line 359: Line 400:
 13:   return 0; 13:   return 0;
 14: } 14: }
-In nearly all of the code samples, you have been asked to ignore certain bits of the code. These bits of code have always appeared around those areas where we are either taking the address of a variable or getting the contents at an address (doing step 1 or step 2 on a variable)+</code>
  
-Those bits of "syntax sugar" are there to keep the compiler from complainingThe first example of this in the above program is on line (10).+In nearly all of the code samples, you have been asked to ignore certain bits of the code These bits of code have always appeared around those areas where we are either taking the address of a variable or getting the contents at an address (doing step 1 or step 2 on a variable)
  
-On line (10) we are taking the address of the floating point number fl ("do only step 1 on a number"). After we get that address, we store it in addr.+Those bits of "syntax sugar" are there to keep the compiler from complaining.  The first example of this in the above program is on line (10).
  
-Why would the compiler complain? Because when we assign the address of fl to addr, the compiler does not expect addr to be an unsigned long int. The compiler expects addr to be float *That is, a special integer designed to hold the address of a float. To keep the compiler from complaining, we tell the compiler to treat &fl as an unsigned long int rather than a float *.+On line (10) we are taking the address of the floating point number fl ("do only step 1 on number") After we get that address, we store it in addr.
  
-This "syntax sugar" that causes the compiler to treat variables and expressions differently is called casting. The way programmer describes line (10) is: "The address of fl is being cast into an unsigned long int and assigned to addr"+Why would the compiler complain?  Because when we assign the address of fl to addr, the compiler does not expect addr to be an unsigned long int The compiler expects addr to be float *.  That is, a special integer designed to hold the address of a float.  To keep the compiler from complaining, we tell the compiler to treat &fl as an unsigned long int rather than a float *.
  
-The other place casting occurs is on line (4)On line (4), we are getting the contents at an address ("do step 2 on a number/address"). Why would the compiler complain? Because the compiler should get the contents of the address of a float. The address of our float is in stored in fptr, which is an unsigned long int, not a float *. We tell the compiler to treat fptr as the address of a floating point number by casting it into a float *. Once we tell the compiler this, we can get the contents at the address without complaint.+This "syntax sugar" that causes the compiler to treat variables and expressions differently is called casting.  The way a programmer describes line (10is: "The address of fl is being cast into an unsigned long int and assigned to addr"
  
-Putting it all together+The other place casting occurs is on line (4). On line (4), we are getting the contents at an address ("do step 2 on a number/address").  Why would the compiler complain?  Because the compiler should get the contents of the address of a float.  The address of our float is in stored in fptr, which is an unsigned long int, not a float *.  We tell the compiler to treat fptr as the address of a floating point number by casting it into a float *.  Once we tell the compiler this, we can get the contents at the address without complaint.
  
-From the previous section, you might be left with the impression that whenever you deal with addresses and pointers, there is a lot of casting. Not so. The only reason our examples up till now have required casting is because we were storing our addresses in unsigned long int variables. The language designers want us to store addresses in the "special integer" variables, that is, the pointer variables they designed for just such a purpose.+ 
 +===== Putting it all together ===== 
 + 
 +From the previous section, you might be left with the impression that whenever you deal with addresses and pointers, there is a lot of casting.  Not so.  The only reason our examples up till now have required casting is because we were storing our addresses in unsigned long int variables.  The language designers want us to store addresses in the "special integer" variables, that is, the pointer variables they designed for just such a purpose.
  
 Once we replace our unsigned long int variables with these pointer variables, none of the casting is required: Once we replace our unsigned long int variables with these pointer variables, none of the casting is required:
  
 C Code Listing 8 C Code Listing 8
 +
 +<code c>
  1: #include <stdio.h>  1: #include <stdio.h>
  2: void somefunc(float* fptr)  2: void somefunc(float* fptr)
Line 392: Line 438:
 13:   return 0; 13:   return 0;
 14: } 14: }
 +</code>
 +
 C++ Code Listing 8 C++ Code Listing 8
 +
 +<code c++>
  1: #include <iostream>  1: #include <iostream>
  2: void somefunc(float* fptr)  2: void somefunc(float* fptr)
Line 407: Line 457:
 13:   return 0; 13:   return 0;
 14: } 14: }
-On line (10), when we take the address of fl the address is assigned to a variable designed to hold it. No casting is required. +</code> 
-When addr is passed to the function in line (11), addr is copied to fptr on line (2). + 
-Line (2) shows that fptr is created as a float pointer, that is a variable designed to hold the address of a floating point number. As a result, no casting is needed on line (4) where the contents at the address are retrieved.+  * On line (10), when we take the address of fl the address is assigned to a variable designed to hold it.  No casting is required. 
 +  When addr is passed to the function in line (11), addr is copied to fptr on line (2). 
 +  Line (2) shows that fptr is created as a float pointer, that is a variable designed to hold the address of a floating point number.  As a result, no casting is needed on line (4) where the contents at the address are retrieved. 
 + 
c/pointers.1470405529.txt.gz · Last modified: 2020/07/15 09:30 (external edit)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki