26.09.2023 Views

The C Programming Language - Pointers

This is a free tutorial about pointers from the book "The C Programming Language" by Heimo Gaicher

This is a free tutorial about pointers from the book "The C Programming Language" by Heimo Gaicher

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong><br />

Heimo Gaicher, born in 1969, has been a passionate tinkerer,<br />

electronics enthusiast, and programmer since a young age.<br />

While working, he completed the industrial electronics<br />

master's school and later the Higher Technical Federal Institute<br />

of Electronics and Technical Informatics (BULME) in Graz. He<br />

has worked extensively in hardware and software<br />

development for LED lighting, testing environments, all-wheeldrive<br />

systems, laboratory measuring devices, and sensor<br />

technology.<br />

Preface<br />

This book is aimed at programming beginners who want to learn the universal<br />

programming language C. Since learning a programming language is not easy for<br />

beginners, this book has been created step-by-step with many examples. A general<br />

and lengthy introduction has been deliberately avoided, as the relevant examples are<br />

precisely documented in the programming code, leading to a better understanding.<br />

<strong>The</strong> book is not a comprehensive reference, but a step-by-step guide for the learner.<br />

Work through the book carefully from the beginning and try to solve the program<br />

examples independently or expand them according to your own ideas and needs. After<br />

all, the best way to learn a programming language is by programming.<br />

This book has been written with great care. If there are still errors, I welcome<br />

corresponding feedback. Comments and critiques are always welcome at<br />

c4programmers@gmail.com.<br />

Have fun experimenting!<br />

© 2023 Heimo Gaicher


Disclaimer:<br />

This book is intended to serve as a guide for learning C programming, and while every<br />

effort has been made to ensure the accuracy and completeness of the information<br />

presented herein, the author and publisher make no warranties, expressed or implied,<br />

as to the contents of this book.<br />

<strong>The</strong> examples and code snippets provided in this book are for educational purposes<br />

only and should not be used in any production environment without thorough testing<br />

and review. <strong>The</strong> author and publisher are not responsible for any errors, omissions, or<br />

damages that may arise from the use of the information presented in this book.<br />

Furthermore, it is important to note that programming is a constantly evolving field<br />

and new techniques, tools, and best practices may emerge after the publication of this<br />

book. Readers are encouraged to stay up to date with the latest developments in C<br />

programming by consulting other resources and online communities.<br />

Finally, this book is not intended as a substitute for formal education or professional<br />

training in computer programming. Readers should use this book as a supplement to<br />

their own learning and seek out additional resources as necessary.<br />

<strong>The</strong> trade names, common names, product designations, etc. reproduced in this work<br />

may also be trademarks without special identification and, as such, are subject to<br />

statutory provisions.<br />

This work is protected by copyright. All rights, including those of translation, reprinting,<br />

and reproduction of the book or parts thereof, are reserved. No part of the work may<br />

be reproduced, processed, duplicated, or distributed in any form (photocopy,<br />

microfilm, or any other method) without written permission from the publisher,<br />

including for the purposes of educational design.<br />

Bibliographic information of the German National Library:<br />

<strong>The</strong> German National Library records this publication in the German National<br />

Bibliography; detailed bibliographic data can be accessed via http://dnb.d-nb.de on<br />

the internet.<br />

© 2023 Heimo Gaicher


Contents<br />

Introduction ____________________________________________________ 5<br />

Representation of Code, Variable- and Function Names _________________ 5<br />

1 <strong>Pointers</strong> ____________________________________________________ 6<br />

1.1 Definition of a Pointer _________________________________________ 7<br />

1.2 Examples with <strong>Pointers</strong> ________________________________________ 7<br />

1.3 Address Assignment of <strong>Pointers</strong> ________________________________ 11<br />

1.3.1 Direct Address Assignment __________________________________________ 12<br />

1.4 Pointer of <strong>Pointers</strong> ___________________________________________ 14<br />

1.5 Pointer Arithmetic ___________________________________________ 15<br />

1.6 Pointer to Arrays ____________________________________________ 16<br />

1.7 Array of <strong>Pointers</strong> ____________________________________________ 17<br />

1.8 <strong>Programming</strong> Example Chessboard _____________________________ 18<br />

1.9 Passing <strong>Pointers</strong> to Functions __________________________________ 19<br />

