w3resource

C - Pointers

What is a Pointer?

A pointer is a variable that stores the address of a memory location. Pointers are used to store the addresses of other variables or memory items. A pointer is extremely helpful for another type of parameter passing, commonly referred to as pass by address. Pointers are essential for dynamic memory allocation.

C Program: C Pointer

The following are some common uses for pointers:

  • To access dynamic data structures such as linked lists, trees, and queues.
  • To access elements of an array or members of a structure.
  • To access an array of characters as a string.
  • To pass the address of a variable to a function.

Declaring a pointer variable

Pointer declarations use the * operator. They follow this format:

  • int n; // declaration of a variable n
  • int * ptr; // declaration of a pointer, called p

In the example above, ptr is a pointer, and its type will be specifically be referred to as "pointer to int", because it stores the address of an integer variable. We also can say its type is: int*

The type is important. While pointers are all the same size, as they just store a memory address, we have to know what kind of thing they are pointing to.

  • double * dptr; // a pointer to a double
  • char * ch; // a pointer to a character
  • float * fptr; // a pointer to a float

Sometimes the notation is confusing, because different textbooks place the * differently. The three following declarations are equivalent:

  • int *ptr;
  • int* ptr;
  • int * ptr;

Above three of these declare the variable ptr as a pointer to an int.

Another tricky aspect of notation: Recall that we can declare multiple variables on one line under the same type, like this:

  • int x, y, z; // three variables of type int

Since the type of a "pointer-to-int" is (int *), we might ask, does this create three pointers?

  • int* a, b, c;

This is not three pointers. Instead, this is one pointer and two integers. If you want to create multiple pointers on one declaration, you must repeat the * operator each time:

  • int * a, * b, * c; // three pointers-to-int
  • int * a, b, c; // a is a pointer, b and c are integers.

Assigning to pointer variables

A variable with a pointer value allocates space to hold the pointer, but not to hold anything it points to. As with any other variable in C, a pointer-valued variable will initially contain garbage - in this case, the address of a location which may or may not contain some useful information. A pointer variable is initialized by assigning it the address of something that already exists. The & (address-of) operator is commonly used to accomplish this:

  • int x; /* an int variable */
  • int *ptr; /* a pointer to an int */
  • ptr = &x; /* p now points to n */

Operators

  • *ptr -- returns the value pointed to by ptr
  • &x -- returns the address of variable x

Using a pointer

There are two ways to use pointer variables:

a) To get their value (a pointer) –

  • int x; /* an int variable */
  • int *a; /* a pointer to an int */
  • int *b; /* another pointer to an int */
  • a = &x; /* a now points to x */
  • b = a; /* b now points to x as well */

b) In most cases, however, you will want to work with the value stored at the location indicated. You can do this by using the * (dereference) operator:

  • int x; /* Declares an integer variable named x */
  • int *a; /* Declares a pointer to an integer named a */
  • a = &x; /* Assigns the address of x to the pointer a; a now points to x */
  • *a = 2; /* Updates the value that a points to (which is x) to 2 */
  • *a = *a + *a; /* Doubles the value of x by adding it to itself; sets x to 4 */

Example:

C Program: C Pointer Explanation

A pointer in C is always a pointer to a particular data type:
int*, double*, char*, etc.

Integer pointer:

An integer pointer stores only the address of an integer variable.

Syntax:

int *p;    // *p is the name of pointer

Example: Integer pointer

Code:

#include<stdio.h>
int main()
{
   int x = 25;
   int *p;
   p = &x;
   printf("Value of x is: %d\n",x);
   printf("Value stored at pointer p is: %d\n",*p);
   printf("Address of the variable x is: %x\n",&x); 
   printf("p points to the address = %x\n",p);
   printf("Address of the pointer p = %x\n",&p);
   return 0;
}

Output:

Value of x is: 25
Value stored at pointer p is: 25
Address of the variable x is: 62fe1c
p points to the address = 62fe1c
Address of the pointer p = 62fe10

Character pointer:

A character pointer stores only the address of a character variable.

Syntax:

char *p; // *p is the name of pointer

Example: Charcter pointer

Code:

