Categories
Conflict-Resolution

How to create pointers in c

Pointers in C are easy and fun to learn. Some C programming tasks are performed more easily with pointers, and other tasks, such as dynamic memory allocation, cannot be performed without using pointers. So it becomes necessary to learn pointers to become a perfect C programmer. Let’s start learning them in simple and easy steps.

As you know, every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator, which denotes an address in memory. Consider the following example, which prints the address of the variables defined −

When the above code is compiled and executed, it produces the following result −

What are Pointers?

A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable address. The general form of a pointer variable declaration is −

Here, type is the pointer’s base type; it must be a valid C data type and var-name is the name of the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for multiplication. However, in this statement the asterisk is being used to designate a variable as a pointer. Take a look at some of the valid pointer declarations −

The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

How to Use Pointers?

There are a few important operations, which we will do with the help of pointers very frequently. (a) We define a pointer variable, (b) assign the address of a variable to a pointer and (c) finally access the value at the address available in the pointer variable. This is done by using unary operator * that returns the value of the variable located at the address specified by its operand. The following example makes use of these operations −

When the above code is compiled and executed, it produces the following result −

NULL Pointers

It is always a good practice to assign a NULL value to a pointer variable in case you do not have an exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer.

The NULL pointer is a constant with a value of zero defined in several standard libraries. Consider the following program −

When the above code is compiled and executed, it produces the following result −

In most of the operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system. However, the memory address 0 has special significance; it signals that the pointer is not intended to point to an accessible memory location. But by convention, if a pointer contains the null (zero) value, it is assumed to point to nothing.

To check for a null pointer, you can use an ‘if’ statement as follows −

Pointers in Detail

Pointers have many but easy concepts and they are very important to C programming. The following important pointer concepts should be clear to any C programmer −

There are four arithmetic operators that can be used in pointers: ++, –, +, –

You can define arrays to hold a number of pointers.

C allows you to have pointer on a pointer and so on.

Passing an argument by reference or by address enable the passed argument to be changed in the calling function by the called function.

C allows a function to return a pointer to the local variable, static variable, and dynamically allocated memory as well.

Creating Pointers

You learned from the previous chapter, that we can get the memory address of a variable with the reference operator & :

Example

int myAge = 43; // an int variable

printf(“%d”, myAge); // Outputs the value of myAge (43)
printf(“%p”, &myAge); // Outputs the memory address of myAge (0x7ffe5367e044)

In the example above, &myAge is also known as a pointer.

A pointer is a variable that stores the memory address of another variable as its value.

A pointer variable points to a data type (like int ) of the same type, and is created with the * operator. The address of the variable you’re working with is assigned to the pointer:

Example

int myAge = 43; // An int variable
int* ptr = &myAge; // A pointer variable, with the name ptr, that stores the address of myAge

// Output the value of myAge (43)
printf(“%d\n”, myAge);

// Output the memory address of myAge (0x7ffe5367e044)
printf(“%p\n”, &myAge);

// Output the memory address of myAge with the pointer (0x7ffe5367e044)
printf(“%p\n”, ptr);

Example explained

Create a pointer variable with the name ptr , that points to an int variable ( myAge ). Note that the type of the pointer has to match the type of the variable you’re working with.

Use the & operator to store the memory address of the myAge variable, and assign it to the pointer.

Now, ptr holds the value of myAge ‘s memory address.

Dereference

In the example above, we used the pointer variable to get the memory address of a variable (used together with the & reference operator).

However, you can also get the value of the variable the pointer points to, by using the * operator (the dereference operator):

Example

int myAge = 43; // Variable declaration
int* ptr = &myAge; // Pointer declaration

// Reference: Output the memory address of myAge with the pointer (0x7ffe5367e044)
printf(“%p\n”, ptr);

// Dereference: Output the value of myAge with the pointer (43)
printf(“%d\n”, *ptr);

Note that the * sign can be confusing here, as it does two different things in our code:

  • When used in declaration ( int* ptr ), it creates a pointer variable.
  • When not used in declaration, it act as a dereference operator.

Why Should I Learn About Pointers? Pointers are important in C, because they give you the ability to manipulate the data in the computer’s memory – this can reduce the code and improve the performance.