1.10 Passing Arrays to Functions ____________________________________ 21<br />

1.11 Return a Pointer from Functions ________________________________ 22


Introduction<br />

Dear reader,<br />

this is a free version of the chapter “<strong>Pointers</strong>” and part of the book “<strong>The</strong> C<br />

<strong>Programming</strong> <strong>Language</strong>” ISBN Softcover: 978-3-347-96632-1 by Heimo Gaicher.<br />

Representation of Code, Variable- and Function Names<br />

In this book, variable and function names, such as myVariable or myFunction(), are<br />

displayed in italics. For function names, two additional brackets are added, like the<br />

function main() for example. Code examples and snippets are shown in a frame using<br />

the Consolas font.<br />

Example<br />

#include <br />

int counter = 100;<br />

void write(void) {<br />

printf(“Value of counter is %d\n”, counter);<br />

}<br />

Program outputs from the IDE's console are displayed with a black background.<br />

Please enter a number: 7<br />

You entered the number 7<br />

Important information or summaries are shown in a grey frame.<br />

This is important information!<br />

Header files from the C Standard Library, such as or , are shown in<br />

angle brackets


1 <strong>Pointers</strong><br />

<strong>Pointers</strong> are a very important tool in the C programming language. Basically, a pointer<br />

is nothing more than a variable that stores the memory address of another variable.<br />

So, pointers only store the address of a memory object of a certain data type.<br />

If you've worked with functions, you may have thought that it would be handy if you<br />

could return more than one value to the calling function.<br />

This is easily done with a pointer. In this case, you need to pass the address, that is, a<br />

pointer to a specific memory location, to the function. You can now use this address<br />

to write a desired value to the memory location specified in the function. You have<br />

now overwritten the variable at the corresponding memory location with a new value<br />

and can also use this variable outside the function.<br />

Another advantage of pointers is the saving of copying operations and the associated<br />

saving of computing time. Suppose you have a function to which you pass ten integer<br />

values. With a 16-bit system, you have to pass 10 x 2 bytes here. But if you use a pointer<br />

here, you only pass a pointer to the beginning of an array of these ten integer values.<br />

And for this pointer you need only 2 bytes of memory.<br />

Also, memory areas can be dynamically manipulated with pointers. You can pass data<br />

objects by reference to functions, and you can use pointers to implement complex data<br />

structures like lists.<br />

So, pointers contain a memory address of a certain expected data type, e.g. char, int,<br />

float, etc. A pointer points directly to a specific address in memory. <strong>Pointers</strong> are<br />

dereferenced with the * operator. <strong>The</strong> & operator returns the address of an element<br />

to which the & operator is applied.<br />

Let's first look at how a variable is stored in memory:<br />

int a = 2;<br />

Here the variable a of data type integer has been initialized with the value 2. In this<br />

example, this variable was stored in RAM, e.g., at address 0x015A.<br />

Name Address Value<br />

a 0x015A 2<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 6


1.1 Definition of a Pointer<br />

A pointer is created like a normal variable. <strong>The</strong> only difference is that you prefix the<br />

pointer name with a * (asterisk).<br />

int *ptr;<br />

char *p;<br />

char *p, a;<br />

// An int pointer. A pointer named ptr pointing to an int.<br />

// A char pointer. A pointer named p which points to a char<br />

// A char pointer named p and a char variable named a<br />

As mentioned before, a pointer contains an address, and we have already worked with<br />

addresses, for example with the scanf() function.<br />

scanf(%d“, &var);<br />

Here, the value entered by the user is stored at the address of var.<br />

1.2 Examples with <strong>Pointers</strong><br />

In the following example, an int variable var is initialized with the value 1234567. <strong>The</strong><br />

compiler allocates a place in RAM for the variable var during the compilation process.<br />

For example, on my system, an int value occupies 4 bytes of memory.<br />

/* example 125 – pointers */<br />

#include <br />

int main()<br />

{<br />

int var = 1234567;<br />

printf("<strong>The</strong> dec. value of var = %d\n", var);<br />

printf("<strong>The</strong> hex value of var = %x\n", var);<br />

/* using format element %p for pointer and & as address operator */<br />

printf("<strong>The</strong> address of var = %p", &var);<br />

}<br />

return 0;<br />

<strong>The</strong> dec. value of var = 123456<br />

