| Main |< C/C++ Functions With Return Values Part 6 | C/C++ Pointers Part 2 >| Site Index | Download |


 

 

 

 

 

 

C LAB WORKSHEET 11

C & C++ Pointers Part 1: Playing With Memory Addresses

 

 

 

 

 

 

  1. Understanding and using C/C++ Pointers.

  2. Pointers and array.

  3. Pointers and function.

  4. Pointers and structure data type.

  5. Tutorial references that should be used together with this worksheet are C & C++ pointers part 1 and C & C++ pointers part 2.

int i = 77;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <stdio.h>

 

void main(void)

{

      int myvar;

      printf("Enter an integer: ");

      scanf_s("%d", &myvar);

      printf("The entered data is: %d\n", myvar);

      printf("And it is stored at %p\n", &myvar);

}

C/C++ pointers windows console program output example

int i, *p;

i = 60; // storing an integer value

p = &i  // storing an address of an integer variable

C/C++ pointers and memory addresses relation diagram

char a[1], *pa;

float x, *px;

pa = &a[0]; // storing a character address in a character pointer.

px = &x;    // storing a float address in a float pointer

pa = &x;    // pa is not a pointer variable for floats.

px = 3.40;  // px cannot store floating point values!

 

 
  • pa is a pointer to characters and can’t store addresses of type characters. Also, x can store only addresses to floats. 3.40 is not an address.

  • Conventionally, names for pointer variables usually begin with the letter p, although they don’t have to. Pointer names beginning with p reminds the programmer that this variable may be a pointer and can store only addresses.

  • 60 is an integer constant. The value of 60 will always be 60. i is an integer variable. Its value may be 60 for now, but later it could change. Similarly, AD1A04 is a pointer constant; it is the address of a location in RAM. The address of that location cannot be changed; it will always be AD1A04. However, p is a pointer variable; the address stored in it may change. Typically, the word “pointer” by itself means a pointer variable.

Pointer Arithmetic

  • We can add to or subtract from pointer variables. However, we must remember that adding a number to a pointer does not necessarily add that many bytes but adds that number of storage units. In this text we will assume that characters are stored in one byte, integers in two and floats in four (you can use the sizeof() function to view the real size of the data type stored in your system). Bytes are used to measure the amount or size of memory.

int i, *p;

  • Using our assumptions above, if 1 is added to a pointer integer, such as p, then 2 bytes will be added to the address that is already in it. Similarly if 1 is subtracted from p, then 2 bytes are subtracted from its contents. However, for every integer added to px, a pointer to floats, four is added to its contents because we are assuming that floats are stored using four bytes. In our case, one storage unit is 4 bytes for floats, 2 for integers and 1 for characters.

Arrays And Pointers Relation

  • When arrays are defined, the array name actually holds the starting address of the array. This string address is fixed because we can’t move the array to some other location in memory that easily once the array is created. For example:

int *p, j[ ] = {2, 6, 3, 7, 4};

  • Here, we have a pointer p and an array j[ ]. As seen in the following Figure the value of j is fixed at the address of 1A02 and can’t be changed.

  • Pointer variable can be changed.

More on pointers and memory addresses relation diagram

C/C++ pointers variable and memory addresses

 

More C/C++ pointers, arrays and memory addresses relation diagram

p = &j[2];

p = p + 1;

p = j + 1;

j = j + 1; // not legal

Examples

 

Create an empty Win32 console application project named mypointer. Add a C++ source file named mypointersrc. Set your project compiled as a C code. Build and run the following code.

 

#include <stdio.h>

 

// function prototype

void ReadArr(int *x, int y);

 

void main(void)

{

      // p used to store addresses for array j[ ].

      int i, j[5], *p;

      // q used to store addresses for array x[ ]

      float x[5], *q = &x[0];

      // printing out the addresses of the two arrays.

      p = &j[0];  // line 1

      for(i = 0; i <= 4; ++i)

            printf("Addresses of j[%d] = %p\tAddresses of x[%d] = %p \n", i,  p + i, i, &q[i]);

      // reading numbers into the integer array.

      printf("\nEnter 5 integers\n");

      // for older compiler may use scanf("%d", &j[4]); etc

      // notice there is no &

      scanf_s("%d", &j[4], 4);

      scanf_s("%d", j, 1);

      scanf_s("%d", j + 1, 1);      // j can't change and it hasn't

      p = &j[1];  //  same as p = j + 1;

      p = p + 1;

      // notice there is no &

      scanf_s("%d", p, sizeof(int));

      ReadArr(j, 3);

      // print the array

      printf("The array is: \n");

      for(i = 0; i <= 4; ++i)

            printf("j[%d] = %d  ", i, j[i]);

      printf("\n");

}

 