Pointers are one of the things that make C stand out from other programming languages, like Python and Java.

Note: Pointers must be handled with care, since it is possible to damage data stored in other memory addresses.

Good To Know: There are three ways to declare pointer variables, but the first way is mostly used:

Pointers store address of variables or a memory location.

Using a Pointer:

To use pointers in C, we must understand below two operators.

  • To access address of a variable to a pointer, we use the unary operator & (ampersand) that returns the address of that variable. For example &x gives us address of variable x.
  • One more operator is unary * (Asterisk) which is used for two things :
    • To declare a pointer variable: When a pointer variable is declared in C/C++, there must be a * before its name.
  • To access the value stored in the address we use the unary operator (*) that returns the value of the variable located at the address specified by its operand. This is also called Dereferencing.
  • Output :
  • Below is pictorial representation of above program:

Pointer Expressions and Pointer Arithmetic
A limited set of arithmetic operations can be performed on pointers. A pointer may be:

  • incremented ( ++ )
  • decremented ( — )
  • an integer may be added to a pointer ( + or += )
  • an integer may be subtracted from a pointer ( – or -= )

Pointer arithmetic is meaningless unless performed on an array.
Note : Pointers contain addresses. Adding two addresses makes no sense, because there is no idea what it would point to. Subtracting two addresses lets you compute the offset between these two addresses.

Array Name as Pointers
An array name acts like a pointer constant. The value of this pointer constant is the address of the first element.
For example, if we have an array named val then val and &val[0] can be used interchangeably.

Now if this ptr is sent to a function as an argument then the array val can be accessed in a similar fashion.

Pointers and Multidimensional Arrays
Consider pointer notation for the two-dimensional numeric arrays. consider the following declaration

In general, nums[i][j] is equivalent to *(*(nums+i)+j)

Updated April 30, 2022

What is Pointer in C?

The Pointer in C, is a variable that stores address of another variable. A pointer can also be used to refer to another pointer function. A pointer can be incremented/decremented, i.e., to point to the next/ previous memory location. The purpose of pointer is to save memory space and achieve faster execution time.

How to Use Pointers in C

If we declare a variable v of type int, v will actually store a value.

v is equal to zero now.

However, each variable, apart from value, also has its address (or, simply put, where it is located in the memory). The address can be retrieved by putting an ampersand (&) before the variable name.

If you print the address of a variable on the screen, it will look like a totally random number (moreover, it can be different from run to run).

Let’s try this in practice with pointer in C example

The output of this program is -480613588.

Now, what is a pointer? Instead of storing a value, a pointer will y store the address of a variable.

VARIABLE POINTER
A value stored in a named storage/memory address A variable that points to the storage/memory address of another variable

Declaring a Pointer

Like variables, pointers in C programming have to be declared before they can be used in your program. Pointers can be named anything you want as long as they obey C’s naming rules. A pointer declaration has the following form.

  • data_type is the pointer’s base type of C’s variable types and indicates the type of the variable that the pointer points to.
  • The asterisk (*: the same asterisk used for multiplication) which is indirection operator, declares a pointer.

Let’s see some valid pointer declarations in this C pointers tutorial:

Initialize a pointer

After declaring a pointer, we initialize it like standard variables with a variable address. If pointers in C programming are not uninitialized and used in the program, the results are unpredictable and potentially disastrous.

To get the address of a variable, we use the ampersand (&)operator, placed before the name of a variable whose address we need. Pointer initialization is done with the following syntax.

Pointer Syntax

A simple program for pointer illustration is given below:

Output:

Operator Meaning
* Serves 2 purpose

Types of Pointers in C

Following are the different Types of Pointers in C:

Null Pointer

We can create a null pointer by assigning null value during the pointer declaration. This method is useful when you do not have any address assigned to the pointer. A null pointer always contains value 0.

Following program illustrates the use of a null pointer:

Output:

Void Pointer

In C programming, a void pointer is also called as a generic pointer. It does not have any standard data type. A void pointer is created by using the keyword void. It can be used to store an address of any variable.

Following program illustrates the use of a void pointer:

Output:

Wild pointer

A pointer is said to be a wild pointer if it is not being initialized to anything. These types of C pointers are not efficient because they may point to some unknown memory location which may cause problems in our program and it may lead to crashing of the program. One should always be careful while working with wild pointers.