<strong>The</strong> hex value of var = 12d687<br />

<strong>The</strong> address of var = 0061ff1c<br />

You can easily check this by setting a breakpoint in the IDE before the last line of code<br />

and starting the debugger. Open the debugging window "Memory dump" under Debug<br />

/ Debugging windows and enter the variable name with an address operator in the<br />

address window, in this case &var, and click the Go button.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 7


<strong>The</strong> address of var is now displayed on the far left. <strong>The</strong> content of var is represented<br />

as a hexadecimal value in the first 4 bytes, with the first byte on the right at position<br />

1. <strong>The</strong> decimal number 1234567 corresponds to the hexadecimal number 0x0012d687,<br />

which is stored at address 0x61ff1c in this example.<br />

In the next example, we declare a pointer variable of type int named ptr and assign it<br />

the address var. In the next line of code, we use the dereference operator * to access<br />

the variable pointed to by ptr, and store its contents in x. We then output the<br />

corresponding values.<br />

/* example 126 – pointers */<br />

#include <br />

int main()<br />

{<br />

int var = 1234567, x;<br />

int *ptr; // ptr is an int pointer<br />

ptr = &var;<br />

x = *ptr;<br />

// ptr = address of var<br />

// x = value of element pointed to by ptr<br />

printf("<strong>The</strong> value of x = %d\n", x); // x holds the value of var<br />

printf("<strong>The</strong> address of var = %p\n", ptr);<br />

printf("<strong>The</strong> address of x = %p\n", &x);<br />

printf("<strong>The</strong> address of ptr = %p", &ptr);<br />

}<br />

return 0;<br />

<strong>The</strong> value of x = 1234567<br />

<strong>The</strong> address of var = 0061ff1c<br />

<strong>The</strong> address of x = 0061ff18<br />

<strong>The</strong> address of ptr = 0061ff14<br />

<strong>The</strong> pointer variable ptr itself must of course also have a place in memory and was<br />

created here at address 0x0061ff14.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 8


In memory, the assignment looks like this:<br />

<strong>The</strong> pointer ptr stored the address of var. We say that the pointer ptr points to var.<br />

Using the dereference operator *, we indirectly access the value of the variable it<br />

points to via the pointer.<br />

We can declare pointers in several ways, such as:<br />

int *ptr;<br />

int* ptr;<br />

int * ptr;<br />

Where you put the * is up to you, but usually the operator is put right before the<br />

variable name.<br />

In the next example, the pointer ptr first gets the address of var and then gets the<br />

address of x. Thus we access the contents of var first and then the contents of x.<br />

/* example 127 – pointers */<br />

#include <br />

int main()<br />

{<br />

int *ptr, var = 10, x = 20;<br />

ptr = &var; // ptr = address of var<br />

printf("Pointer points to %p and the value is %d\n", ptr, *ptr);<br />

ptr = &x; // ptr = address of x<br />

printf("Pointer points to %p and the value is %d\n", ptr, *ptr);<br />

}<br />

return 0;<br />

Pointer points to 0061ff18 and the value is 10<br />

Pointer points to 0061ff14 and the value is 20<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 9


<strong>Pointers</strong>, or rather pointer variables, are also stored under an address in memory.<br />

Depending on the system, pointer variables are at least large enough to store an<br />

address, in this case 4 bytes.<br />

In the following example we access two variables a and b with a char pointer ptr_a<br />

and an int pointer ptr_b and output the addresses and their contents.<br />

/* example 128 – pointers */<br />

#include <br />

int main(void)<br />

{<br />

char a='A', *ptr_a = &a;<br />

int b=1000, *ptr_b = &b;<br />

printf("a = %c = dec %d\n",a,a);<br />

printf("b = %d\n",b);<br />

printf("Address of a = %p\n",ptr_a);<br />

printf("Value of a = %c = %d\n",*ptr_a, *ptr_a);<br />

printf("Address of b = %p\n",ptr_b);<br />

printf("Value of b = %d\n",*ptr_b);<br />

printf("Address of ptr_a = %p\n",&ptr_a);<br />

printf("Address of ptr_b = %p\n",&ptr_b);<br />

printf("Size of ptr_a = %d\n",sizeof(ptr_a));<br />

printf("Size of ptr_b = %d\n",sizeof(ptr_b));<br />

}<br />

