C Programming Tutorial

  • Pointer to a Structure in C

Last updated on July 27, 2020

We have already learned that a pointer is a variable which points to the address of another variable of any data type like int , char , float etc. Similarly, we can have a pointer to structures, where a pointer variable can point to the address of a structure variable. Here is how we can declare a pointer to a structure variable.

This declares a pointer ptr_dog that can store the address of the variable of type struct dog . We can now assign the address of variable spike to ptr_dog using & operator.

Now ptr_dog points to the structure variable spike .

Accessing members using Pointer #

There are two ways of accessing members of structure using pointer:

  • Using indirection ( * ) operator and dot ( . ) operator.
  • Using arrow ( -> ) operator or membership operator.

Let's start with the first one.

Using Indirection (*) Operator and Dot (.) Operator #

At this point ptr_dog points to the structure variable spike , so by dereferencing it we will get the contents of the spike . This means spike and *ptr_dog are functionally equivalent. To access a member of structure write *ptr_dog followed by a dot( . ) operator, followed by the name of the member. For example:

(*ptr_dog).name - refers to the name of dog (*ptr_dog).breed - refers to the breed of dog

Parentheses around *ptr_dog are necessary because the precedence of dot( . ) operator is greater than that of indirection ( * ) operator.

Using arrow operator (->) #

The above method of accessing members of the structure using pointers is slightly confusing and less readable, that's why C provides another way to access members using the arrow ( -> ) operator. To access members using arrow ( -> ) operator write pointer variable followed by -> operator, followed by name of the member.

Here we don't need parentheses, asterisk ( * ) and dot ( . ) operator. This method is much more readable and intuitive.

We can also modify the value of members using pointer notation.

Here we know that the name of the array ( ptr_dog->name ) is a constant pointer and points to the 0th element of the array. So we can't assign a new string to it using assignment operator ( = ), that's why strcpy() function is used.

In the above expression precedence of arrow operator ( -> ) is greater than that of prefix decrement operator ( -- ), so first -> operator is applied in the expression then its value is decremented by 1.

The following program demonstrates how we can use a pointer to structure.

Expected Output:

How it works:

In lines 3-9, we have declared a structure of type dog which has four members namely name , breed , age and color .

In line 13, a variable called my_dog of type struct dog is declared and initialized.

In line 14, a pointer variable ptr_dog of type struct dog is declared.

In line 15, the address of my_dog is assigned to ptr_dog using & operator.

In lines 17-20, the printf() statements prints the details of the dog.

In line 23, a new name is assigned to ptr_dog using the strcpy() function, because we can't assign a string value directly to ptr_dog->name using assignment operator.

In line 26, the value of ptr_dog->age is incremented by 1 using postfix increment operator. Recall that postfix ++ operator and -> have the same precedence and associates from left to right. But since postfix ++ is used in the expression first the value of ptr_dog->age is used in the expression then it's value is incremented by 1 .

Load Comments

  • Intro to C Programming
  • Installing Code Blocks
  • Creating and Running The First C Program
  • Basic Elements of a C Program
  • Keywords and Identifiers
  • Data Types in C
  • Constants in C
  • Variables in C
  • Input and Output in C
  • Formatted Input and Output in C
  • Arithmetic Operators in C
  • Operator Precedence and Associativity in C
  • Assignment Operator in C
  • Increment and Decrement Operators in C
  • Relational Operators in C
  • Logical Operators in C
  • Conditional Operator, Comma operator and sizeof() operator in C
  • Implicit Type Conversion in C
  • Explicit Type Conversion in C
  • if-else statements in C
  • The while loop in C
  • The do while loop in C
  • The for loop in C
  • The Infinite Loop in C
  • The break and continue statement in C
  • The Switch statement in C
  • Function basics in C
  • The return statement in C
  • Actual and Formal arguments in C
  • Local, Global and Static variables in C
  • Recursive Function in C
  • One dimensional Array in C
  • One Dimensional Array and Function in C
  • Two Dimensional Array in C
  • Pointer Basics in C
  • Pointer Arithmetic in C
  • Pointers and 1-D arrays
  • Pointers and 2-D arrays
  • Call by Value and Call by Reference in C
  • Returning more than one value from function in C
  • Returning a Pointer from a Function in C
  • Passing 1-D Array to a Function in C
  • Passing 2-D Array to a Function in C
  • Array of Pointers in C
  • Void Pointers in C
  • The malloc() Function in C
  • The calloc() Function in C
  • The realloc() Function in C
  • String Basics in C
  • The strlen() Function in C
  • The strcmp() Function in C
  • The strcpy() Function in C
  • The strcat() Function in C
  • Character Array and Character Pointer in C
  • Array of Strings in C
  • Array of Pointers to Strings in C
  • The sprintf() Function in C
  • The sscanf() Function in C
  • Structure Basics in C
  • Array of Structures in C
  • Array as Member of Structure in C
  • Nested Structures in C
  • Pointers as Structure Member in C
  • Structures and Functions in C
  • Union Basics in C
  • typedef statement in C
  • Basics of File Handling in C
  • fputc() Function in C
  • fgetc() Function in C
  • fputs() Function in C
  • fgets() Function in C
  • fprintf() Function in C
  • fscanf() Function in C
  • fwrite() Function in C
  • fread() Function in C

Recent Posts

  • Machine Learning Experts You Should Be Following Online
  • 4 Ways to Prepare for the AP Computer Science A Exam
  • Finance Assignment Online Help for the Busy and Tired Students: Get Help from Experts
  • Top 9 Machine Learning Algorithms for Data Scientists
  • Data Science Learning Path or Steps to become a data scientist Final
  • Enable Edit Button in Shutter In Linux Mint 19 and Ubuntu 18.04
  • Python 3 time module
  • Pygments Tutorial
  • How to use Virtualenv?
  • Installing MySQL (Windows, Linux and Mac)
  • What is if __name__ == '__main__' in Python ?
  • Installing GoAccess (A Real-time web log analyzer)
  • Installing Isso

