Pointers

On our machine storm.cis.fordham.edu, a memory address is customarily written in hexadecimal notation.

Display the value of an integer in decimal, binary, and hexadecimal.

The places of a number (2024) written in decimal (base 10)

1000’s
place
100’s
place
10’s
place
1’s
place
2 0 2 4
2 × 1000 = 2000
0 ×  100 =    0
2 ×   10 =   20
4 ×    1 =    4
           2024

The places of the same number (2024), written in binary (base 2)

1024’s
place
512’s
place
256’s
place
128’s
place
64’s
place
32’s
place
16’s
place
8’s
place
4’s
place
2’s
place
1’s
place
1 1 1 1 1 1 0 1 0 0 0
1 × 1024 = 1024
1 ×  512 =  512
1 ×  256 =  256
1 ×  128 =  128
1 ×   64 =   64
1 ×   32 =   32
0 ×   16 =    0
1 ×    8 =    8
0 ×    4 =    0
0 ×    2 =    0
0 ×    1 =    0
           2024

As you see in the case of the number 2024, it usually takes many, many more binary digits than decimal digits to write the value of a number. That’s why they invented hexadecimal digits.

Each hexadecimal digit (hex digit) stands for four binary digits (bits).

Eight bits is called a byte.
Four bits is called a nibble.
So each hex digit stands for one nibble.
For example, the hex digit E stands for the nibble 1110.

  32768’s
place
16384’s
place
8192’s
place
4096’s
place
2048’s
place
1024’s
place
512’s
place
256’s
place
128’s
place
64’s
place
32’s
place
16’s
place
8’s
place
4’s
place
2’s
place
1’s
place
binary 0 0 0 0 0 1 1 1 1 1 1 0 1 0 0 0
hex 0 7 E 8

Here are the 16 nibbles that the 16 hex digits stand for.

hex digit 4 bits
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

Conversion programs

  1. decimaltohex.C: convert base 10 to base 16.
  2. hextodecimal.C: convert base 16 to base 10.
  3. table.C: decimal (base 10) and hexadecimal (base 16), side by side.

The address of a variable

  1. address.C: output the address of a variable in hexadecimal.
    The value of i is 10
    The address of i is 0x7fff2757276c
    The number of bytes in i is 4
    
  2. pointer.C: store the address of a variable in another variable, called a pointer.
  3. dereference.C: use the unary * operator to dereference a “pointer to an int” to get the value of the original int.
    (The binary * operator means multiplication.)
  4. struct.C: use the unary * operator to dereference a “pointer to a structure” to get the value of each field of the original structure.

Pointers and loops

  1. increment: when you increment a pointer with ++, how much does the pointer increase?
  2. loop.C: loop through an array of ints with a pointer to an int.
    Exercise.
    Now I can tell you what begin and end really mean. In loop.C, change &a[0] to begin(a), and change &a[n] to end(a).
  3. movingaverage.C: use a pointer to concentrate on three consecutive elements of an array.

Pointer arguments vs. reference arguments

  1. reference2.C: a reference argument makes it hard to see that a function could change the value of one of its actual arguments.
  2. reference3.C: a pointer argument makes it obvious that a function could change the value of one of its actual arguments.
  3. My recommendations:
    1. Let the formal argument be a pointer when you want to allow the function to change the value of the actual argument.
    2. Let the formal argument be a reference when you merely want to avoid the time and expense of creating a copy of the value of the actual argument.

Pass an array to a function using pointers.

  1. minimum.C: pass the address of the first element of the array, and the address that is just after the last element.
  2. My recommendation:
    When passing an array a to a function, let the formal arguments be the address of the first element, and the address of just beyond the last element. Then use begin(a) and end(a) as the actual arguments.
  3. Write a function named sort that takes the same two formal arguments as the function in minimum.C. The sort function will sort the elements of the array into increasing order, using the algorithm we saw in bubblesortint.C.

The end. Thank you.