// function definition, to read a number into x[y]

// receive a pointer integer and integer arguments

// return nothing...

void ReadArr(int *x, int y)

{

      x = x + y;

      scanf_s("%d", x, 1);

}

C/C++ pointers and memory addresses windows console output example

More Pointers Practice

 

  1. Remember that &i will give the address of variable i.  Build and run the following program, show the output and answer the question.

 

#include <stdio.h>

 

void main(void)

{

      int i = 7, j = 11;

      printf("i = %d, j = %d\n", i, j);

      printf("&i = %p, &j = %p\n", &i, &j);

}

 

As you may recall, each variable has a data type, name, value and address associated with it. In the following Figure, inside the boxes, under the label of “value”, show the values of i and j. Likewise, on the lines under the label marked “Address”, show the addresses of i and j in RAM from your output.

 

pointers and memory addresses relation

Keep in mind that those addresses are different from the shown on the left and may also different with your friends.

 

 

------------------------------------------------------

 

 

 

  1. Build and run the following program, show the output and answer the questions.

 

#include <stdio.h>

 

void main(void)

{

      int i = 7, j = 11;

      printf("i = %d, j = %d\n", i, j);

      printf("&i = %p, &j = %p\n", &i, &j);

      // reassign new values...

      i = 4;

      j = 5;

      // reprint...

      printf("\ni = %d, j = %d\n", i, j);

      printf("&i = %p, &j = %p\n", &i, &j);

}

  1. After the initialization statement, were we able to change the values of the variables?

  2. After the assignment statements, were we able to change the addresses of the variables? Try &i = 4;

  3. Now at the end of main(), add the following statement and try running it: j = &i; Were we able to store the address of i into j?

  1. Yes.

  2. No we can't. The &i = 4; generate the following error during the build time.

"...error C2106: '=' : left operand must be l-value..."

  1. We add the following code at the end of main().

// assigning the address of variable i to normal variable j

j = &i;

printf("\ni = %d, j = %d\n", i, j);

printf("&i = %p, &j = %p\n", &i, &j);

 

 

Yes we can store the address of i into j.

 

 

  1. We need a new way to define a variable if that variable will store memory addresses or RAM locations. Notice the declaration of pOne using an asterisk. *pOne is a variable that can hold the memory addresses of integers. Show the output and answer the questions.

 

#include <stdio.h>

 

void main(void)

{

      int i = 7;      // Statement 1

      int *pOne;  // Statement 2

      float x = 0.00;

      printf("&i = %p \n", &i);

      pOne = &i;  // Statement 3

      printf("pOne = %p\n", pOne);

}

 

More on pointers and memory addresses relation

  1. In the above diagram show the value of i inside its box and next to its address.

  2. After Statement 3 is executed, what is the value of pOne? Show the value in the diagram.

  3. Can you assign only addresses to pOne? Can you assign an integer as shown below to pOne?

pOne = 4;

  1. From Statement 1 and 2, how can we tell beforehand that i can hold only integers and pOne can hold only the addresses of integer?

  2. Try assigning an address of a float as shown below to pOne. Does it work?

pOne = &x;

  1. Does pOne have its own memory location in RAM, as shown in the diagram? If so, show the address where pOne is stored. Try:

printf("&pOne = %p\n", &pOne);

 

 

We can assign addresses or an integer to pOne.

 

 

However assigning an integer to pOne has no valuable purpose in programming because we don't know what is stored at the address and programming wise it is illegal.

  1. We need to use an asterisk (*) to denote the variable can only hold the address of integer.

  2. Yes it works with warning during the building.

"warning C4133: '=' : incompatible types - from 'float *__w64 ' to 'int *'"

  1. Yes pOne have its own memory location in memory.

 

 

 

 

  1. The following experiment is a review of the previous experiments. Show the output and answer the questions.

 

#include <stdio.h>

 

void main(void)

{

      char a = 'Q', *pa;

      // the F modifier force the value to float

      // else by default it is a double

      float x = 7.3F, *px;

      int i = 2, *m;

      pa = &a;

      px = &x;

      m = &i;

      printf("pa = %p\npx = %p\n m = %p\n", pa, px, m);

}

  1. Out of the six variables declared, which may store addresses?

  2. In the following Figure, show the values of a, x and i.

  3. From the output, show the values of pa, px and m in the Figure below.