Intro to C for CS31 Students

Part 2: structs & pointers.

  • Pointers and Functions C style "pass by referece"
  • Dynamic Memory Allocation (malloc and free)
  • Pointers to Structs

Defining a struct type

Declaring variables of struct types, accessing field values, passing structs to functions, rules for using pointer variables.

  • Next, initialize the pointer variable (make it point to something). Pointer variables store addresses . Initialize a pointer to the address of a storage location of the type to which it points. One way to do this is to use the ampersand operator on regular variable to get its address value: int x; char ch; ptr = &x; // ptr get the address of x, pointer "points to" x ------------ ------ ptr | addr of x|--------->| ?? | x ------------ ------ cptr = &ch; // ptr get the address of ch, pointer "points to" ch cptr = &x; // ERROR! cptr can hold a char address only (it's NOT a pointer to an int) All pointer variable can be set to a special value NULL . NULL is not a valid address but it is useful for testing a pointer variable to see if it points to a valid memory address before we access what it points to: ptr = NULL; ------ ------ cptr = NULL; ptr | NULL |-----| cptr | NULL |----| ------ ------
  • Use *var_name to dereference the pointer to access the value in the location that it points to. Some examples: int *ptr1, *ptr2, x, y; x = 8; ptr1 = NULL; ptr2 = &x; ------------ ------ ptr2 | addr of x|--------->| 8 | x ------------ ------ *ptr2 = 10; // dereference ptr2: "what ptr2 points to gets 10" ------------ ----- ptr2 | addr of x|--------->| 10 | x ------------ ----- y = *ptr2 + 3; // dereference ptr2: "y gets what ptr2 points to plus 3" ----- ----- ptr1 = ptr2; // ptr1 gets address value stored in ptr2 ------------ ----- ptr2 | addr of x |--------->| 10 | x ------------ ----- /\ ------------ | ptr1 | addr of x |-------------- ------------ // TODO: finish tracing through this code and show what is printed *ptr1 = 100; ptr1 = &y; *ptr1 = 80; printf("x = %d y = %d\n", x, y); printf("x = %d y = %d\n", *ptr2, *ptr1);
  • and what does this mean with respect to the value of each argument after the call?
  • Implement a program with a swap function that swaps the values stored in its two arguments. Make some calls to it in main to test it out.

malloc and free

Pointers, the heap, and functions, linked lists in c.

Pointers in C Explained – They're Not as Difficult as You Think

Pointers are arguably the most difficult feature of C to understand. But, they are one of the features which make C an excellent language.

In this article, we will go from the very basics of pointers to their usage with arrays, functions, and structure.

So relax, grab a coffee, and get ready to learn all about pointers.

A. Fundamentals

  • What exactly are pointers?
  • Definition and Notation
  • Some Special Pointers
  • Pointer Arithmetic

B. Arrays and Strings

  • Why pointers and arrays?
  • Array of Pointers
  • Pointer to Array

C. Functions

  • Call by Value v/s Call by Reference
  • Pointers as Function Arguments
  • Pointers as Function Return
  • Pointer to Function
  • Array Of Pointers to Functions
  • Pointer to Function as an Argument

D. Structure

  • Pointer to Structure
  • Array of Structure
  • Pointer to Structure as an Argument

E. Pointer to Pointer

F. conclusion, a. definition, notation, types and arithmetic, 1. what exactly are pointers.

Before we get to the definition of pointers, let us understand what happens when we write the following code:

What exactly are pointers?

A block of memory is reserved by the compiler to hold an int value. The name of this block is digit and the value stored in this block is 42 .

Now, to remember the block, it is assigned with an address or a location number (say, 24650).

The value of the location number is not important for us, as it is a random value. But, we can access this address using the & (ampersand) or address of operator.

We can get the value of the variable digit from its address using another operator * (asterisk), called the indirection or dereferencing or value at address operator.

2. Definition and Notation

The address of a variable can be stored in another variable known as a pointer variable. The syntax for storing a variable's address to a pointer is:

For our digit variable, this can be written like this:

or like this:

This can be read as - A pointer to int (integer) addressOfDigit stores the address of(&) digit variable.

Few points to understand:

dataType – We need to tell the computer what the data type of the variable is whose address we are going to store. Here, int was the data type of digit .

It does not mean that addressOfDigit will store a value of type int . An integer pointer (like addressOfDigit ) can only store the address of variables of integer type.

* – A pointer variable is a special variable in the sense that it is used to store an address of another variable. To differentiate it from other variables that do not store an address, we use * as a symbol in the declaration.

Here, we can assign the address of variable1 and variable2 to the integer pointer addressOfVariables but not to variable3 since it is of type char . We will need a character pointer variable to store its address.

We can use our addressOfDigit pointer variable to print the address and the value of digit as below:

Here, *addressOfDigit can  be read as the value at the address stored in addressOfDigit .

Notice we used %d as the format identifier for addressOfDigit . Well, this is not completely correct. The correct identifier would be %p .

Using %p , the address is displayed as a hexadecimal value. But the memory address can be displayed in integers as well as octal values. Still, since it is not an entirely correct way, a warning is shown.

The output according to the compiler I'm using is the following:

This is the warning shown when you use  %d - " warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' ".

3. Some Special Pointers

The wild pointer.

When we defined our character pointer alphabetAddress , we did not initialize it.

Such pointers are known as wild pointers . They store a garbage value (that is, memory address) of a byte that we don't know is reserved or not (remember int digit = 42; , we reserved a memory address when we declared it).

Suppose we dereference a wild pointer and assign a value to the memory address it is pointing at. This will lead to unexpected behaviour since we will write data at a  memory block that may be free or reserved.

Null Pointer

To make sure that we do not have a wild pointer, we can initialize a pointer with a NULL value, making it a null pointer .

A null pointer points at nothing, or at a memory address that users can not access.

Void Pointer