return 0;<br />

a = A = dec 65<br />

b = 1000<br />

Address of a = 0060FEFF<br />

Value of a = A = 65<br />

Address of b = 0060FEF4<br />

Value of b = 1000<br />

Address of ptr_a = 0060FEF8<br />

Address of ptr_b = 0060FEF0<br />

Size of ptr_a = 4<br />

Size of ptr_b = 4<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 10


<strong>The</strong> following figure shows the addressing in the memory area:<br />

1.3 Address Assignment of <strong>Pointers</strong><br />

Where does a pointer point to after it has been declared but not yet used?<br />

int *ptr;<br />

// undefined pointer<br />

<strong>The</strong> pointer points to an undefined memory location! An undefined pointer can be<br />

dangerous because it is not known to which address it points! For this reason pointers<br />

should always be initialized. This means that you have to assign a value, i.e. a memory<br />

address, to the pointer.<br />

int *ptr = &var;<br />

// defined pointer<br />

This is a defined pointer. <strong>The</strong> pointer ptr has been initialized with the address of var.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 11


To prevent a pointer from pointing to an unknown, undefined memory address, it<br />

should be assigned an address immediately, or if the address is not yet known, the<br />

value 0 or NULL. When a pointer is assigned the value 0 or NULL, it is called a null<br />

pointer. This prevents a valid memory address from being determined by chance when<br />

the pointer is used, thus causing errors that are difficult to find.<br />

int *ptr1 = NULL;<br />

int *ptr2 = 0;<br />

// NULL pointer<br />

// NULL pointer<br />

To keep track when dealing with pointers, you should always use a meaningful name<br />

for a pointer.<br />

int *ptr_var = &var;<br />

As in this example, _var has been appended to the name of the pointer to make it clear<br />

that this pointer points to the address of var. You can also assign an address to a<br />

pointer after it has been declared.<br />

int *ptr_var; // undefined pointer<br />

…<br />

ptr_var = &var; // defined pointer - ptr_var points to var<br />

1.3.1 Direct Address Assignment<br />

A pointer can also be assigned a direct address in memory during initialization. <strong>The</strong><br />

following example shows a direct address assignment:<br />

/* example 129 – pointers */<br />

#include <br />

int main()<br />

{<br />

int *ptr = (int *)0x0061ff14; // typecast to an int* - ptr points to 0x0061ff14<br />

printf("ptr points to: %p\n", ptr);<br />

}<br />

return 0;<br />

ptr points to: 0061ff14<br />

To assign a desired address to a pointer, a number (the desired address) must first be<br />

typed into a pointer, in this case an int pointer. This tells the compiler that it is a pointer<br />

to the constant address 0x0061ff14.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 12


In the following program, the contents of two variables are swapped using pointers:<br />

/* example 130 – pointers */<br />

#include <br />

int main(void)<br />

{<br />

int a = 2, b = 4, temp;<br />

int *ptr_a = &a, *ptr_b = &b;<br />

printf("a = %d, b = %d\n", a, b);<br />

temp = *ptr_a; // temp gets the value pointed to by *ptr_a. temp = value of a<br />

*ptr_a = *ptr_b; // <strong>The</strong> value pointed to by *ptr_a is overwritten with the value<br />

// pointed to by *ptr_b, a now gets the value of b<br />

*ptr_b = temp; // <strong>The</strong> value pointed to by *ptr_b is overwritten with the value<br />

// of temp and that is the value of a<br />

printf("a = %d, b = %d\n", a, b);<br />

}<br />

return 0;<br />

a = 2, b = 4<br />

a = 4, b = 2<br />

In the next example, the values are added with a float pointer:<br />

/* example 131 – pointers */<br />

#include <br />

int main(void)<br />

{<br />

float a=0, b=0, *ptr_a=NULL;<br />

ptr_a = &a;<br />

*ptr_a = 12;<br />

// Pointer ptr_a stores the address of a<br />

// Writes 12 in a<br />

printf("a = %.2f\n",a);<br />

*ptr_a += 5.5; // Adds 5.5 to the existing value of a<br />

printf("a = %.2f\n",a);<br />

b = *ptr_a + 5; // Adds 5 to the existing value of a and stores the result in b<br />

}<br />

printf("b = %.2f\n",b);<br />