pointers variables and memory addresses relation

  1. Now that you know the values of pa, px and m, what are the addresses of a, x, and i? Show them in the Figure.

  2. Must variable that store addresses begin with the letter p? If not, how can we tell from the declaration of these variables that they can store addresses?

  3. Which variable(s) may store only (single) characters?

  4. Which variable(s) may store addresses to characters?

  5. Can you store the address of a float in pa? Can you store the address of an integer in pa? If not, what error or warning message is obtained? For example:

pa = &x;

pa = &i;

  1. Can you store a character in pa? If not, what error message is obtained?

pa = 'Q';

  1. Can you change the address of a variable? If not, what error message is obtained?

&a = 4440;

  1. Try storing the addresses of a and i in px. Does px hold the addresses of floats only?

px = &a;

px = &i;

  1. Try storing the addresses of a and x in m. Does m hold the addresses of integers only?

m = &a;

m = &x;

  1. What can you store in a? What can you store in pa? What in their declarations identifies the difference?

  2. What can you store in x? What can you store in px? What in their declarations identifies the difference?

 

 

  1. *pa, *px and *m will store addresses.

 

 

  1. Not really. However as a convention, pointer variables prefix with 'p' to denote it is a pointer variable. The asterisk (*) will denote the variable is a pointer variable.

  2. Variable a.

  3. Variable *pa.

  4. Yes we can assign other pointer types. However this will deviate the purpose of declaring the original variable and programming wise it is illegal. The following are the warning generated. The code run without any error.

"warning C4133: '=' : incompatible types - from 'float *__w64 ' to 'char *'"

"warning C4133: '=' : incompatible types - from 'int *__w64 ' to 'char *'"

  1. Same as (h) with the following warning message.

"warning C4047: '=' : 'char *' differs in levels of indirection from 'int'"

  1. No we can't. The code generates the following error.

"error C2106: '=' : left operand must be l-value"

  1. No it doesn't. However the following warnings generated.

"warning C4133: '=' : incompatible types - from 'char *__w64 ' to 'float *'"

"warning C4133: '=' : incompatible types - from 'int *__w64 ' to 'float *'"

  1. No it doesn't. However the following warnings generated.

"warning C4133: '=' : incompatible types - from 'char *__w64 ' to 'int *'"

"warning C4133: '=' : incompatible types - from 'float *__w64 ' to 'int *'"

  1. By avoiding any warning/error we can store a character in variable 'a' and we can store an address (memory location) in pa that point to a character data type.

  2. By avoiding any warning/error we can store a float in variable x and we can store an address (memory location) in px that point to a float data type.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  1. Show the output and answer the questions.

 

#include <stdio.h>

 

void main(void)

{

      char a = 'Q', b = 'X', *pa, *pb;

      pa = &a;    // Statement 1

      pb = pa;    // Statement 2

      printf("pa = %p, pb = %p\n", pa, pb);     // Statement 3

      pa = &b;

      printf("pa = %p, pb = %p\n", pa, pb);

}

  1. Can we assign a variable that stores addresses to another variable, like in Statement 2?

  2. Can we store the address of any character variable in either pa or pb? How can you tell it?

  3. Where is the variable 'a' stored? Where is the variable 'b' stored? Fill in the following diagram.

More on C/C++ pointers and memory addresses relation

  1. What is the first address stored in pa? Show it in the diagram.

  2. Strike out that value you just placed for pa and write next to it the new address stored in pa.

  3. From this experiment, can you tell where pa and pb are stored? If not, give the Statement that will print these addresses and copy those addresses in the diagram.

 

 

  1. Yes, provided both are pointer variables that point to a similar data type.

  2. We can store address of any character variable in pa or pb because both pointer variables point to a similar data type, a char. Programming wise, in this case it is legal.

 

 

  1. By adding the following two line of codes we can see a complete scenario when the program re-build and re-run.

// printing the data stored pointed by those pointers

printf("*pa = %c, *pb = %c\n", *pa, *pb);

// printing the addresses of those pointers

printf("&pa = %p, &pb = %p\n", &pa, &pb);

 

 

 

 

 

 

www.tenouk.com

 

| Main |< C/C++ Functions With Return Values Part 6 | C/C++ Pointers Part 2 >| Site Index | Download |


The C & C++ Pointers: Part 1 | Part 2 | Part 3