A void pointer can be used to point at a variable of any data type. It can be reused to point at any data type we want to. It is declared like this:

Since they are very general in nature, they are also known as generic pointers .

With their flexibility, void pointers also bring some constraints. Void pointers cannot be dereferenced as any other pointer. Appropriate typecasting is necessary.

Similarly, void pointers need to be typecasted for performing arithmetic operations.

Void pointers are of great use in C. Library functions malloc() and calloc() which dynamically allocate memory return void pointers. qsort() , an inbuilt sorting function in C, has a function as its argument which itself takes void pointers as its argument.

Dangling Pointer

A dangling pointer points to a memory address which used to hold a variable. Since the address it points at is no longer reserved, using it will lead to unexpected results.

Though the memory has been deallocated by free(ptr) , the pointer to integer ptr still points to that unreserved memory address.

4. Pointer Arithmetic

We know by now that pointers are not like any other variable. They do not store any value but the address of memory blocks.

So it should be quite clear that not all arithmetic operations would be valid with them. Would multiplying or dividing two pointers ( having addresses ) make sense?

Pointers have few but immensely useful valid operations:

  • You can assign the value of one pointer to another only if they are of the same type (unless they're typecasted or one of them is void * ).

2.   You can only add or subtract integers to pointers.

When you add (or subtract) an integer (say n) to a pointer, you are not actually adding (or subtracting) n bytes to the pointer value. You are actually adding (or subtracting) n- times the size of the data type of the variable being pointed bytes.

The value stored in newAddress will not be 103, rather 112 .

3.   Subtraction and comparison of pointers is valid only if both are members of the same array. The subtraction of pointers gives the number of elements separating them.

4.  You can assign or compare a pointer with NULL .

The only exception to the above rules is that the address of the first memory block after the last element of an array follows pointer arithmetic.

Pointer and arrays exist together. These valid manipulations of pointers are immensely useful with arrays, which will be discussed in the next section.

1. Why pointers and arrays?

In C, pointers and arrays have quite a strong relationship.

The reason they should be discussed together is because what you can achieve with array notation ( arrayName[index] ) can also be achieved with pointers, but generally faster.

2. 1-D Arrays

Let us look at what happens when we write int myArray[5]; .

Five consecutive blocks of memory starting from myArray[0] to myArray[4] are created with garbage values in them. Each of the blocks is of size 4 bytes.

Thus, if the address of myArray[0] is 100 (say), the address of the rest of the blocks would be 104 , 108 , 112 , and 116 .

Have a look at the following code:

So, &prime , prime , and &prime[0] all give the same address, right? Well, wait and read because you are in for a surprise (and maybe some confusion).

Let's try to increment each of &prime , prime , and &prime[0] by 1.

Wait! How come &prime + 1 results in something different than the other two? And why are prime + 1 and &prime[0] + 1 still equal? Let's answer these questions.

prime and &prime[0] both point to the 0th element of the array prime . Thus, the name of an array is itself a pointer to the 0th element of the array .

Here, both point to the first element of size 4 bytes. When you add 1 to them, they now point to the 1st element in the array. Therefore this results in an increase in the address by 4.

&prime , on the other hand, is a pointer to an int array of size 5 . It stores the base address of the array prime[5] , which is equal to the address of the first element. However, an increase by 1 to it results in an address with an increase of 5 x 4 = 20 bytes.

In short, arrayName and &arrayName[0] point to the 0th element whereas &arrayName points to the whole array.

We can access the array elements using subscripted variables like this:

We can do the same using pointers which are always faster than using subscripts.

Both methods give the output:

Thus, &arrayName[i] and arrayName[i] are the same as arrayName + i and   *(arrayName + i) , respectively.

3. 2-D Arrays

Two-dimensional arrays are an array of arrays.

Here, marks can be thought of as an array of 5 elements, each of which is a one-dimensional array containing 3 integers. Let us work through a series of programs to understand different subscripted expressions.

Like 1-D arrays, &marks points to the whole 2-D array, marks[5][3] . Thus, incrementing to it by 1 ( = 5 arrays X 3 integers each X 4 bytes = 60) results in an increment by 60 bytes.

If marks was a 1-D array, marks and &marks[0] would have pointed to the 0th element. For a 2-D array, elements are now 1-D arrays . Hence, marks and &marks[0] point to the 0th array (element), and the addition of 1 point to the 1st array.

And now comes the difference. For a 1-D array, marks[0] would give the value of the 0th element. An increment by 1 would increase the value by 1.

But, in a 2-D array, marks[0] points to the 0th element of the 0th array. Similarly, marks[1] points to the 0th element of the 1st array. An increment by 1 would point to the 1st element in the 1st array.

This is the new part. marks[i][j] gives the value of the jth element of the ith array. An increment to it changes the value stored at marks[i][j] . Now, let us try to write marks[i][j] in terms of pointers.

We know marks[i] + j would point to the ith element of the jth array from our previous discussion. Dereferencing it would mean the value at that address. Thus, marks[i][j] is the same as   *(marks[i] + j) .

From our discussion on 1-D arrays, marks[i] is the same as *(marks + i) . Thus, marks[i][j] can be written as *(*(marks + i) + j) in terms of pointers.

Here is a summary of notations comparing 1-D and 2-D arrays.

A string is a one-dimensional array of characters terminated by a null(\0) . When we write char name[] = "Srijan"; , each character occupies one byte of memory with the last one always being \0 .

Similar to the arrays we have seen, name and &name[0] points to the 0th character in the string, while &name points to the whole string. Also, name[i] can be written as *(name + i) .

A two-dimensional array of characters or an array of strings can also be accessed and manipulated as discussed before.

5. Array of Pointers

Like an array of int s and an array of char s, there is an array of pointers as well. Such an array would simply be a collection of addresses. Those addresses could point to individual variables or another array as well.

The syntax for declaring a pointer array is the following:

Following the operators precedence , the first example can be read as -   example1 is an array( [] ) of 5 pointers to int . Similarly, example2 is an array of 8 pointers to char .

We can store the two-dimensional array to string top using a pointer array and save memory as well.

top will contain the base addresses of all the respective names. The base address of "Liverpool" will be stored in top[0] , "Man City" in top[1] , and so on.

In the earlier declaration, we required 90 bytes to store the names. Here, we only require ( 58 (sum of bytes of names) + 12 ( bytes required to store the address in the array) ) 70 bytes.

The manipulation of strings or integers becomes a lot easier when using an array of pointers.

If we try to put "Leicester" ahead of "Chelsea" , we just need to switch the values of top[3] and top[4] like below:

Without pointers, we would have to exchange every character of the strings, which would have taken more time. That's why strings are generally declared using pointers.

6. Pointer to Array

Like "pointer to int " or "pointer to char ", we have pointer to array as well. This pointer points to whole array rather than its elements.

Remember we discussed how &arrayName points to the whole array? Well, it is a pointer to array.

A pointer to array can be declared like this:

Notice the parentheses. Without them, these would be an array of pointers. The first example can be read as - ptr1 is a pointer to an array of 5 int (integers) .

When we dereference a pointer, it gives the value at that address. Similarly, by dereferencing a pointer to array, we get the array and the name of the array points to the base address. We can confirm that *pointerToGoals gives the array goals if we find its size.

If we dereference it again, we will get the value stored in that address. We can print all the elements using pointerToGoals .

Pointers and pointer to arrays are quite useful when paired up with functions. Coming up in the next section!

1. Call by Value vs Call by Reference

Have a look at the program below:

The function multiply() takes two int arguments and returns their product as int .

In the function call multiply(x,y) , we passed the value of x and y ( of main() ), which are actual arguments , to multiply() .

The values of the actual arguments are passed or copied to the formal arguments x and y ( of multiply() ). The x and y of multiply() are different from those of main() . This can be verified by printing their addresses.

Since we created stored values in a new location, it costs us memory. Wouldn't it be better if we could perform the same task without wasting space?

Call by reference helps us achieve this. We pass the address or reference of the variables to the function which does not create a copy. Using the dereferencing operator * , we can access the value stored at those addresses.

We can rewrite the above program using call by reference as well.

2. Pointers as Function Arguments

In this section, we will look at various programs where we give int , char , arrays and strings as arguments using pointers.

We created four functions, add() , subtract() , multiply() and divide() to perform arithmetic operations on the two numbers a and b .

The address of a and b was passed to the functions. Inside the function using * we accessed the values and printed the result.

Similarly, we can give arrays as arguments using a pointer to its first element.

Since the name of an array itself is a pointer to the first element, we send that as an argument to the function greatestOfAll() . In the function, we traverse through the array using loop and pointer.

Here, we pass in the string name to wish() using a pointer and print the message.

3. Pointers as Function Return

The function multiply() takes two pointers to int . It returns a pointer to int as well which stores the address where the product is stored.

It is very easy to think that the output would be 15. But it is not!

When multiply() is called, the execution of main() pauses and memory is now allocated for the execution of multiply() . After its execution is completed, the memory allocated to multiply() is deallocated.

Therefore, though c ( local to main() ) stores the address of the product, the data there is not guaranteed since that memory has been deallocated.

So does that mean pointers cannot be returned by a function? No!

We can do two things. Either store the address in the heap or global section or declare the variable to be static so that their values persist.

Static variables can simply be created by using the keyword static before data type while declaring the variable.

To store addresses in heap, we can use library functions malloc() and calloc() which allocate memory dynamically.

The following programs will explain both the methods. Both methods return the output as 15.

4. Pointer to Function

Like pointer to different data types, we also have a pointer to function as well.

A pointer to function or function pointer stores the address of the function. Though it doesn't point to any data. It points to the first instruction in the function.

The syntax for declaring a pointer to function is:

The below example will make it clearer.

The declaration for the pointer p to function multiply() can be read as ( following operator precedence ) - p is a pointer to function with two int eger pointers ( or two pointers to int ) as parameters and returning a pointer to int .

Since the name of the function is also a pointer to the function, the use of & is not necessary. Also removing * from the function call doesn't affect the program.

5. Array of Pointers to Functions

We have already seen how to create an array of pointers to int , char , and so on. Similarly, we can create an array of pointers to function.

In this array, every element will store an address of a function, where all the functions are of the same type. That is, they have the same type and number of parameters and return types.

We will modify a program discussed earlier in this section. We will store the addresses of add() , subtract() , multiply() and divide() in an array make a function call through subscript.

The declaration here can be read as - p is an array of pointer to functions with two float pointers as parameters and returning void .

6. Pointer to Function as an Argument

Like any other pointer, function pointers can also be passed to another function, therefore known as a callback function or called function . The function to which it is passed is known as a calling function .

A better way to understand would be to look at qsort() , which is an inbuilt function in C. It is used to sort an array of integers, strings, structures, and so on. The declaration for qsort() is:

qsort() takes four arguments:

  • a void pointer to the start of an array
  • number of elements
  • size of each element
  • a function pointer that takes in two void pointers as arguments and returns an int

The function pointer points to a comparison function that returns an integer that is greater than, equal to, or less than zero if the first argument is respectively greater than, equal to, or less than the second argument.

The following program showcases its usage:

Since a function name is itself a pointer, we can write compareIntegers as the fourth argument.

1. Pointer to Structure

Like integer pointers, array pointers, and function pointers, we have pointer to structures or structure pointers as well.

Here, we have declared a pointer ptrStudent of type struct records . We have assigned the address of student to ptrStudent .

ptrStudent stores the base address of student , which is the base address of the first member of the structure. Incrementing by 1 would increase the address by sizeof(student) bytes.

We can access the members of student using ptrStudent in two ways. Using our old friend * or using -> ( infix or arrow operator ).

With * , we will continue to use the . ( dot operator) whereas with -> we won't need the dot operator.

Similarly, we can access and modify other members as well. Note that the brackets are necessary while using * since the dot operator( . ) has higher precedence over * .

2. Array Of Structure

We can create an array of type struct records and use a pointer to access the elements and their members.

Note that ptrStudent1 is a pointer to student[0] whereas ptrStudent2 is a pointer to the whole array of  10 struct records . Adding 1 to ptrStudent1 would point to student[1] .

We can use ptrStudent1 with a loop to traverse through the elements and their members.

3. Pointer to Structure as an Argument

We can also pass the address of a structure variable to a function.

Note that the structure struct records is declared outside main() . This is to ensure that it is available globally and printRecords() can use it.

If the structure is defined inside main() , its scope will be limited to main() . Also structure must be declared before the function declaration as well.

Like structures, we can have pointers to unions and can access members using the arrow operator ( -> ).

So far we have looked at pointer to various primitive data types, arrays, strings, functions, structures, and unions.

The automatic question that comes to the mind is – what about pointer to pointer?

Well, good news for you! They too exist.

To store the address of int variable var , we have the pointer to int ptr_var . We would need another pointer to store the address of ptr_var .

Since ptr_var is of type int * , to store its address we would have to create a pointer to int * . The code below shows how this can be done.

We can use ptr_ptrvar to access the address of ptr_var and use double dereferencing to access var.

It is not required to use brackets when dereferencing ptr_ptrvar . But it is a good practice to use them. We can create another pointer ptr_ptrptrvar , which will store the address of ptr_ptrvar .

Since ptr_ptrvar is of type int** , the declaration for ptr_ptrptrvar will be

We can again access ptr_ptrvar , ptr_var and var using ptr_ptrptrvar .

If we change the value at any of the pointer(s) using ptr_ptrptrvar or ptr_ptrvar , the pointer(s) will stop pointing to the variable.

Phew! Yeah, we're finished. We started from pointers and ended with pointers (in a way). Don't they say that the curve of learning is a circle!

Try to recap all the sub-topics that you read. If you can recollect them, well done! Read the ones you can't remember again.

This article is done, but you shouldn't be done with pointers. Play with them. Next, you can look into Dynamic Memory Allocation to get to know pointers better .

Stay home, stay safe.

Sachin. Cricket. Dhoni. De Villiers. Buttler. In that order.

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Pointers with Structures in C

C++ Course: Learn the Essentials

C allows programmers to create user-defined data types by grouping data of different types together using struct keywords, such data types are called structures. Like any other data type in C, variables of user-defined structure occupy addresses in a memory block, and pointers can be used to point them. A pointer pointing to a structure is called structure pointer . Structures and pointers in C together help in accessing structure members efficiently.

Structure pointer declaration is similar to declaring a structure variable using the struct keyword followed by the type of structure it will point to. A structure pointer can only hold the address of the structure used at the time of its declaration. Structures and pointers in C together make accessing structure value and passing to functions easier.

Introduction

C allows programmers to create their data type by grouping different types together into one using structures. For example, if we want to store information about our classmates, each student variable should hold information about the student's name, roll number, and grades. No pre-defined data type in C can alone store all this information.

For such cases where we want to store information that no data type can hold, we create our data types using structure to hold the required information.

Different components of a structure are called members for example, in the above case, student name and roll number are members of the structure. Like every other data type, structure variables are stored in memory, and we can use pointers to store their addresses.

Structure pointer points to the address of the structure variable in the memory block to which it points. This pointer can be used to access and change the value of structure members. This way, structures and pointers in C can be used to create and access user-defined data types conveniently.

Before understanding how to use structures and pointers in C together, let us understand how structures are defined and accessed using the variable name.

Syntax to Define a Structure

C struct keyword is used to create a new data type, followed by the structure name. We define different members of the structure inside parenthesis. Once a structure is defined, its name structure_name can be used to declare variables as

To access the value of members of a structure, the dot (.) operator and the structure variable name followed by the member's name are used. For example, if we want the value of member_variable_1 from a structure variable structure_variable syntax will be

structure_variable is the structure variable, and member_variable_1 is one of its members.

The structure members do not occupy space in memory until they are associated with a structure variable.

Now that we know how structures are declared and accessed let us create a structure User that holds information about user name, his role and his age. Here name , role , age are members of the structure User .

Explanation

Here, we have created a user-defined data type, User using the struct keyword, this structure has three members that are name (string), age (int), and role (string). To store information of two users, we have declared two structure variables user_1 and user_2 of type User and later initialized and accessed their value in the main() function using the variable name and dot (.) operator.

Declare a Structure Pointer

declare a structure pointer in c

We now know how structures are defined and used in a C code let us see how we can use structures with pointers to access structure variables and their members. Declaration of structure pointer is similar to the declaration of structure variables, and the only difference is that the pointer name is prefixed with an asterisk * symbol.

Structure pointer in C is declared using the keyword struct followed by structure name to which the pointer will point to followed by pointer name. A structure pointer can only hold the address of a variable of the same structure type used in its declaration.

This way structures and pointers in C are used together to create a pointer pointing to the structure.

Initialization of Structure Pointer

After a structure pointer is declared, we need to initialize it to a variable before using it. To initialize a variable, we need to provide the address of the structure variable using the & operator.

Also, the structure pointer can be initialized during the time of declaration.

Accessing Structure Member Using Pointer

There are two ways to access the values of structure members using pointers -

1. Using asterisk (*) and dot (.) operator with the structure pointer. 2. Using membership or arrow (->) operator.

Let us see some examples to understand how we can access structure members using two different approaches.

Example 1 : Accessing structure members using the dot operator

Here, cp is a pointer that points to the structure variable first_point . This means dereferencing the pointer gives us the content of first_point . Hence, *cp and first_point are functionally identical. To access members of the structure dot operator can be used followed by the member name.

For example , in the example above:

  • (*cp).x refers to member x of first_point .
  • (*cp).y refers to member y of first_point .
Note: Parentheses around the pointer is important because the precedence of dot operator is greater than indirection (*) operator.

Example 2 : Accessing structure members using the arrow operator

Another way to access structure members in C is using the ( -> ) operator. Using this way, we don't need an asterisk and dot operator with the pointer. To access members of the structure using ( -> ) operator we write pointer name with -> followed by the name of the member that is

Let us see an example to understand how we can use an arrow operator to access structure members using structures and pointers in C.

Accessing members of the structure using the membership operator on structure pointer makes code more readable when compared to the other approach.

Example 3 : Structure pointer in function arguments

Here, we have defined function arguments as structure pointers and when we are creating function calls instead of passing structure variables, we are passing reference of them to function. Because reference of variable is passed to the function any changes made on structure members inside function body will persist outside the function scope.

  • Structures in C allow programmers to create user-defined data types by grouping different defined data types into one. Different individual components in the structure are called members.
  • To create a new structure struct keyword is used and similarly, when a structure variable is created struct keyword is used followed by structure type and variable name.
  • Pointer pointing to a structure variable is called a structure pointer, and structures and pointers in C together can be used to access and change the values of members of the structure they are pointing.
  • Declaring a structure pointer is similar to the declaration of a structure variable. To declare a structure pointer struct keyword is used followed by the structure name and pointer name with an asterisk * symbol.
  • Using dot and asterisk operator on a pointer.
  • Using arrow operator ( -> ) on a pointer.
  • Getting started with C Language
  • Best C Programming Courses
  • Awesome Book
  • Awesome Community
  • Awesome Tutorial
  • Awesome YouTube
  • — character classification & conversion
  • Aliasing and effective type
  • Command-line arguments
  • Common C programming idioms and developer practices
  • Common pitfalls
  • Compilation
  • Compound Literals
  • Constraints
  • Create and include header files
  • Declaration vs Definition
  • Declarations
  • Enumerations
  • Error handling
  • Files and I/O streams
  • Formatted Input/Output
  • Function Parameters
  • Function Pointers
  • Generic selection
  • Identifier Scope
  • Implementation-defined behaviour
  • Implicit and Explicit Conversions
  • Initialization
  • Inline assembly
  • Interprocess Communication (IPC)
  • Iteration Statements/Loops: for, while, do-while
  • Jump Statements
  • Linked lists
  • Literals for numbers, characters and strings
  • Memory management
  • Multi-Character Character Sequence
  • Multithreading
  • Pass 2D-arrays to functions
  • Introduction
  • Address-of Operator ( & )
  • Common errors
  • Const Pointers
  • Dereferencing a Pointer
  • Dereferencing a Pointer to a struct
  • Function pointers
  • Initializing Pointers
  • Pointer Arithmetic
  • Pointer to Pointer
  • Polymorphic behaviour with void pointers
  • Same Asterisk, Different Meanings
  • void* pointers as arguments and return values to standard functions
  • Preprocessor and Macros
  • Random Number Generation
  • Selection Statements
  • Sequence points
  • Side Effects
  • Signal handling
  • Standard Math
  • Storage Classes
  • Structure Padding and Packing
  • Testing frameworks
  • Threads (native)
  • Type Qualifiers
  • Undefined behavior
  • Variable arguments

C Language Pointers Dereferencing a Pointer to a struct

Let's say we have the following structure:

We can define MY_STRUCT to omit the struct keyword so we don't have to type struct MY_STRUCT each time we use it. This, however, is optional.

If we then have a pointer to an instance of this struct

If this statement appears at file scope, instance will be initialized with a null pointer when the program starts. If this statement appears inside a function, its value is undefined. The variable must be initialized to point to a valid MY_STRUCT variable, or to dynamically allocated space, before it can be dereferenced. For example:

When the pointer is valid, we can dereference it to access its members using one of two different notations:

While both these methods work, it is better practice to use the arrow -> operator rather than the combination of parentheses, the dereference * operator and the dot . operator because it is easier to read and understand, especially with nested uses.

Another important difference is shown below:

In this case, copy contains a copy of the contents of instance . Changing my_int of copy will not change it in instance .

In this case, ref is a reference to instance . Changing my_int using the reference will change it in instance .

It is common practice to use pointers to structs as parameters in functions, rather than the structs themselves. Using the structs as function parameters could cause the stack to overflow if the struct is large. Using a pointer to a struct only uses enough stack space for the pointer, but can cause side effects if the function changes the struct which is passed into the function.

Got any C Language Question?

pdf

  • Advertise with us
  • Privacy Policy

Get monthly updates about new articles, cheatsheets, and tricks.

  • C Data Types
  • C Operators
  • C Input and Output
  • C Control Flow
  • C Functions
  • C Preprocessors
  • C File Handling
  • C Cheatsheet
  • C Interview Questions

Related Articles

  • Solve Coding Problems
  • How to Get Value of Multidimensional Array in C?
  • How to Check if Empty Array in C?
  • How to Empty a Char Array in C?
  • How to Declare 3-Dimensional Arrays in Wiring in C?
  • Sign Extend a Nine-Bit Number in C
  • C nanosleep() Function
  • tolower() Function in C
  • getchar Function in C
  • Char Comparison in C
  • How to Hide the Console Window of a C Program?
  • Using goto for Exception Handling in C
  • Why can't a const variable be used to define an Array's initial size in C?
  • Is sizeof for a struct equal to the sum of sizeof of each member?
  • C - Parallel for loop in OpenMP
  • Difference between Structure and Array in C
  • Array of Pointers in C
  • Power BI - Create Drill Up and Drill Down Reports
  • Power BI - Drill through Filters
  • How to remove blank lines from a .txt file in Python

How to Declare and Initialize an Array of Pointers to a Structure in C?

Prerequisite:

  • Structure in C

In C language, arrays are made to store similar types of data in contiguous memory locations. We can make arrays of either primitive data types, like int, char, or float, or user-defined data types like Structures and Unions. We can also make arrays of pointers in C language. Today we will learn how to create arrays of Structure Pointers or pointers-to-structure in C language, both Statically and Dynamically.

Creating structure pointer arrays(Static Arrays) 

I). 1d arrays.

