0% found this document useful (0 votes)
15 views17 pages

Session 6 - Handout

Arrays and pointers

Uploaded by

teforijkaard
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views17 pages

Session 6 - Handout

Arrays and pointers

Uploaded by

teforijkaard
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Universität Duisburg-Essen

PRACTICAL TRAINING TO THE LECTURE

Procedural Programming

Session Six: Addressing - From Direct and Indirect


Addressing to Pointers

Name: Matriculation-Number:

First Name: Group-Number:

Tutor: Date:

Prof. Dr. rer. nat. Elsa Kirchner


Dipl.-Ing. Joachim Zumbrägel
Universität Duisburg-Essen
Faculty of Engineering, Department Electrical Engineering and Information Technology
Medical Technology Systems

Procedural Programming/Lab6 1
Pointers
In C, pointers are used to point to another variable or a constant. Obviously, the pointer doesn’t
point like you would with a finger but rather a pointer’s value holds the address of the variable or
the constant to which it is used to point.

In fact, you might have done something similar in real life, like for example if you may have been
asked where a particular person lives and the house that they lived in might not have been close
enough to be pointed out physically at, so instead you may have provided them with an address for
the house by which it could be located. This is how pointers work also.

Uses of the Pointer variables


Some reasons for using the pointers are

1. To return more than one value from a function.

2. To pass an array and function more conveniently from one function to another.

3. To manipulate the arrays more easily by moving the pointers to them.

4. To create a more complex data structure, such as the linked lists and the binary trees.

Pointer Operators in C
Basically, there are two pointer operators used in C, known as:

 & ─ The address of operator

 * ─ The dereferencing operator

Don't confuse the * operator for multiplication. C language doesn’t confuse this operator with the
multiplication sign when you use it as a dereferencing pointer in your program

The & operator always gives the memory address of whatever variable it precedes. The * operator,
when used with pointers, either declares a pointer or dereferences the pointer's value. The next
section explains each of these operators.

Procedural Programming/Lab6 2
Declaring a pointer
Pointers are declared in the same way as the simple variables are declared, but the name of the
variable pointer must be followed by the star or the asterisk sign:

int* a;

The above statement declares an integer pointer variable a, and the using the asterisk sign means it
is being used to assign a variable as a pointer. This asterisk is also known as the indirection operator.
Instead of following the data type, a pointer variable can also be declared with an asterisk preceding
the variable name:

int *a;

Assigning a Pointer the Address of a Variable or Constant


The following program shows that the value of a pointer is same as the address to which it points. It
also shows how to use the address of operator & to assign the address of a variable to a pointer.

Example:

/* example: using pointers */

#include<stdio.h>

int main()
{
int a = 2;
int *b;
b = &a;

//print address in hex form with capital letters (example 0060FEF8)


printf("Address of variable a is %p \n", b);

//prints address in hex form with 8 digits (example 0x0060fef8)


printf("Address of variable a is %#.8x \n", b);

//prints value of the address where b refers to


printf("Value of variable a is %d \n", *b);
return 0;
}

Exercise 6.1: Declare a pointer to a float variable

Procedural Programming/Lab6 3
Exercise 6.2: Declare a pointer to a long integer variable.

Exercise 6.3: Declare a pointer to an unsigned integer variable x and initialize the pointer to the
address of x.

Exercise 6.4: Declare two integer variables x and y and two integer pointer variables i and j. Assign
4 to x, and 8 to y, i to the address of the x variable, and j to the address of y variable, then print
the following:

a. The address of x and the value of x


b. The value of i and the value of *i
c. The address of y and the value of y
d. The value of j and the value of *j
e. The address of i
f. The address of j

Procedural Programming/Lab6 4
Exercise 6.5: Assuming the following declarations

int w = 6,
x = 2,
y,
z;

int* w_ptr = &w;


int* x_ptr = &x;
int* y_ptr = &y;
int* z_ptr = &z;