Following program illustrates the use of wild pointer:

Output:

Other types of pointers in ‘c’ are as follows:

  • Dangling pointer
  • Complex pointer
  • Near pointer
  • Far pointer
  • Huge pointer

Direct and Indirect Access Pointers

In C, there are two equivalent ways to access and manipulate a variable content

  • Direct access: we use directly the variable name
  • Indirect access: we use a pointer to the variable

Let’s understand this with the help of program below

After compiling the program without any errors, the result is:

Pointer Arithmetic in C

The pointer operations are summarized in the following figure

Priority operation (precedence)

When working with C pointers, we must observe the following priority rules:

  • The operators * and & have the same priority as the unary operators (the negation!, the incrementation++, decrement–).
  • In the same expression, the unary operators *, &. ++, – are evaluated from right to left.

If a P pointer points to an X variable, then * P can be used wherever X can be written.

The following expressions are equivalent:

For the above code, below expressions are true

In the latter case, parentheses are needed: as the unary operators * and ++ are evaluated from right to left, without the parentheses the pointer P would be incremented, not the object on which P points.

Below table shows the arithmetic and basic operation that can be used when dealing with C pointers

Operation Explanation
Assignment int *P1,*P2
P1=P2;
P1 and P2 point to the same integer variable
Incrementation and decrementation Int *P1;
P1++;P1– ;
Adding an offset (Constant) This allows the pointer to move N elements in a table.
The pointer will be increased or decreased by N times the number of byte (s) of the type of the variable.
P1+5;

C Pointers & Arrays with Examples

Traditionally, we access the array elements using its index, but this method can be eliminated by using pointers. Pointers make it easy to access each array element.

Output:

Adding a particular number to a pointer will move the pointer location to the value obtained by an addition operation. Suppose p is a pointer that currently points to the memory location 0 if we perform following addition operation, p+1 then it will execute in this manner:

Since p currently points to the location 0 after adding 1, the value will become 1, and hence the pointer will point to the memory location 1.

C Pointers and Strings with Examples

A string is an array of char objects, ending with a null character ‘\ 0’. We can manipulate strings using pointers. This pointer in C example explains this section

Output:

Another way to deal strings is with an array of pointers like in the following program:

The pointer in C language is a variable which stores the address of another variable. This variable can be of type int, char, array, function, or any other pointer. The size of the pointer depends on the architecture. However, in 32-bit architecture the size of a pointer is 2 byte.

Consider the following example to define a pointer which stores the address of an integer.

Declaring a pointer

The pointer in c language can be declared using * (asterisk symbol). It is also known as indirection pointer used to dereference a pointer.

Pointer Example

An example of using pointers to print the address and value is given below.

As you can see in the above figure, pointer variable stores the address of number variable, i.e., fff4. The value of number variable is 50. But the address of pointer variable p is aaa3.

By the help of * (indirection operator), we can print the value of pointer variable p.

Let’s see the pointer example as explained for the above figure.

Output

Pointer to array

Pointer to a function

Pointer to structure

Advantage of pointer

1) Pointer reduces the code and improves the performance, it is used to retrieving strings, trees, etc. and used with arrays, structures, and functions.

2) We can return multiple values from a function using the pointer.

3) It makes you able to access any memory location in the computer’s memory.

Usage of pointer

There are many applications of pointers in c language.

1) Dynamic memory allocation

In c language, we can dynamically allocate memory using malloc() and calloc() functions where the pointer is used.

2) Arrays, Functions, and Structures

Pointers in c language are widely used in arrays, functions, and structures. It reduces the code and improves the performance.

Address Of (&) Operator

The address of operator ‘&’ returns the address of a variable. But, we need to use %u to display the address of a variable.

Output

NULL Pointer

A pointer that is not assigned any value but NULL is known as the NULL pointer. If you don’t have any address to be specified in the pointer at the time of declaration, you can assign NULL value. It will provide a better approach.

In the most libraries, the value of the pointer is 0 (zero).

Pointer Program to swap two numbers without using the 3rd variable.

Output

Reading complex pointers

There are several things which must be taken into the consideration while reading the complex pointers in C. Lets see the precedence and associativity of the operators which are used regarding pointers.