#include<stdio.h>
int main()
{
   char ch = 'W',*p;
   p = &ch;
   printf("Value of ch is: %c\n",ch);
   printf("Value stored at pointer p is: %c\n",*p);
   printf("Address of the variable ch is: %x\n",&ch); 
   printf("p points to the address = %x\n",p);
   printf("Address of the pointer p = %x\n",&p);
   return 0;
}

Output:

Value of ch is: W
Value stored at pointer p is: W
Address of the variable ch is: 62fe1f
p points to the address = 62fe1f
Address of the pointer p = 62fe10

Floating pointer:

An integer pointer stores only the address of an integer variable.

Syntax:

float *p;    // *p is the name of pointer

Code:

#include<stdio.h>
int main()
{
   float x = 125.23;
   float *p;
   p = &x;
   printf("Value of x is: %f\n",x);
   printf("Value stored at pointer p is: %f\n",*p);
   printf("Address of the variable x is: %x\n",&x); 
   printf("p points to the address = %x\n",p);
   printf("Address of the pointer p = %x\n",&p);
   return 0;
}

Output:

Value of x is: 125.230003
Value stored at pointer p is: 125.230003
Address of the variable x is: 62fe1c
p points to the address = 62fe1c
Address of the pointer p = 62fe10

Printing pointers

We can print a pointer value using printf() function with the %p format specifier. Following program prints out some pointer values:

Code:

#include <stdio.h>
#include <stdlib.h>

int n = 0;   /* a global variable*/
int main(int argc, char **argv) 
{
    char str[6] = "Hello"; /* String variable*/
    char *cptr;
    cptr = str;
    static int st;  /* static local variable */
    int at;         /* automatic variable */
    int *ptr;       /* pointer variable */
    printf("&n    = %p\n", (void *) &n);
    printf("&st   = %p\n", (void *) &st);
    printf("&at   = %p\n", (void *) &at);
    printf("&ptr  = %p\n", (void *) &ptr);
    printf("&cptr = %p\n", (void *) &cptr);
    free(ptr);
    return 0;
}

Output:

&n    = 0000000000407030
&st   = 0000000000407034
&at   = 000000000062FE04
&ptr  = 000000000062FDF8
&cptr = 000000000062FE08

Manipulating Pointers

In the preceding code snippet we saw, ptr was pointing to x i.e. ptr contained the address of the location in which x is stored. The data item represented by x can be accessed by using the unary operator *, which is also termed as the indirection operator can be used only on pointers. Consider the following example:

int x,y,z, *ptr;
	x=34;
	y=67;
	z=20;
	printf ("x=%d , y=%d", x , y);
	/* output: x=34 , y=67 */
	ptr = &x;             /* ptr now points to x */
	y = *ptr;            /* y gets the value of variable to which ptr points i.e x*/
	printf ("x=%d,  y=%d",   x,  y);
	/* output: x=34 , y=34 */
	z =*ptr + 1;         /* z  gets the value 35 */
	*ptr  =  0;         /* x gets the value 0 */

The null pointer:

There is a special pointer called null pointer whose value is 0. You can assign 0 into a pointer:

  • ptr = 0;

Null pointer is the only integer literal that can be assigned to a pointer, and arbitrary numbers may not be assigned to them:

  • int * p = 0; // Assignment of null pointer to p
  • int * q;
  • q = 0; // okay. null pointer again.
  • int * x;
  • z = 125; // [Error] invalid conversion from 'int' to 'int*'
  • double * dptr;
  • dptr = 10; //invalid conversion from 'int' to 'double*'

Null pointers are never valid targets, however a segmentation fault will occur if you attempt to dereference the null pointer. In most cases, a null pointer is used to initialize pointers until their values are known before they are used.

Pointers of the same type:

A pointer can also be assigned to another pointer of the same type:

  • int * p1, * p2; // Two pointers of type int
  • p1 = p2; // Assign one to the other Now they both point to the same place

A pointer to a different type is treated by C as a different type:

  • int * pi; // Pointer to int
  • char * pc; // Pointer to char
  • double * pd; // Pointer to double

Said three pointer variables (pi, pc ,pd) are all considered to have different types:

  • pi = pd; // Invalid
  • pd = pc; // Invalid
  • pi = pc; // Invalid

Previous: Arrays in C
Next: C Pointers and Functions



Follow us on Facebook and Twitter for latest update.