Pointers in C – Part 1

In this tutorial, we are going to see the pointers in C programming. This is a very big concept. So, we have split this into two parts. Please check out the pointers part 2

You can also read, Different types of pointers, bitwise operators, and embedded interview topics.

Pointers in C

Introduction

The concept of pointers is one of the most powerful fundamentals of the C/C++ language. Through pointers, a developer can directly access memory from his/her code which makes memory related operations very fast. But, as always, with great power comes great responsibility. A developer has to very carefully make use of pointers in order to avoid some problems that can be a nightmare to debug.

What are Pointers?

Different from other normal variables which can store values, pointers are special variables that can hold the address of a variable. Since they store the memory address of a variable, the pointers are very commonly said to “point to variables”. Let’s try to understand the concept.

As shown in the above diagram: 

  • A normal variable ‘var’ has a memory address of 1001 and holds a value of 50.
  • A pointer variable has its own address 2047 but stores 1001, which is the address of the variable ‘var’.

How to Declare a Pointer?

A pointer is declared as :

<pointer type> *<pointer-name>;

In the above declaration :
1. Pointer-type: It specifies the type of pointer. It can be int, char, float, etc. This type specifies the type of variable whose address this pointer can store.

2. Pointer-name: It can be any name specified by the user.  An example of a pointer declaration can be :

char *chptr;

In the above declaration, ‘char’ signifies the pointer type, chptr is the name of the pointer while the asterisk ‘*’ signifies that ‘chptr’ is a pointer variable.

How to initialize a Pointer?

A pointer is initialized in the following way :

<pointer declaration(except semicolon)> = <address of a variable>

                  (OR)

<pointer declaration>
<name-of-pointer> = <address of a variable>

Note that the type of variable above should be the same as the pointer type. (Though this is not a strict rule but this should be kept in mind). For example :

char ch = 'c';
char *chptr = &ch; //initialize

      OR

char ch = 'c';
char *chptr;
chptr = &ch //initialize

In the code above, we declared a character variable ch which stores the value ‘c’. Now, we declared a character pointer ‘chptr’ and initialized it with the address of variable ‘ch’. Note that the ‘&’ operator is used to access the address of any type of variable.

How to Use a Pointer?

A pointer can be used in two contexts.

Context 1: For accessing the address of the variable whose memory address the pointer stores. Again consider the following code :

char ch = 'c';
char *chptr = &ch;

Now, whenever we refer to the name ‘chptr’ in the code after the above two lines, then the compiler would try to fetch the value contained by this pointer variable, which is the address of the variable (ch) to which the pointer points. i.e. the value is given by ‘chptr’ would be equal to ‘&ch’.

For example :

char *ptr = chptr;

The value held by ‘chptr’ (which in this case is the address of the variable ‘ch’) is assigned to the new pointer ‘ptr’.

Context 2: For accessing the value of the variable whose memory addresses the pointer stores.

char ch = 'c';
char t;
char *chptr = &ch;
t = *chptr;

We see that in the last line above, we have used ‘*’ before the name of the pointer. What does this asterisk operator do? Well, this operator when applied to a pointer variable name(like in the last line above) yields the value of the variable to which this pointer points. This means, in this case, ‘*chptr’ would yield the value kept at the address held by chptr. Since ‘chptr’ holds the address of variable ‘ch’ and value of ‘ch’ is ‘c’, so ‘*chptr’ yeilds ‘c’.

When used with pointers, the asterisk ‘*’ operator is also known as ‘value of’ operator. An Example of C Pointers Consider the following code : 

#include <stdio.h>
int main(void) 
{ 
    char ch = 'c'; 
    char *chptr = &ch; 
    int i = 20; 
    int *intptr = &i; 
    float f = 1.20000; 
    float *fptr = &f; 
    char *ptr = "I am a string"; 
    printf("\n [%c], [%d], [%f], [%c], [%s]\n", *chptr, *intptr, *fptr, *ptr, ptr); 
    return 0; 
}

OUTPUT :

$ ./pointers

[c], [20], [1.200000], [I], [I am a string]

To debug a C program, use gdb. The above code covers all the common pointers. The first three of them are very trivial to understand. So let’s concentrate on the fourth one. In the fourth example, a character pointer points to a string. In C, a string is nothing but an array of characters. So, we have no staring pointers in C. It’s the character pointers that are used in the case of strings too.

Now, coming to the string, when we point a pointer to a string, by default it holds the address of the first character of the string. Let’s try to understand it better.

The string, ‘I am String’ in memory is placed as :

1001   1002   1003   1004   1005   1006   1007   1008   1009   1010  1011   1012

  I             a      m             S      t      r      i      n     g     \0

Since characters occupy one byte each, so they are placed like above in the memory. Note the last character, it’s a null character that is placed at the end of every string by default in C. This null character signifies the end of the string.

Now coming back to the point, any character pointer pointing to a string, stores the address of the first character of the string. In the code above, ‘ptr’ holds the address of the character ‘I’ ie 1001. Now, when we apply the ‘value of’ operator ‘*’ to ‘ptr’, we intend to fetch the value at address 1001 which is ‘I’ and hence when we print ‘*ptr’, we get ‘I’ as the output. Also, If we specify the format specifier as ‘%s’ and use ‘ptr’ (which contains the starting address of the string), then the complete string is printed using printf. The concept is that %s specifier requires the address of the beginning byte of string to display the complete string, which we provided using ‘ptr’ (which we know holds the beginning byte address of the string). This we can see as the last print in the output above.

Pointers as Structure Objects

Consider the following code :

#include<stdio.h>

struct st { 
    int a; 
    char ch; 
};

int main(void) 
{ 
    struct st obj; 
    struct st *stobj = &obj;

    stobj->a = 5; 
    stobj->ch = 'a';

    printf("\n [%d] [%c]\n", stobj->a, stobj->ch); 
    return 0; 
}

OUTPUT:

$ ./pointers

[5] [a]

In the above code, we have declared a pointer stobj of type ‘struct st’. Now, since the pointer type is structure, the address it points to has to be of a ‘struct st’ type variable (which in this case is ‘obj’). Other interesting part is how structure elements are accessed using pointer variable ‘stobj’. Yes, When dealing with pointer objects, its a standard to use arrow operator -> instead of ‘.’ operator(which would have been used, had we used ‘obj’ to access the structure elements).

This is the pointer’s basic tutorial. In our part 2 tutorial we will see the Advanced concepts of  Pointers in C. Please see the Pointers Part 2 also.

You can also read the below tutorials.

Linux Device Driver TutorialsC Programming Tutorials
FreeRTOS TutorialsNuttX RTOS Tutorials
RTX RTOS TutorialsInterrupts Basics
I2C Protocol – Part 1 (Basics)I2C Protocol – Part 2 (Advanced Topics)
STM32 TutorialsLPC2148 (ARM7) Tutorials
PIC16F877A Tutorials8051 Tutorials
Unit Testing in C TutorialsESP32-IDF Tutorials
Raspberry Pi TutorialsEmbedded Interview Topics
Reset Sequence in ARM Cortex-M4BLE Basics
VIC and NVIC in ARMSPI – Serial Peripheral Interface Protocol
Bootloader Tutorials
4.7 3 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
1
0
Would love your thoughts, please comment.x