-
Using
the variables in question #1, show the printouts for each of the
following.
for(i = 0; i <= 4; i++)
printf("j
+ i = %p, j[%d] = %d\n", j + i, i, j[i]);
---------------------------------------------------------------------
for(i = 0; i <= 4; ++i)
printf("x
+ i = %p, &x[%d] = %p, x[%d] = %.2f\n", x + i, i, &x[i],
i, x[i]);
----------------------------------------------------------------------
for(ptr2 = x + 4; ptr2 >= x; --ptr2)
printf("ptr2
= %p, ptr2 - 1 = %p\n", ptr2, ptr2 - 1);
|

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

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

|
| |
|
-
Define
a float array called t[ ] with 10 slots.
Send the address of the first element of the array to a function
called ReadThemAll(). Also send 2 and
6 as integers. The function will assign the array address to a pointer
called p and read floats in all the
slots between these two numbers, inclusive. Although the
ReadThemAll() function will read in
the t[ ] array of
main(), the ReadThemAll()
function should not use brackets, [ ]
but only the asterisk operator, *.
When the function is done, have main()
print out the entire array. See the following Figure for the detail.
Write a complete program.

|
#include <stdio.h>
// a prototype
void ReadThemAll(int *x, int y, int
z);
void main(void)
{
int t[10];
int j, p = 2, q = 6;
// array's name without a bracket
is a pointer
// to the first element of
the array
ReadThemAll(t, p, q);
for(j=p;j<=q;j++)
printf("t[%d]
= %d\n", j, t[j]);
}
void ReadThemAll(int *x, int y, int
z)
{
int i;
for(i=y; i<=z;i++)
// assign 7 to all the element
x[i] = 7;
}

|
| |
|
-
Write
a function called FindIt(). This function
will receive z[ ], a float array;
size, an integer specifying the number
of slots in the array and look, a float.
The function will look for look in
the array and return the address where that number was found in
the array. Assume that the number will be found. Write
main() to go with the function that
will pass the appropriate variables and receive the address where
the number was found into a pointer. Then print out that address.
|
#include <stdio.h>
// a prototype, the return value
is an address
// so we use a pointer to a float
value
float * FindIt(float *z, int size,
float look);
void main(void)
{
// f or F just a modifier to force
the type/value to float,
// because double will be
assumed by default
// it looks similar in Java
:-)
float num[5] = {3.5f, 5.7f,
2.3f, 1.7f, 7.8f};
float find = 2.3f;
int slot = 5;
// this will store the return 'address'
float *addr;
// bring along all necessary arguments...
// an array, array's size
and a float to be searched
addr = FindIt(num, slot, find);
printf("The address of value
%.2f is %p\n", find, addr);
}
float * FindIt(float *z, int size,
float look)
{
int i;
float *loc;
for(i=0; i < size; i++)
{
printf("z[%d]
= %.2f at %p\n", i, z[i], &z[i]);
// take note here. We are comparing
an array value
// to a fix value
if(z[i] == look)
loc = &z[i];
}
// return the address through a pointer
return loc;
}

|
| |
|
More Pointers Questions
And Practice
-
Let
us first review how computers count:
1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C,
D, E, F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D,
1E, 1F, 20, 21 and so on.
This method of counting numbers is called
the hexadecimal numbering system
or hex for short. Keep
in mind that computers process data based on
binary numbering system,
0 and 1. You can use scientific calculator to convert to other numbering
system for example, binary to hex or to
decimal numbering system
that we are familiar to.
-
In hex, what number comes after 9, 19, F and 1D?
-
In hex, what number comes before 10, 20, F and 2E?
-
In hex, what number comes after 99, 299, 29F, FFEF and 9FF?
|
-
A,
1A, 10 and 1E respectively.
-
F,
1F, E and 2D respectively.
-
9A,
29A, 2A0, FFF0 and A00 respectively.
|
| |
|
|
Using
the Hex mode from Windows scientific calculator.
|

|
| |
|
-
Each
memory location (also called Random Access Memory - RAM) in a computer has an address so
that the system knows which location to access. Each location typically
stores one byte of data. The amount of data RAM can store is measured
in bytes. In the following Figure, each memory location’s address
is shown. What is the memory address of the location that is 5 addresses
away from FFAE?

|
FFB3 (FFAE
+ 5)
|
| |
|
-
More
memory locations are shown here after location FFB8. For those locations,
their contents are also shown. In which location is 23 stored? What
is the address of the memory location that is 10 addresses before
the location where 112 is stored?

|
23 is
stored at FFBD. The address is FFB6 (FFC0 - A where 10 is A in hex)
|
| |
|
-
In the
following array declaration, array a[ ]
is defined and initialized. Some computers need two bytes of memory
to store integers as shown in the Figure. What is the starting address
of the location where 28 is stored? How many bytes are needed to
store a 4-element integer array shown below?
int a[4] = {4, 77, 28, 12};
|
The starting
address for the 28 is FFC3. It takes 16 bytes to store 4-element integer
array. Every integer will take 4 bytes each, then 4 x 4 = 16 bytes.
16 is equal t o10 in hex. Hence, FFBB + 9 = FFCA (9 is used because
the first address index is 0) or the first address that is FFBB already
considered as 1 location.
|
|

The following
code sample can be used to determine the array size.
#include <stdio.h>
void main(void)
{
int a[4] = {4, 77, 28, 12};
printf("The size of a is %d\n",
sizeof(a));
}

|
| |
|
|

|
| |
|
-
If 1
byte is needed to store characters on a certain computer and 4 bytes
are needed to store floats, show the starting addresses of each
array slot in the diagram for these two arrays. The starting addresses
of b[ ] and x[
] are given. Also, where does x[ ]
end?
char b[5] = "Only";
float x[2] = {44.0, -24.1};

|

The x[
] ends at C77D.
|
| |
|
-
Answer
the following questions based on the structure data type.
struct
money
{
char Country[10];
int Denomination;
float ConversionFactor;
};
struct
money rupees[6];
-
How many bytes does each slot of
rupees[ ]
occupy?
-
What is the (starting) address of
each slot of
rupees[ ]
if the first one starts at
FF10?
|
-
Theoretically
every slot of rupees[ ] will occupy 10 + 4 +4 = 18 bytes.
-
Theoretically
they are FF10, FF28, FF40, FF58, FF70, FF88, ..., ...
In
the real situation memory allocation should be slightly different
(normally allocated more than theoretically they should be) because
of the memory alignment. The 32 bits will consist of 4 bytes. Each
bytes is 8 bits in size. A single byte will consist of 2 nibbles
that is 4 bits each and nibble may be the smallest alignment. In
this case the allocated memory will be in multiple of 8 bits (1
byte) though the variable just only need 5 bits more, 8 bits (1
byte) in size will be allocated. For example, in 32 bit system,
this struct will have 20 bytes in size.
In this case using 4 bytes for every 32 bits in size, we need 4
bytes x 5 memory slots alignment = 20 bytes. If the system allocate
4 memory slots alignment, it is not enough because 4 bytes x 4 memory
slots = 16 bytes while the struct need
18 bytes. Hence the nearest alignment is 4 bytes x 5 memory alignment
slots = 20 bytes. However this also depend on the processor and/or
the computer architecture itself such as PowerPC, Power and Intel
based system.
#include <stdio.h>
struct money
{
char Country[10];
int Denomination;
float ConversionFactor;
};
void main(void)
{
struct money rupees[6];
printf("The size of char
is %d\n", sizeof(char));
printf("The size of int
is %d\n", sizeof(int));
printf("The size of float
is %d\n", sizeof(float));
printf("The size of struct
money is %d\n", sizeof(struct money));
printf("The size of rupees
is %d\n", sizeof(rupees));
}

Try
change the size of the Country's array to different sizes, rebuild
and re-run this program and notice the new
struct size. Different array sizes may have same size of
struct because of the memory alignment.
|
| |
|
-
Pointers
are special kinds of variables used to store memory addresses. You
use an asterisk in front of the variables when defining a pointer.
int i, *p1;
float x, *p2;
-
Which of the four variables above
are pointers:
i,
x,
p1 and/or
p2?
-
Which of these four items can store
addresses?
|
-
*p1
and *p2 are pointer variables.
-
*p1
and *p2 can store addresses.
|
| |
|
-
Not
only is p1 a special kind of variable
(a pointer variable) it is also a special kind of a pointer.
p1 is a pointer to integers only. Therefore,
if 1 is added to p1, then actually
4 is added to it because we are assuming that integers take 4 bytes
to store on our computer.
int i, *p1;
float x, *p2;
-
If we say,
p1 = p1 + 3;
and the initial value of
p1
is
FF18, what will be the final
value of
p1?
-
If the initial value of
p1
was
CD1E
and we add 5 to it, what will
p1
become?
-
If floats need 4 bytes of RAM to
be stored and initially
p2
is
7D50, what will be the value
of
p2 after 3 is
added to it?
-
If
p2
is initially
CABB and 5
is added to it, what will
p2 become?
|
-
Final
value of p1 is FF24. Here 3 x 4 bytes each = 12 bytes far away.
12 in hex is C. Then FF18 + C = FF24.
-
Here
5 x 4 bytes each = 20 bytes. 20 in hex is 14. Then CD1E + 14 = CD32.
-
Here
3 x 4 bytes each = 12 bytes in total. 12 is C in hex. Then 7D50
+ C = 7D5C.
-
Similar
to (b), 5 x 4 bytes each = 20 bytes. Then CABB + 14 = CACF.
|
| |
|
-
As
before, p1 is a pointer to integers
and p2 is a pointer to floats. Before
each part below, assume p1’s initial value is
F100 and p2’s initial value is
F2CC. Give the values of p1 and p2
after each of these statements:
-
p1 = p1 + 2;
-
p1 = p1 – 2;
-
p2 = p2 + 2;
-
p2 = p2 – 2;
|
-
F100
+ 8 = F108.
-
F100
- 8 = F0F8.
-
F2CC
+ 8 = F2D4.
-
F2CC
- 8 = F2C4.
|
| |
|
-
Assume
that p1 has the address of
i[0] and p2
has the address of x[0].
int i[5], *p1;
float x[5], *p2;
-
After the statement
p1 = p1 + 3;
p1
will contain the address of which slot in the array
i[
]?
-
After this statement
p2 = p2 + 3;
p2
will contain the address of which slot in the array
x[
]?
-
In total how many address locations
were added in
a?
In
b?
-
In total how many indexes were added
in
a?
In
b?
|
-
Slot
number 3 (index number 2).
-
Slot
number 3 (index number 2).
-
A
total of 3 x 4 = 12 address locations both in a. and b. (inclusive
the first slot else just 11 address locations).
-
3
indexes were added for both a. and b..
|
| |
|
-
i[0]
is stored at F400 and x[0] is stored
at BBB0. Assume that initially, p1
has the address of i[0] and p2 has the address of x[0] answer the
following questions.
int i[15], *p1;
float x[15], *p2;
-
If
p1
contains
F410,
it has the address of which slot of the array
i[ ]?
-
If
p2
contains
BBC0,
it has the address of which slot of the array
x[ ]?
|
-
Slot
number 4. (F410 - F400) = 10. 10 is 16 in decimal. So 16 / 4 bytes
per integer = 4.
-
Slot
number 4. (BBC0 - BBB0) = 10. 10 is 16 in decimal. So 16/4 bytes
per float = 4.
|
| |
|
-
Which
of the following statements are valid and give reason?
-
p1 = &i[0];
-
p1 = &x[0];
-
p1 = i[0];
|
-
This
is valid because the address of the first array element is assign
to the pointer *p1 and both have a similar type,
int.
-
Not
valid because address of the first float type array is assigned
to an integer type pointer.
-
Not
valid because we cannot assign a value (i[0] - array's element)
to a pointer that hold an address.
|
| |
|
-
The
name of the array (without the bracket) is equal to the address
of the first slot/index in that array. If x[5] is stored starting
at AA00, then what is the value of
x? What is the value of &x[0]?
|
The value
of x (a pointer to the first address of the array element) and
&x[0]
(address of the first array's element) is AA00.
|
| |
|
-
If
x[15] is stored starting at AA00, then
what is the address of each?
-
x + 2
-
&x[2]
|
-
AA00
+ 2 = AA02.
-
AA00
+ the address of the third array's element depending on the type
of the array.
|
| |
|
-
Arrays
are similar to pointers. One difference is that we can’t change
the value of the array address, but we can change the value of a
pointer variable. Using the declaration given below, which of the
following statements are valid and give reason?
int i[15], *p1;
float x[15], *p2;
-
x = x + 1;
-
x = p2 + 1;
-
p2 = x + 1;
-
p2 = p2 + 1;
-
x[2] = x[2] + 1;
-
&x[2] = p2;
|
-
Valid.
Add 1 to the first array's address, x and assign the new address
to the first array's address, x overwriting the previous address.
-
Valid.
Add 1 to the pointer p2, and assign the new address value to the
first array element's address, x.
-
Valid.
Add 1 to the first array element's address, x and assign this new
address to the pointer *p2.
-
Valid.
Add 1 to pointer p2 and assign this new value to pointer p2 (previous
value will be overwritten).
-
Valid.
Add 1 to the third array's element, x[2] and assign this new value
to the third array's element, x[2], overwriting the previous value.
-
Valid.
Assign pointer p2 to the third array element address, &x[2].
|
| |
|
-
An
array can be considered as a pointer constant and its address
can’t be changed. A pointer variable such as
p2 can have the address stored in it
changed. Which of the following two initializations are valid?
int *ptr1;
int i[10] = &ptr1;
int i[10];
int *ptr1 = &i[0];
|
The second
one is valid. In the first one we try to change the address of the 11th
array element by assigning pointer ptr1.
|
| |
|
-
When
we pass an array to a function, we actually pass the address of
that array. Hence, a function that receives an array as an argument
can receive it as a pointer. Write a function header for a function
called MyFunction(), where an array
is received into float pointer called p.
A float pointer is returned by the function.
|
float
* MyFunction(float *p);
|
| |
|
-
Write
the main() code that will pass this
array to MyFunction(). Also write the
MyFunction() that will print the addresses
of the first five elements of the array and return the address of
the fifth element. main() will receive
that address into a pointer called q
and it will print it.
|
#include <stdio.h>
// a function prototype
float * MyFunction(float *p);
void main(void)
{
float test[10] = {1.55f,2.4f,3.5f,4.7f,5.2f,6.1f,7.28f,8.8f,9.32f,11.77f};
float *q;
// call MyFunction bringing along
the array through a pointer
q = MyFunction(test);
printf("The address of the
fifth element is %p\n", q);
}
float * MyFunction(float *p)
{
int i;
// a good practice to assign uninitialized
// pointer to NULL. NULL point
to the address 000000 of memory.
float *fifth = NULL;
// print the addresses of the first
five elements
for(i=0;i<5;i++)
printf("p[%d]
= %.2f at %p\n", i, p[i], &p[i]);
// assign and return the fifth
element's address
fifth = &p[4];
return fifth;
}

|
| |
|
-
Answer
the following questions.
-
Is an array a
pointer constant or a
pointer variable?
-
If
p
is a pointer and
x[ ]
is an array, can we print
p[2]?
-
If
p
is a pointer and
x[ ]
is an array, can we print
x + 2?
-
What did we assume the storage units
(number of bytes) for characters, integers and floats to be?
|
-
An
array is a pointer constant.
-
No,
we can't.
-
Yes,
we can.
-
Depending
on the platform or machine, character is 1 byte, integer and float
are 4 bytes each.
|