We can statically allocate memory for 1D and 2D arrays in C language. The static memory is allocated in the stack memory. We can do static memory allocation of structure pointers in the following ways: 

Step 1 – Declaring and initializing 1D arrays

Let’s say we have a structure “node”, and we created different pointers to this structure. Now, to make a 1D array of those pointers in static memory, we must follow the following syntax:

We can access the pointers inside our array just like we access normal array elements. There is just a little bit of modification that we need to use the arrow operator to access the data present inside our structure pointer.

Step 2 – Accessing the pointers within the array

In the above example, we have a structure called a “node”. We made 2 pointers to that structure namely- ‘structure_ptr1’ and ‘structure_ptr2’ and initialized them. After this, we declared an array – “struct_array” of size 2 and initialized it with our struct pointers.

ii). 2D Arrays

Step 1 –  Declaring and initializing 2D arrays

Step 2- Accessing elements of our 2D array

So this is how we declare and initialize a 2D array of structure pointers. Here, we use the same structure – “node” and made 4 pointers for it which were – “structure_ptr1”, “structure_ptr2”, “structure_ptr3” and “structure_ptr4”. After that, we declared a 2D array of size – 2 X 2 namely –  structure_array.

Note: The data type of the array must be the same as that of the structure followed by * (asterisk) sign, which signifies array of structure pointers.