Operator Precedence Associativity
(), [] 1 Left to right
*, identifier 2 Right to left
Data type 3

Here,we must notice that,

  • (): This operator is a bracket operator used to declare and define the function.
  • []: This operator is an array subscript operator
  • * : This operator is a pointer operator.
  • Identifier: It is the name of the pointer. The priority will always be assigned to this.
  • Data type: Data type is the type of the variable to which the pointer is intended to point. It also includes the modifier like signed int, long, etc).

How to read the pointer: int (*p)[10].

To read the pointer, we must see that () and [] have the equal precedence. Therefore, their associativity must be considered here. The associativity is left to right, so the priority goes to ().

Inside the bracket (), pointer operator * and pointer name (identifier) p have the same precedence. Therefore, their associativity must be considered here which is right to left, so the priority goes to p, and the second priority goes to *.

Assign the 3rd priority to [] since the data type has the last precedence. Therefore the pointer will look like following.

  • char -> 4
  • * -> 2
  • p -> 1
  • [10] -> 3

The pointer will be read as p is a pointer to an array of integers of size 10.

Example

How to read the following pointer?

Explanation

This pointer will be read as p is a pointer to such function which accepts the first parameter as the pointer to a one-dimensional array of integers of size two and the second parameter as the pointer to a function which parameter is void and return type is the integer.

Most of us are familiar with creating arrays with data types such as integers, characters, or floats. This guide will show you how to create an array of pointers and use it to store data.

How to Create an Array

We can define an array as a collection of items. For example, an array can store names of 100 people and such.

To declare an array in C, we use the syntax:

Here, the dataType refers to the type of array, which can be an integer, float, a character, or a pointer.

The arrName refers to the name given to the array, which can be any descriptive term for the variable as long it obeys the rules of naming a variable in C.

Finally, the arrSize refers to the total number of items to store in the array. This value is constant and unchangeable once declared.

For example, we can define an array of integers to store 10 values as:

We can also define and initialize an array in the same line. For example, to define the array above and populate it with the required values, we can do :

We can also do the same without explicitly specifying the array size. Consider the example below:

To access items in an array, we use the indexing method by specifying the array’s name followed by the index of the item we wish to access.

For example, to access the item at index 5, we can do

In this case, it should return the 6 th item in the array because array indexing starts at 0. Therefore, the first item is at 0, the second item at 1, and so on.

We can also use the above method to modify the values in an array.

Here is an example:

The above statement will change the array value at index 5 to 5.

C Pointers

Pointers are variables that we can use to store addresses of values in a program. For example, when you define a variable, it is assigned a memory address that you can access by using the
&varname;

The above code should give the address for the “i” variable. Note that this address can vary every time you run the program.

Here is a sample address:

Declaring a Pointer

To declare a pointer in C, we use the type followed by an asterisk and the variable’s name.

To assign an address to the pointer, we can do:

In the example above, we set the address of the variable “i” to *ptr.

Accessing Values from a Pointer

We can access the values stored in a pointer address by using the asterisk (*) notation. For example:

In this case, we get the specific value stored and not the address of the value.

Array of Pointers

As we created an array of integer values in the examples above, we can create an array of a pointer—basically, an array that stores memory addresses.

To do this, we can use the syntax:

In this example, we have an array of 10 integer pointers, allowing you to store memory addresses of 5 integer variables.

For example, we can have the simple code below:

int main ( ) <
int * ptrarray [ 4 ] ;
int w = 100 , x = 200 , y = 300 , z = 400 ;

ptrarray [ 0 ] = & w ;
ptrarray [ 1 ] = & x ;
ptrarray [ 2 ] = & y ;
ptrarray [ 3 ] = & z ;

for ( int i = 0 ; i 4 ; i ++ ) <
printf ( “The value %d has the adddress %d \n ” , * ptrarray [ i ] , ptrarray [ i ] ) ;
>
return 0 ;
>

Once we compile and run the code above, we should get results similar to the ones below:

Using this method, we can access both the addresses and the values stored in the array pointer.

Conclusion

In this short guide, we discussed how to use arrays and pointers in the C language. We also discussed how to create an array of pointers to store addresses for various values.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list

By Chaitanya Singh | Filed Under: c-programming