State whether the following assignment is legal or not:

*x_ptr = &x;

Procedural Programming/Lab6 5
Dereferencing or Reusing a Pointer
Because the main use of a pointer is to access and if required to change the value of a variable that
the pointer is pointing to, so we can also reuse a pointer variable to point to different variables and
make changes as required.

Example:

The following program shows that the value of the integer variable ‘a’ is changed twice.

/* example: reusing pointers*/

#include <stdio.h>

int main()
{

int a = 5;
int *b = &a;

printf("The value of a is %d \n", a);

a = 10;

printf("The value of a after a = 10 is %d \n", a);

*b = 15;

printf("The value of a after *b = 15 is %d \n", a);

return 0;

Procedural Programming/Lab6 6
Exercise 6.6: Declare three integer variables x, y, z and three integer pointer variables i, j, k. Assign
three different values to x, y, z. Set i, j, k to the addresses of x, y, z correspondingly.

a. Print the values of integer variables x, y, z, and the integer pointer variables i, j, k with labels.
b. Print the message: substituting values.
c. Run the substitution code: z = x; x = y; y = z;
d. Print the values of x, y, z, i, j, k, *i, *j, *k with labels.

Procedural Programming/Lab6 7
Pointer and Arrays
In C, pointer and arrays have a very close relation. This results to the fact that In C arrays and
pointers can be treated in the same way. In order to understand that, we should go one step back
and have a look at the memory organization of arrays. It was already mentioned that an array
occupies a contiguous block of memory in order to store the different elements. So if we define an
integer array named “int_arr”(on a machine which reserves 4 byte for an integer) with five
elements, the compiler will reserve altogether 20 bytes of memory for that array. Additionally we
want to initialize the array with 5 values. In order to do that in C, we have to use the following
definition:

integer int_arr[5] = {10,20,30,40,50};

We know already that we can access the different elements by use of the subscript (index) of that
array. In order to get access to the different values we would use int_arr[i] with i in the range of 0-4.

But we have another possibility to get access to the different elements. In C , the name (with no
subscript) of an array is a pointer to the first element of that array. That means for our example that
int_arr points to the address where the value of int_arr[0] is stored. So int_arr can be
seen as a pointer to an address where an integer value is stored. For that reason we can now define
a pointer variable to which we assign the address of the first array element:

integer *pt_int; //definition of an “integer” pointer


pt_int = int_arr; //assignment is equal to pt_int = &int_arr[0]

The logical consequence is that we can access the first element of the array in three different ways.

1. int_arr[0]

2. *int_arr

3. *pt_int

The next step is that we should be able to get access to the other array elements by use of the
pointer. This is possible because it is allowed to add an integer value to a pointer. The simplest thing
we can do is to increase a pointer by the value of one. But what does it mean regarding the address
where the pointer points to after the increment? Right now the pointer refers the address where the
first array element is stored,because of:

pt_int = int_arr;

If we increase now the pointer pt_int by one, it refers than to the address of the next element of
our array what means to the address of int_arr[1]. If we now think about the fact, that the
array occupies a contiguous memory block it is clear what happened. The pointer refers at the
beginning to the beginning of a memory block where 5 integer values are stored. An increment by
one let the pointer refer to the next address of that memory, what means it refers to the address
where the value “20” is stored.

Procedural Programming/Lab6 8
The following list shows that relation for the complete array:

(pt_int) points to int_arr[0];


(pt_int + 1) points to int_arr[1];
(pt_int + 2) points to int_arr[2];
(pt_int + 3) points to int_arr[3];
(pt_int + 4) points to int_arr[4];

So if we want to get access to third element of our array we can do that in the following ways:

1. int_arr[2]

2. *(int_arr + 2) //The array is treated like a pointer

3. *(pt_int + 2)

Example:

The following program declares an integer array and an integer pointer that points to the start of the
array. The array and pointer values are printed using subscript notation. Later on, the program uses
the array notation to print the array and the pointer values.

/* example: References arrays like pointers and pointers like arrays */

#include <stdio.h>

int main()
{
int ctr;
int iarray[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *iptr;

iptr = iarray; // Make iptr point to array's first element.


// This would also work: iptr = &iarray[0];
printf("Using the array subscripts:\n");
printf("iarray\tiptr\n");
for (ctr = 0; ctr < 10; ctr++)
{
printf("%d\t%d \n", iarray[ctr], iptr[ctr]);
}

printf("\nUsing the pointer notation:\n");


printf("iarray\tiptr\n");
for (ctr = 0; ctr < 10; ctr++)
{
printf("%d\t%d \n", *(iarray+ctr), *(iptr+ctr));
}

return 0;
}

Procedural Programming/Lab6 9
Pointer Arithmetic
In C, you are allowed to add an integer to a pointer. Some arithmetic operators which can be used
with pointers are:

 Increment and decrement operators ++, --

 Integers can be added or subtracted from pointers using +, -, +=, and -=

 A pointer can be subtracted from another pointer by using the subtraction operator –

Example:

/* example: using pointer arithmetic */

#include<stdio.h>

int main()
{

//Assuming the following variable definitions


int a[]={3,8,11,12,15};
int *b = a;

//Use of ++ and --
b++; // points at 8
b--; // now points at 3

//Use of + to add an int to a pointer:


printf("%d", *(b + 2)); //This statement will print 11

//Use of +=:
b = a; // points at 3
b += 2; // points at 11

//Pointer subtraction:
b += 2; // points at 11
printf("%d", b–a); //this will print 4

return 0;

Procedural Programming/Lab6 10
Exercise 6.7: Assuming the following declarations:

int array[] = {1, 2, 3, 4, 5, 6};


int* array_pntr = array;

State the value of the following expressions:

i) array_pntr[4]

ii) *array_pntr + 4

Using Pointers to Pass Arguments by Reference


Continuing from session of functions, we can say that it’s fine to pass arguments by value when you
don’t want to change the value of arguments in the called function. But when the main intention of
a function is to modify the value of the arguments passed to it, like for example you want to modify
values of an array passed to a function. This is where it’s useful to pass arguments by reference and
this is done by using pointers.

Passing by reference means that the function parameters are declared as references rather than the
normal variables.

To pass a variable by reference, the data type in the argument, both in the function declaration and
function definition, is realized as a pointer definition.

Procedural Programming/Lab6 11
Example:

The following program illustrates passing arguments by value:

/* example: pass by reference */

#include <stdio.h>

void triple(int *);

int main()
{
int num;

printf("Enter number:\n");
scanf("%d", &num);
triple(&num);
printf("The entered number tripled in main function is: %d \n", num);
return 0;
}

void triple(int* x)
{
printf("The number to be tripled is %d\n", *x);
*x = *x * 3; //other but equivalent expression: *x *=3;
printf("The number tripled in triple function is %d \n", *x);
}

Exercise 6.8: Please trace the above program example and write down the results below.

Procedural Programming/Lab6 12
Arrays of Pointers
If you want to reserve more than one pointer for different values, you might want to consider
declaring an array of pointers.

From the previous sessions, you already know that you can have an array of characters, integers, etc.
The same way, you also can have an array of pointers, with each pointer being a pointer to a
particular type of data.

Examples:

The following statement declares an array of 5 integer pointer variables:

int *iptr[5]; // Declares an array of 5 integer pointers

Similarly, the following statement reserves an array of 10 character pointer variables:

char *cpoint[10]; // Array of 10 character pointers

Each element of the array holds an address which points to other values in memory. The handling of
an pointer array works in the same way like for “normal” arrays.

For example, if you want to assign to the element iptr[2] the address of an integer variable
named age: you have to write:

iptr[2] = &age; // the iptr[2] now points to the address of age

Procedural Programming/Lab6 13
Structures
In C, one of the most vital steps to designing your program is choosing how to represent your data in
a good way. There are cases where declaring variables or an array is not enough. In such situations, C
allows you to use structures.

So you might ask, what are structures anyway? Well, a structure can be defined as a set of variables
of different types collected under a single name. They are used to handle that data in a better way.
For example, if you want to store some information about a person like his name, id number, age,
etc, you can collect this information under a single structure like a record instead of storing it in
different places.

Defining Structures

Structures are defined using the keyword struct, followed by the structure name and containing a
list of declarations of the structure's members with their data types, enclosed in braces:

struct [structure_name]
{
data_type member_declaration_list;
};

A structure should consist of at least one member.

Example:

struct Date
{
short year, month, day;
};

The above example defines a structure named Date, which has three members all of type short.

Example:

struct employee
{
char name[20];
int id_num;
float salary;
};

The above example defines a structure named employee, having three members of different data
types.

Procedural Programming/Lab6 14
Example:

/* example: using structures */

#include <stdio.h>

#define MAXTITLE 41 // defining maximum length of title


#define MAXAUTHOR 31 // defining maximum length of the author's name

struct book
{
char title[MAXTITLE];
char author[MAXAUTHOR];
float price;
};

int main()
{

struct book catalog; // declaring catalog as a book variable

printf("Please enter the book title: ");


gets(catalog.title);

printf("Now enter the author name: ");


gets(catalog.author);

printf("Now enter the price of the book in Euros: ");


scanf("%f", &catalog.price);

printf("%s by %s is %.2f Euros\n", catalog.title, catalog.author,


catalog.price);

return 0;
}

Explanation:

In the above program example, the structure created has three members: one to store the title of a
book of type char, one to store the author name also of type char, and one to store the price of type
float. In order to access a member of the structure, we need to define another variable in our
main() function as catalog and make that as a variable of structure book. Like in the program:

struct book catalog;

It declares index to be a structure variable using the book structure design.

Here we use the gets() function instead of using the scanf() for inputting strings.

Procedural Programming/Lab6 15
The gets() function reads characters from the standard input and stores them as a C string till it
reaches a newline character or the end of file.

Note: Strings and files will be covered in detail in a later on session.

Any member of a structure can be accessed by using the dot(.)operator:

structure_variable_name.member_name

So for example, when we want to access the title variable of the structure, then we can do this by

catalog.title

Arrays of Structures

Now what if we want to use our program to store more data? For this you can use an array of
structures, as shown in the next example.

Example:

/* account records */

#include <stdio.h>

#define MAXFIRSTNAME 41 // maximum number of characters for first name


#define MAXLASTNAME 41 // maximum number of characters for last name
#define MAXRECORDS 100 // maximum number of records allowed

struct account
{ // set up the account template
char firstname[MAXFIRSTNAME];
char lastname[MAXLASTNAME];
float balance;
};

Procedural Programming/Lab6 16
int main()
{
// defines an array of account structures
struct account book[MAXRECORDS];

int count = 0;
int index;

printf("Please enter the first name: ");

while (count < MAXRECORDS && gets(book[count].firstname) != NULL


&& book[count].firstname[0] != '\0' )
{
printf("Now enter the last name: ");
gets(book[count].lastname);

printf("Now enter the Balance in Euros: ");


scanf("%f", & book[count++].balance);

while (getchar() != '\n')


continue;

if (count < MAXRECORDS)


printf("Enter the next first name: ");
}

if (count > 0)
{
printf("\nHere is the list of your Clients:\n");

for (index = 0; index < count; index++)


{
printf("%s %s has %.2f Euros in their Account\n",
book[index].firstname,
book[index].lastname,
book[index].balance);
}
}
else
printf("No Records!\n");

return 0;
}

Procedural Programming/Lab6 17

You might also like