Creating structure pointer arrays (Dynamic Arrays)

As we know that in C language, we can also dynamically allocate memory for our variables or arrays. The dynamically allocated variables or arrays are stored in Heap. To dynamically allocate memory for structure pointer arrays, one must follow the following syntax:

Notice the double-pointer after the structure name and during typecasting malloc to the structure. This double pointer is necessary because we are pointing to an array of structure pointers, and we know that we use double pointers if we want to point to another pointer. 

You can clearly see in the above code how we have initialized the structure pointer array at the end. The difference between this and static arrays is just that static arrays are allocated in stack memory, while these are allocated in heap memory. And so, you can resize these arrays anytime you want.

We can access these arrays just like we did with the static ones so there is no change in syntax for that.

Note: In case of static arrays, you can initialize the array all at once during the time of initialization like –  node *struct_arr [10 ] = { struct_ptr1, struct_ptr2, struct_ptr3 ….. }, whereas dynamically allocated arrays need to be initialized index-by-index.

ii).  2D Arrays

To allocate dynamic 2D arrays of pointers, first, we will create a 1D array dynamically and then will create sub-arrays at each index of that 1D array (basically an array of arrays containing pointers). Now, this requires the use of triple-pointers. We will understand this with the help of a diagram:

Dynamic Pointer Array of Structures