A pointer is a variable that stores the address of another variable. Unlike other variables that hold values of a certain type, pointer holds the address of a variable. For example, an integer variable holds (or you can say stores) an integer value, however an integer pointer holds the address of a integer variable. In this guide, we will discuss pointers in C programming with the help of examples.

Before we discuss about pointers in C, lets take a simple example to understand what do we mean by the address of a variable.

A simple example to understand how to access the address of a variable without pointers?

In this program, we have a variable num of int type. The value of num is 10 and this value must be stored somewhere in the memory, right? A memory space is allocated for each variable that holds the value of that variable, this memory space has an address. For example we live in a house and our house has an address, which helps other people to find our house. The same way the value of the variable is stored in a memory address, which helps the C program to find that value when it is needed.

So let’s say the address assigned to variable num is 0x7fff5694dc58 , which means whatever value we would be assigning to num should be stored at the location: 0x7fff5694dc58 . See the diagram below.

Output:

A Simple Example of Pointers in C

This program shows how a pointer is declared and used. There are several other things that we can do with pointers, we have discussed them later in this guide. For now, we just need to know how to link a pointer to the address of a variable.

Important point to note is: The data type of pointer and the variable must match, an int pointer can hold the address of int variable, similarly a pointer declared with float data type can hold the address of a float variable. In the example below, the pointer and the variable both are of int type.

C Pointers – Operators that are used with Pointers

Lets discuss the operators & and * that are used with Pointers in C.

“Address of”(&) Operator

We have already seen in the first example that we can display the address of a variable using ampersand sign. I have used &num to access the address of variable num. The & operator is also known as “Address of” Operator.

Point to note: %p is a format specifier which is used for displaying the address in hex format.
Now that you know how to get the address of a variable but how to store that address in some other variable? That’s where pointers comes into picture. As mentioned in the beginning of this guide, pointers in C programming are used for holding the address of another variables.

Pointer is just like another variable, the main difference is that it stores address of another variable rather than a value.

“Value at Address”(*) Operator

The * Operator is also known as Value at address operator.

How to declare a pointer?

The above are the few examples of pointer declarations. If you need a pointer to store the address of integer variable then the data type of the pointer should be int. Same case is with the other data types.

By using * operator we can access the value of a variable through a pointer.
For example:

*p would give us the value of the variable a. The following statement would display 10 as output.

Similarly if we assign a value to *pointer like this:

It would change the value of variable a. The statement above will change the value of a from 10 to 200.

Example of Pointer demonstrating the use of & and *

Lets take few more examples to understand it better –
Lets say we have a char variable ch and a pointer ptr that holds the address of ch.

Read the value of ch

Change the value of ch

The above code would replace the value ‘a’ with ‘b’.

Can you guess the output of following C program?

Output:

More Topics on Pointers

1) Pointer to Pointer – A pointer can point to another pointer (which means it can store the address of another pointer), such pointers are known as double pointer OR pointer to pointer.

2) Passing pointers to function – Pointers can also be passed as an argument to a function, using this feature a function can be called by reference as well as an array can be passed to a function while calling.

3) Function pointers – A function pointer is just like another pointer, it is used for storing the address of a function. Function pointer can also be used for calling a function in C program.

Example Uses of Function Pointers

Functions as Arguments to Other Functions

If you were to write a sort routine, you might want to allow the function’s caller to choose the order in which the data is sorted; some programmers might need to sort the data in ascending order, others might prefer descending order while still others may want something similar to but not quite like one of those choices. One way to let your user specify what to do is to provide a flag as an argument to the function, but this is inflexible; the sort function allows only a fixed set of comparison types (e.g., ascending and descending).

A much nicer way of allowing the user to choose how to sort the data is simply to let the user pass in a function to the sort function. This function might take two pieces of data and perform a comparison on them. We’ll look at the syntax for this in a bit.

Callback Functions

Another use for function pointers is setting up “listener” or “callback” functions that are invoked when a particular event happens. The function is called, and this notifies your code that something of interest has taken place.

Why would you ever write code with callback functions? You often see it when writing code using someone’s library. One example is when you’re writing code for a graphical user interface (GUI). Most of the time, the user will interact with a loop that allows the mouse pointer to move and that redraws the interface. Sometimes, however, the user will click on a button or enter text into a field. These operations are “events” that may require a response that your program needs to handle. How can your code know what’s happening? Using Callback functions! The user’s click should cause the interface to call a function that you wrote to handle the event.