a = 12.00<br />

a = 17.50<br />

b = 22.50<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 13


As you can see, working with pointers can be a bit confusing. <strong>The</strong>refore, here is a brief<br />

summary of how pointers are used:<br />

char ch = 'A';<br />

int a = 0, y = 10;<br />

float z = 0.0, x = 3.14;<br />

int *iptr1 = (int *)0x0061ff14; // typecast to an int* - iptr1 points to 0x0061ff14<br />

int *iptr_a;<br />

// undefined int pointer<br />

int *iptr_y = NULL;<br />

// int pointer initialized to NULL<br />

float *fptr_x;<br />

// undefined float pointer<br />

fptr_x = &x;<br />

char cptr_ch = &ch;<br />

// defined float pointer - fptr_x points to x<br />

// defined float pointer - fptr_x points to x<br />

iptr_y = &y;<br />

// iptr_y stores the address of y<br />

*iptr_y = 1000; // iptr_y points to y -> now y = 1000;<br />

a = *iptr_y; // a stores the value pointed to by iptr_y -> a = 1000<br />

*iptr_y = a + 500; // y = 1000 + 500 -> now y = 1500<br />

iptr_a = &a;<br />

// iptr_a stores the address of a<br />

printf("%d\n" , *iptr_a);<br />

printf("%p\n" , iptr_a);<br />

// displays the value a<br />

// displays the Address of a<br />

1.4 Pointer of <strong>Pointers</strong><br />

A pointer to a pointer contains the address of a pointer to which it points. A simple<br />

pointer contains the address of a variable. However, when a pointer points to another<br />

pointer, the first pointer contains the address of the second pointer, which in turn<br />

points to the variable that contains a value.<br />

In the following figure, the pointer pptr points to another pointer ptr, which in turn<br />

points to the variable b. With double dereferencing, you can use the pointer ptr to<br />

access the variable b directly.<br />

Figure 1: Pointer to pointer<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 14


A pointer-to-pointer variable must also be declared as such with **. Here is an<br />

example:<br />

/* example 132 – pointer to pointer */<br />

#include <br />

int main(void)<br />

{<br />

int b = 1000;<br />

int *ptr, **pptr;<br />

ptr = &b;<br />

pptr = &ptr;<br />

// ptr takes the address of b<br />

// pptr takes the address of ptr<br />

printf("Value of b = %d\n",b);<br />

printf("Value of b via *ptr = %d\n",*ptr);<br />

printf("Value of b via **pptr = %d\n",**pptr);<br />

}<br />

return 0;<br />

Value of b = 1000<br />

Value of b via *ptr = 1000<br />

Value of b via **pptr = 1000<br />

1.5 Pointer Arithmetic<br />

You already know that a pointer stores an address, and this address is nothing but an<br />

integer numeric value. And of course you can also change this value by adding or<br />

subtracting a certain value. This means that the four operators +, -, ++ and -- are<br />

available for pointer arithmetic.<br />

Suppose we have an integer pointer iptr pointing to a variable ivar1 with address<br />

0x0060FF00. And suppose that an int value on the system to be used is 4 bytes in size.<br />

This means that the compiler has reserved a memory space of 4 bytes from address<br />

0x0060FF00 to address 0x0060FF03 for variable ivar1. For example, the memory for<br />

the second integer variable ivar2 starts at address 0x0060FF04.<br />

What would happen if we incremented the int pointer with iptr++? In this case, the<br />

pointer would point to address 0x0060FF04, and we could access the value of ivar2 via<br />

the pointer.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 15


1.6 Pointer to Arrays<br />

A pointer always increments or decrements by the number of bytes of the data type<br />

to which it points. For a char this would be one byte, for a double it would be 4 or 8<br />

bytes depending on the system.<br />

To illustrate this, in the following example we create an int array and store four values<br />

in it. Instead of the "usual" access to the elements of the array, we now use a pointer<br />

to access the first element in the array, and then increment the pointer three times in<br />

the for loop. This moves the pointer to the next position in the array.<br />

/* example 133 – pointer to arrays */<br />

#include <br />

int main (void)<br />