Explanation of the above figure:

  • *** st_arr is a triple pointer used to access the 2D array of structure pointers. Now, it is made a triple pointer because we are accessing those arrays, whose each element has a pointer to another array (subarray). And each element of those sub-arrays, have a pointer to the structure.
  • Each index of st_arr[i] contains sub-arrays.
  • Each index of sub-arrays – st_arr[i][j] contains a pointer to the structure.
  • st_ptr is a pointer to the structure.
  • In the above code, as we have already discussed that triple pointer was used to point to an array of arrays containing structure pointers.
  • In the second step, we used double pointers as we had to use a pointer, which could point to an array of structure pointers.
  • In the third step, we initialized our dynamic 2D array, just like the static 2D array, index by -index.

Please Login to comment...

  • C-Structure & Union
  • Technical Scripter 2022
  • Technical Scripter

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Popular Tutorials

Popular examples, learn python interactively, go introduction.

  • Golang Getting Started
  • Go Variables
  • Go Data Types
  • Go Print Output
  • Go Take Input
  • Go comments
  • Go Operators
  • Go Type Casting

Go Flow Control

  • Go Boolean Expression
  • Go if...else
  • Go for Loop
  • Go while Loop
  • Go break and continue

Go Data Structures

  • Go Functions
  • Go Variable Scope
  • Go Recursion
  • Go Anonymous Function
  • Go Packages