To get a sense for when you might do this, consider what might happen if you were using a GUI library that had a “create_button” function. It might take the location where a button should appear on the screen, the text of the button, and a function to call when the button is clicked. Assuming for the moment that C (and C++) had a generic “function pointer” type called function, this might look like this: Whenever the button is clicked, callback_func will be invoked. Exactly what callback_func does depends on the button; this is why allowing the create_button function to take a function pointer is useful.

Function Pointer Syntax

The syntax for declaring a function pointer might seem messy at first, but in most cases it’s really quite straight-forward once you understand what’s going on. Let’s look at a simple example: In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It’s as if you’re declaring a function called “*foo”, which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function. (Similarly, a declaration like int *x can be read as *x is an int, so x must be a pointer to an int.)

The key to writing the declaration for a function pointer is that you’re just writing out the declaration of a function but with (*func_name) where you’d normally just put func_name.

Reading Function Pointer Declarations

Initializing Function Pointers

Using a Function Pointer

Function Pointers in the Wild

Let’s go back to the sorting example where I suggested using a function pointer to write a generic sorting routine where the exact order could be specified by the programmer calling the sorting function. It turns out that the C function qsort does just that.

From the Linux man pages, we have the following declaration for qsort (from stdlib.h): Note the use of void*s to allow qsort to operate on any kind of data (in C++, you’d normally use templates for this task, but C++ also allows the use of void* pointers) because void* pointers can point to anything. Because we don’t know the size of the individual elements in a void* array, we must give qsort the number of elements, nmemb, of the array to be sorted, base, in addition to the standard requirement of giving the length, size, of the input.

But what we’re really interested in is the compar argument to qsort: it’s a function pointer that takes two void *s and returns an int. This allows anyone to specify how to sort the elements of the array base without having to write a specialized sorting algorithm. Note, also, that compar returns an int; the function pointed to should return -1 if the first argument is less than the second, 0 if they are equal, or 1 if the second is less than the first.

For instance, to sort an array of numbers in ascending order, we could write code like this:

Using Polymorphism and Virtual Functions Instead of Function Pointers (C++)

But Are You Really Not Using Function Pointers?

Function Pointers Summary

Syntax

Declaring

Initializing

Invoking

Benefits of Function Pointers

  • Function pointers provide a way of passing around instructions for how to do something
  • You can write flexible functions and libraries that allow the programmer to choose behavior by passing function pointers as arguments
  • This flexibility can also be achieved by using classes with virtual functions

I am grateful to Alex Hoffer and Thomas Carriero for their comments on a draft of this article.

STOP! If you have not gone over Section 1: Simple C or do not completely understand what is going on, do not proceed. The following will make absolutely no sense if you have not read Section 1. Go back and re-read pages that are troubling you and practice before proceeding! If you are comfortable with the material discussed thus far, lets begin our journey into pointers.

Pointers :: Definition

  • Pointers provide an indirect method of accessing variables. The reason why some people have difficulty understanding the concept of a pointer is that they are usually introduced without some sort of analogy or easily understood example.
  • For our simple to understand example, let’s think about a typical textbook. It will usually have a table of contents, some chapters, and an index. Suppose we have a Chemistry textbook and would like to find more information on the noble gases. What one would typically do instead of flipping through the entire text, is to consult the index in the back. The index would direct us to the page(s) on which we can read more on noble gases. Conceptually, this is how pointers work!
  • A pointer is simply a reference containing a memory address. In our example, the noble gas entry in the index would list page numbers for more information. This is analogous to a pointer reference containing the memory address of where the real data is actually stored!
  • You may be wondering, what is the point of this (no pun intended)? Why don’t I just make all variables without the use of pointers? It’s because sometimes you can’t. What if you needed an array of ints, but didn’t know the size of the array before hand? What if you needed a string, but it grew dynamically as the program ran? What if you need variables that are persistent through function use without declaring them global (remember the swap function)? They are all solved through the use of pointers. Pointers are also essential in creating larger custom data structures, such as linked lists.
  • So now that you understand how pointers work, let’s define them a little better.
    • A pointer when declared is just a reference. DECLARING A POINTER DOES NOT CREATE ANY SPACE FOR THE POINTER TO POINT TO. We will tackle this dynamic memory allocation issue later.
    • As stated prior, a pointer is a reference to an area of memory. This is known as a memory address. A pointer may point to dynamically allocated memory or a variable declared within a block.
    • Since a pointer contains memory addresses, the size of a pointer typically corresponds to the word size of your computer. You can think of a “word” as how much data your computer can access at once. Typical machines today are 32- or 64-bit machines. 8-bits per byte equates to 4- or 8-byte pointer sizes. More on this later.