{<br />

int ivar[] = {2, 8, 5, 9};<br />

int *iptr;<br />

iptr = ivar; // ivar is an array, therefore we need no address operator &<br />

for (int i = 0; i < 4; i++) {<br />

printf("Address of ivar[%d] = %p\n", i, iptr );<br />

printf("Value of ivar[%d] = %d\n", i, *iptr );<br />

}<br />

iptr ++; // move to the next position<br />

}<br />

return 0;<br />

Address of ivar[0] = 0060FEE8<br />

Value of ivar[0] = 2<br />

Address of ivar[1] = 0060FEEC<br />

Value of ivar[1] = 8<br />

Address of ivar[2] = 0060FEF0<br />

Value of ivar[2] = 5<br />

Address of ivar[3] = 0060FEF4<br />

Value of ivar[3] = 9<br />

As you can see, the array ivar[] was stored at address 0x0060FEE8. This is also the<br />

address of the first element with the content 2. <strong>The</strong> value of the pointer was then<br />

increased by 4 bytes. So the next address in the array for the 2nd element is<br />

0x0060FEEC, whose content is the value 8. This allows access to the individual<br />

elements of an array. It is noticeable here that the & operator for an address<br />

assignment is missing. This is because according to the ANSI-C standard, an array name<br />

represents a pointer to the 1st element of the array. Another notation would be e.g.<br />

ptr_a = &a[0]; <strong>The</strong> address of the 1st element of array a is also passed to the pointer<br />

ptr_a with this command.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 16


1.7 Array of <strong>Pointers</strong><br />

If we want to store an array of pointers, we need to declare it as follows:<br />

int *ptr[4];<br />

// Pointer as an array of 4 int pointers<br />

Each element of the array contains a pointer of type int. Let's make an example:<br />

/* example 134 – array of pointers */<br />

#include <br />

int main (void)<br />

{<br />

int ivar[] = {2, 8, 5, 9};<br />

int *iptr[4];<br />

// declare an array of 4 pointers<br />

for (int i = 0; i < 4; i++) {<br />

iptr[i] = &ivar[i]; // assign the address of each array element<br />

}<br />

printf("Value of ivar[%d] = %d\n", i, *iptr[i]);<br />

}<br />

return 0;<br />

Value of ivar[0] = 2<br />

Value of ivar[1] = 8<br />

Value of ivar[2] = 5<br />

Value of ivar[3] = 9<br />

Let’s do the same with a char array!<br />

/* example 135 – array of pointers */<br />

#include <br />

int main (void)<br />

{<br />

char *cptr[] = {"Hi", "i am", "a pointer", "array"};<br />

for (int i = 0; i < 4; i++) {<br />

printf("Value of cptr[%d] = %s\n", i, cptr[i]);<br />

}<br />

}<br />

return 0;<br />

Value of cptr[0] = Hi<br />

Value of cptr[1] = i am<br />

Value of cptr[2] = a pointer<br />

Value of cptr[3] = array<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 17


1.8 <strong>Programming</strong> Example Chessboard<br />

A game is to be developed in which a piece can be moved on a chess board by keyboard<br />

input. A chessboard consists of 8x8 squares (8x8 matrix). <strong>The</strong> starting position of the<br />

piece is in the field [0][0] and the piece (the number 1) is to be moved with the keys w,<br />

a, s, d (w = up, a = left, s = down, d = right). If the edge of the playing field is crossed,<br />

the character positions itself on the opposite side. <strong>The</strong> program should end with x.<br />

1 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

moving [w = up, a = left, s = down, d = right] (exit with x):<br />

/* example 136 – chessboard */<br />

#include <br />

#include <br />

// Prototypes<br />

void fieldOutput(int *field);<br />

void move(int *field, int *posX, int *posY, char moving);<br />

int main(void)<br />

{<br />

int field[8][8] = { 0 }, posX=0, posY=0;<br />

char moving;<br />

field[posY][posX] = 1;<br />

// set game piece<br />

do {<br />

fieldOutput(&field[0][0]);<br />

printf("\nmoving [w = up, a = left, s = down, d = right] (exit with x): ");<br />

scanf("%c", &moving);<br />

move(&field[0][0], &posX, &posY, moving);<br />

fflush(stdin);<br />

system("Cls");<br />

}while(moving != 'x');<br />

// clear keyboard buffer<br />

// clear screen<br />

}<br />

return 0;<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 18