Go Pointers & Interface

Go Pointers

  • Go Pointers and Functions
  • Go Pointers to Struct

Go Interface

  • Go Empty Interface
  • Go Type Assertions

Go Additional Topics

  • Go defer, panic, and recover

Go Tutorials

Go pointers to structs.

The struct types store the variables of different data types and we use the struct variable to access the members of the struct.

In Go, we can also create a pointer variable of struct type.

Before you learn about pointers to struct, make sure to know about:

  • Go Pointer to Struct

Suppose we have a struct like this

Now, let's create a struct variable of Person type.

Similar to this, we can also create a pointer variable of struct type.

We can now assign the address of the struct variable to this pointer variable. Let's see an example.

In the above example, we have created a struct variable person1 that initialized the struct members; name to John and age to 25 .

We have also created a pointer variable of the struct type that stores the address of person1 .

Since the ptr now stores the address of person1 , we get &{John 25} as the output while printing ptr .

Note : We can also create struct-type pointers and assign variable addresses in the same line. For example,

Access struct using pointer in Golang

We can also access the individual member of a struct using the pointer. For example,

In the above example, we have used the struct type pointer to access struct members:

  • ptr.name - gives the value of the name member
  • ptr.age - gives the value of the age member

Here, we have used the dot operator to access the struct members using the pointer.

Note: We can also use the dereference operator, * to access the members of struct. For example,

Change the Struct member in Go

Similarly, we can also use the pointer variable and the dot operator to change the value of a struct member. For example,

In the above example, notice the line

Here, we have changed the value of the struct member temperature to 25 using the pointer variable ptr .

Table of Contents

  • Introduction
  • Access struct using pointer
  • Change the Struct member

Sorry about that.

