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
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