Pointers :: Declaration and Syntax

  • Pointers are declared by using the * in front of the variable identifier. For example: This delcares a pointer, ip, to an integer. Let’s say we want ip to point to an integer. The second line delares a pointer to a float, but initializes the pointer to point to the NULL pointer. The NULL pointer points to a place in memory that cannot be accessed. NULL is useful when checking for error conditions and many functions return NULL if they fail. We first encountered the & operator first in the I/O section. The & operator is to specify the address-of x. Thus, the pointer, ip is pointing to x by assigning the address of x. This is important. You must understand this concept.
  • This brings up the question, if pointers contain addresses, then how do I get the actual value of what the pointer is pointing to? This is solved through the * operator. The * dereferences the pointer to the value. So, would print 5 5 to the screen.
  • There is a critical difference between a dereference and a pointer declaration: The statement int *ip = &y; is different than x = *ip; . The first statement does not dereference, the * signifies to create a pointer to an int. The second statement uses a dereference.
  • Remember the swap function? We can now simulate call by reference using pointers. Here is a modified version of the swap function using pointers: This snip of swapping code works. When you call swap, you must give the address-of a and b, because swap is expecting a pointer.
  • Why does this work? It’s because you are giving the address-of the variables. This memory does not “go away” or get “popped off” after the function swap ends. The changes within swap change the values located in those memory addresses.

Pointers :: Pointers and const Type Qualifier

  • The const type qualifier can make things a little confusing when it is used with pointer declarations.
  • The below example is from Weiss pg. 132: As you can see, you must be careful when specifying the const qualifier when using pointers.

Pointers :: void Pointers

  • void pointers can be assigned to any pointer value. It sometimes necessary to store/copy/move pointers without regard to the type it references.
  • You cannot dereference a void pointer.
  • Functions such as malloc , free , and scanf utilize void pointers.

Pointers :: Pointers to Functions

  • Earlier, we said that you can pass functions as parameters into functions. This was essentially a reference, or pointer, passed into the function.
  • There is an alternative way to declare and pass in functions as parameters into functions. It is discussed in detail in Weiss, pgs. 135-136.

Pointers :: Pointer Arithmetic

  • C is one of the few languages that allows pointer arithmetic. In other words, you actually move the pointer reference by an arithmetic operation. For example: On a typical 32-bit machine, *ip would be pointing to 5 after initialization. But ip++; increments the pointer 32-bits or 4-bytes. So whatever was in the next 4-bytes, *ip would be pointing at it.
  • Pointer arithmetic is very useful when dealing with arrays, because arrays and pointers share a special relationship in C. More on this when we get to arrays!
  • Pointers are an indirect reference to something else. They are primarily used to reference items that might dynamically change size at run time.
  • Pointers have special operators, & and * . The & operator gives the address-of a pointer. The * dereferences the pointer (when not used in a pointer declaration statement).
  • You must be careful when using const type qualifier. You have to also be cautious about the void pointer.
  • C allows pointer arithmetic, which gives the programmer the freedom to move the pointer using simple arithmetic. This is very powerful, yet can lead to disaster if not used properly.

Notice: Please do not replicate or copy these pages and host them elsewhere. This is to ensure that the latest version can always be found here.

Disclaimer: The document author has published these pages with the hope that it may be useful to others. However, the document author does not guarantee that all information contained on these webpages are correct or accurate. There is no warranty, expressed or implied, of merchantability or fitness for any purpose. The author does not assume any liability or responsibility for the use of the information contained on these webpages.

If you see an error, please send an email to the address below indicating the error. Your feedback is greatly appreciated and will help to continually improve these pages.