Related Tutorials

Programming

IMAGES

  1. C Language Pointer to Structure

    struct assign to pointer

  2. Arrow Operator For Pointers To Structs

    struct assign to pointer

  3. C++ : C++ Pointers. How to assign value to a pointer struct?

    struct assign to pointer

  4. Pointer to Structure Variable

    struct assign to pointer

  5. How to implement function Pointer in C Struct

    struct assign to pointer

  6. Dive Into Systems

    struct assign to pointer

VIDEO

  1. Extra Problems 1 Pointers double pointers tracing inside function

  2. Struct vs Enum......#coding #programming #rust #js #struct #enum

  3. 8.2 Pointer to struct, continued

  4. Tugas Pertemuan 1 (Struct dan Pointer)

  5. 8

  6. C PROGRAMMING

COMMENTS

  1. Pointer to a Structure in C

    There are two ways of accessing members of structure using pointer: Using indirection ( *) operator and dot (.) operator. Using arrow ( ->) operator or membership operator. Let's start with the first one. Using Indirection (*) Operator and Dot (.) Operator

  2. c

    May 11, 2015 at 6:15 there is the probability that the code will not work. This is because the code is trying to pass complete struct objects. In general only a pointer to a struct should be passed. Also it will probably fail because the struct being returned by person_create () is on the local stack. Only intrinsic objects pass properly.

  3. C structs and Pointers (With Examples)

    Run Code In this example, the address of person1 is stored in the personPtr pointer using personPtr = &person1;. Now, you can access the members of person1 using the personPtr pointer. By the way, personPtr->age is equivalent to (*personPtr).age personPtr->weight is equivalent to (*personPtr).weight Dynamic memory allocation of structs

  4. Structure Pointer in C

    A structure pointer is defined as the pointer which points to the address of the memory block that stores a structure known as the structure pointer. Complex data structures like Linked lists, trees, graphs, etc. are created with the help of structure pointers.

  5. CS31: Intro to C Structs and Pointers

    Pointers Pointers and Functions C style "pass by referece" Dynamic Memory Allocation (malloc and free) Pointers to Structs Part 1 contains C basics, including functions, static arrays, I/O Links to other C programming Resources C Stucts and Pointers This is the second part of a two part introduction to the C programming language.

  6. C Pointers

    To declare a pointer, we use the ( * ) dereference operator before its name. Example int *ptr; The pointer declared here will point to some random memory address as it is not initialized. Such pointers are called wild pointers. 2. Pointer Initialization

  7. Pointers in C Explained

    Suppose we dereference a wild pointer and assign a value to the memory address it is pointing at. This will lead to unexpected behaviour since we will write data at a memory block that may be free or reserved. ... Pointer to Structure. Like integer pointers, array pointers, and function pointers, we have pointer to structures or structure ...

  8. C++ Pointers to Structure

    C++ Pointers to Structure A pointer variable can be created not only for native types like ( int, float, double etc.) but they can also be created for user defined types like structure. If you do not know what pointers are, visit C++ pointers. Here is how you can create pointer for structures:

  9. c

    3,592 9 46 82 2 Such expressions ( fp=&f1;) can not write outside of function. - BLUEPIXY Nov 3, 2014 at 10:47 Add a comment 2 Answers Sorted by: 3 struct fraction *fp; struct fraction f1,f2; fp=&f1; is indeed similar to

  10. Pointers and Structures in C

    Pointer pointing to a structure variable is called a structure pointer, and structures and pointers in C together can be used to access and change the values of members of the structure they are pointing. Declaring a structure pointer is similar to the declaration of a structure variable. To declare a structure pointer struct keyword is used ...

  11. C struct (Structures)

    Nested Structures. You can create structures within a structure in C programming. For example, struct complex { int imag; float real; }; struct number { struct complex comp; int integers; } num1, num2; Suppose, you want to set imag of num2 variable to 11. Here's how you can do it: num2.comp.imag = 11;

  12. C

    The pointer to a pointer in C is used when we want to store the address of another pointer. The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double-pointers. We can use a pointer to a pointer to change the values of normal ...

  13. C Language Tutorial => Dereferencing a Pointer to a struct

    The variable must be initialized to point to a valid MY_STRUCT variable, or to dynamically allocated space, before it can be dereferenced. For example: MY_STRUCT info = { 1, 3.141593F }; MY_STRUCT *instance = &info; When the pointer is valid, we can dereference it to access its members using one of two different notations: While both these ...

  14. How to Declare and Initialize an Array of Pointers to a Structure in C

    Step 1 - Declaring and initializing 1D arrays Let's say we have a structure "node", and we created different pointers to this structure. Now, to make a 1D array of those pointers in static memory, we must follow the following syntax: Syntax:

  15. Go Pointers to Structs (With Examples)

    type Person struct { name string age int } Now, let's create a struct variable of Person type. person1 := Person {"John", 25} Similar to this, we can also create a pointer variable of struct type. var ptr *Person. We can now assign the address of the struct variable to this pointer variable. Let's see an example.

  16. Pointers as Member of Structure in C

    How to assign a value to a pointer member of structure in C Before assigning a value to a pointer you should assign a valid memory. If you don't assign a valid memory, you will get the undefined behavior. There is two way to access the value of a pointer member of a structure in C. 1. Using the structure variable

  17. c

    The parameter of our push () function takes a struct node as a pointer to pointer so it is passed as a reference, not an actual copy. So the first pointer of our struct node** headref is just a pointer to the memory location of our head node and the second pointer points to the value, which is the next memory location that the head node points to.

  18. Is assigning a struct variable to itself (via pointer dereferencing

    struct Struct { int member; }; int main() { struct Struct s, *p1, *p2; s.member = 1234; p1 = p2 = &s; *p1 = *p2; // is this allowed? } I mainly ask because in this SO post and this SO post a number of answers state that struct assignment is more or less equivalent to memcpy, and some compilers even generate a memcpy call for the assignment ...