void fieldOutput(int *field) {<br />

printf("\n");<br />

int i, j;<br />

// output playing field<br />

for(i=0; i 7)<br />

*posY = 0;<br />

}<br />

*(field + *posY * 8 + *posX) = 1; // set new position<br />

1.9 Passing <strong>Pointers</strong> to Functions<br />

<strong>Pointers</strong> can also be passed as parameters to functions. We have already explained<br />

this point in detail in the chapter "Call by Reference". <strong>The</strong> address of a variable was<br />

passed to a function and addressed with pointers within the function. Here is another<br />

small example for the output of the Unix time.<br />

<strong>The</strong> Unix time is a system for describing a point in time. It is the number of seconds<br />

that have elapsed since January 1, 1970, 00:00:00 (UTC), minus leap seconds. In this<br />

calculation, each day has exactly 86400 seconds.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 19


For this we need the function time(), which is defined in the header file . This<br />

function returns the UTC time in seconds.<br />

Syntax:<br />

time_t time(time_t *second)<br />

/* example 137 - get UTC time in seconds */<br />

#include <br />

#include <br />

void getSecondsUTC(unsigned long *ptr_time) {<br />

// get the current number of secondsonds since 1970.01.01 00:00:00 UTC<br />

*ptr_time = time(NULL);<br />

}<br />

int main (void)<br />

{<br />

unsigned long seconds;<br />

getSecondsUTC(&seconds);<br />

// pass the address of seconds<br />

printf("Number of seconds since 1970.01.01: %ld\n", seconds);<br />

printf("Number of minutes since 1970.01.01: %ld\n", seconds/60);<br />

printf("Number of hours since 1970.01.01: %ld\n", seconds/3600);<br />

printf("Number of days since 1970.01.01: %ld\n", seconds/(3600*24));<br />

}<br />

return 0;<br />

Number of seconds since 1970.01.01: 1674053452<br />

Number of minutes since 1970.01.01: 27900890<br />

Number of hours since 1970.01.01: 465014<br />

Number of days since 1970.01.01: 19375<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 20


1.10 Passing Arrays to Functions<br />

Of course, we can also pass an array as a pointer to a function. In the next example,<br />

myArray[] is initialized with four int values and passed as the first parameter as a<br />

pointer to the getSum() function. <strong>The</strong> second parameter is the constant value 4, which<br />

passes the array size to the function.<br />

/* example 138 - pass an array to a function */<br />

#include <br />

int getSum(int *arr, int size) {<br />

int sum = 0;<br />

}<br />

for (int i = 0; i < size; i++) {<br />

sum += arr[i];<br />

}<br />

return sum;<br />

int main (void)<br />

{<br />

int myArray[] = {16, 12, 7, 21};<br />

int sumOfMyArray;<br />

sumOfMyArray = getSum(myArray, 4); // pass array as pointer + size<br />

printf("<strong>The</strong> sum of all elements is: %d\n", sumOfMyArray);<br />

}<br />

return 0;<br />

<strong>The</strong> sum of all elements is: 56<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 21


1.11 Return a Pointer from Functions<br />

You already know how to declare functions with return values. If the return value is a<br />

pointer, a * is appended to the return type as usual.<br />

int* func() {<br />

…<br />

}<br />

In the following example, the address of ivar is returned as the return value:<br />

/* example 139 - return a pointer from functions */<br />

#include <br />

int* myFunction(void) {<br />

static int ivar = 100; // declare here a static variable<br />

}<br />

return (&ivar); // return the address of ivar<br />

int main (void)<br />

{<br />

int *iptr;<br />

iptr = myFunction();<br />

// function call, iptr get the address of ivar<br />

printf("Address of ivar: %p\n", iptr);<br />

printf("Value of ivar: %d\n", *iptr);<br />

*iptr = 50; // change the value of ivar to 50<br />

printf("Value of ivar: %d\n", *iptr);<br />

}<br />

return 0;<br />

Address of ivar: 0040a004<br />

Value of ivar: 100<br />

Value of ivar: 50<br />

It is important that the variable within the function is defined as a static variable,<br />

otherwise it will be destroyed when the function is exited and access to this address is<br />

no longer possible.<br />

<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 22


<strong>The</strong> C <strong>Programming</strong> <strong>Language</strong> by Heimo Gaicher – Chapter <strong>Pointers</strong> 23

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!