This is the third post in the series. The very first tutorial is Mapping primitive data types from C. There are also Mapping struct and union types from C and Mapping strings from C tutorials.

In this tutorial We will learn how to:

Mapping function pointer types from C

The best way to understand the mapping between Kotlin and C is to try a tiny example. Declare a function that accepts a function pointer as a parameter and another function that returns a function pointer.

Kotlin/Native comes with the cinterop tool; the tool generates bindings between the C language and Kotlin. It uses a .def file to specify a C library to import. More details on this are in Interop with C Libraries.

The quickest way to try out C API mapping is to have all C declarations in the interop.def file, without creating any .h of .c files at all. Then place the C declarations in a .def file after the special — separator line:

The interop.def file is enough to compile and run the application or open it in an IDE. Now it is time to create project files, open the project in IntelliJ IDEA and run it.

Inspect generated Kotlin APIs for a C library

While it is possible to use the command line, either directly or by combining it with a script file (such as .sh or .bat file), this approach doesn’t scale well for big projects that have hundreds of files and libraries. It is then better to use the Kotlin/Native compiler with a build system, as it helps to download and cache the Kotlin/Native compiler binaries and libraries with transitive dependencies and run the compiler and tests. Kotlin/Native can use the Gradle build system through the kotlin-multiplatform plugin.

We covered the basics of setting up an IDE compatible project with Gradle in the A Basic Kotlin/Native Application tutorial. Please check it out if you are looking for detailed first steps and instructions on how to start a new Kotlin/Native project and open it in IntelliJ IDEA. In this tutorial, we’ll look at the advanced C interop related usages of Kotlin/Native and multiplatform builds with Gradle.

First, create a project folder. All the paths in this tutorial will be relative to this folder. Sometimes the missing directories will have to be created before any new files can be added.

Use the following build.gradle(.kts) Gradle build file:

The project file configures the C interop as an additional step of the build. Let’s move the interop.def file to the src/nativeInterop/cinterop directory. Gradle recommends using conventions instead of configurations, for example, the source files are expected to be in the src/nativeMain/kotlin folder. By default, all the symbols from C are imported to the interop package, you may want to import the whole package in our .kt files. Check out the kotlin-multiplatform plugin documentation to learn about all the different ways you could configure it.

Let’s create a src/nativeMain/kotlin/hello.kt stub file with the following content to see how C primitive type declarations are visible from Kotlin:

Now you are ready to open the project in IntelliJ IDEA and to see how to fix the example project. While doing that, see how C functions are mapped into Kotlin/Native declarations.

C function pointers in Kotlin

With the help of IntelliJ IDEA’s Go To | Declaration or Usages or compiler errors, see the following declarations for the C functions:

You see that the function’s typedef from C has been turned into Kotlin typealias . It uses CPointer type to represent the pointer parameters, and CFunction Int> to represent the function signature. There is an invoke operator extension function available for all CPointer types, so that it is possible to call it as you would call any other function in Kotlin.

Pass Kotlin function as C function pointer

It is the time to try using C functions from the Kotlin program. Call the accept_fun function and pass the C function pointer to a Kotlin lambda:

This call uses the staticCFunction <..>helper function from Kotlin/Native to wrap a Kotlin lambda function into a C function pointer. It only allows having unbound and non-capturing lambda functions. For example, it is not able to use a local variable from the function. You may only use globally visible declarations. Throwing exceptions from a staticCFunction <..>will end up in non-deterministic side-effects. It is vital to make sure that you code is not throwing any sudden exceptions from it.

Use the C function pointer from Kotlin

The next step is to call a C function pointer from a C pointer that you have from the supply_fun() call:

Kotlin turns the function pointer return type into a nullable CPointer object. There is the need to explicitly check for null first. The elvis operator for that in the code above. The cinterop tool helps us to turn a C function pointer into an easy to call object in Kotlin. This is what we did on the last line.

Fix the code

You’ve seen all definitions and it is time to fix and run the code. Run the runDebugExecutableNative Gradle task in the IDE or use the following command to run the code:

The code in the hello.kt file may look like this:

Next Steps

Continue exploring more C language types and their representation in Kotlin/Native in next tutorials:

The C Interop documentation covers more advanced scenarios of the interop.