What are Array of Pointers in C- C Programming Course in Telugu

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

Free C Programming Course · Chapter 8 · Pointers

Array of Pointers in C

Understand the array of pointers in C: how to declare it, fill it, dereference it and pass it to functions. A hands-on lesson in our free C tutorial on embedded C programming, with string tables and sensor probe lists.

1
Asterisk placed before the array name
24
Bytes for 3 pointers on 64-bit
3
Real-world firmware patterns covered

What You Will Learn

After pointers, arrays and multi-dimensional arrays, it is time to combine two ideas. An array of pointers in C is simply an array whose elements are pointers. It sounds like a small step, yet it is behind menu tables, command dispatchers, peripheral register lists and every table of strings in your firmware. This lecture of our free embedded C course shows you how to declare one, read and write through it, and hand it to a function safely.

  • The declaration syntax and a simple rule for reading it correctly.
  • How each element holds the address of some other variable, and how to reach the value through it.
  • How to build a table of strings, the most common array of pointers in embedded programs.
  • How to pass the table to a helper function and update the original variables.
  • Which memory the pointers live in, and what to watch out for.

Prerequisites

You should know how to declare a pointer, take an address with &, and dereference with *. You also need the array fundamentals from earlier chapters and the lecture on passing arrays to functions.

What Is an Array of Pointers in C?

An ordinary array holds values, such as integers. An array of pointers holds addresses. Each element is a pointer variable and can store the address of any variable of the matching type. The declaration looks like an array declaration with one extra asterisk placed before the array name:

datatype *array_name[size];

For example, int *probe[3]; declares probe as an array of three pointers to int. A reliable way to read this: start at the name and go right first, then left. probe is an array of 3 (the brackets bind first) of pointers (the asterisk) to int. This reading order will matter a lot in the next lecture, where we compare it with a very similar-looking declaration.

An Array of Three Pointers

probe[0]→temp_c = 36
probe[1]→vbat_mv = 3300
probe[2]→rpm = 1500
The array stores three addresses; the three integers live elsewhere and need not be neighbours.

Notice how different this is from an array of integers. The three integers can sit anywhere in memory, in any order, even in different functions’ stack frames. The pointer array is just an index card file that records where each of them lives.

Build and Run: Sensor Probe Table

This original program models a tiny telemetry unit with three readings kept in separate variables. A pointer array lets us treat them as a list. Save it as ep_ptr_array.c.

#include <stdio.h>
#include <stddef.h>

static void trim_all(int *const list[], size_t n, int amount)
{
    for (size_t i = 0; i < n; i++) {
        *list[i] -= amount;
    }
}

int main(void)
{
    int temp_c   = 36;
    int vbat_mv  = 3300;
    int rpm      = 1500;

    int *probe[3] = { &temp_c, &vbat_mv, &rpm };

    printf("sizeof(probe)    = %zu bytes (3 pointers)\n", sizeof(probe));
    printf("sizeof(probe[0]) = %zu bytes (one pointer)\n", sizeof(probe[0]));

    for (int i = 0; i < 3; i++) {
        printf("*probe[%d] = %d\n", i, *probe[i]);
    }

    *probe[1] -= 100;
    printf("after *probe[1] -= 100 -> vbat_mv = %d\n", vbat_mv);

    trim_all(probe, 3, 10);
    printf("after trim_all(10)   -> %d, %d, %d\n", temp_c, vbat_mv, rpm);
    printf("probe[2] == &rpm ? %s\n", probe[2] == &rpm ? "yes" : "no");

    const char *state_name[] = { "IDLE", "RUN", "FAULT" };
    size_t count = sizeof(state_name) / sizeof(state_name[0]);
    for (size_t s = 0; s < count; s++) {
        printf("state %zu = %s\n", s, state_name[s]);
    }
    return 0;
}
gcc -std=c11 -Wall -Wextra -o ep_ptr_array ep_ptr_array.c
./ep_ptr_array

Expected output on a 64-bit Linux machine:

sizeof(probe)    = 24 bytes (3 pointers)
sizeof(probe[0]) = 8 bytes (one pointer)
*probe[0] = 36
*probe[1] = 3300
*probe[2] = 1500
after *probe[1] -= 100 -> vbat_mv = 3200
after trim_all(10)   -> 26, 3190, 1490
probe[2] == &rpm ? yes
state 0 = IDLE
state 1 = RUN
state 2 = FAULT

Reading Through an Array of Pointers

The expression probe[i] is the i-th pointer, and *probe[i] is the integer it points to. The subscript binds tighter than the star, so no parentheses are needed. Writing through it works the same way: *probe[1] -= 100 changes vbat_mv itself, as the output line shows. The array never copies the values; it only remembers where they are.

What the sizes tell you

Three pointers take 24 bytes on a 64-bit system, so sizeof(probe) is 24 and each element is 8. On a 32-bit microcontroller the figures would be 12 and 4. The size of the array depends only on the number of pointers and the pointer width, never on what they point to.

Arrays of Pointers to Strings

The second half of the program shows the most common use of an array of pointers in firmware: a table of strings. The declaration const char *state_name[] creates an array of pointers, each pointing at the first character of a string literal. The element count comes from the usual division of total size by element size, which is valid here because state_name is a real array in its own scope.

This is far better than a rectangular array of characters when the strings have different lengths. A rectangular layout must reserve space for the longest string in every row; a pointer table stores only one address per string, and the strings themselves occupy just the bytes they need.

FeatureArray of pointers to strings2-D char array
Declarationconst char *names[]char names[3][6]
Memory useOne pointer per string plus the textFixed width for every row
Mixed lengthsEfficientWastes space
Modifying a stringNot allowed for literalsAllowed (it is your own buffer)

Where the Table Lives on a Microcontroller

For firmware, write the table as static const char *const names[] = { ... };. The second const makes the pointers themselves read-only, so the whole table can be placed in flash instead of RAM. That saves precious RAM on small devices and prevents accidental edits at run time. In our demo the table is a local variable, which is fine for learning on a PC.

Passing an Array of Pointers to a Function

The helper trim_all() receives int *const list[]. As with any array parameter, the brackets turn into a pointer, so the real type is int *const *list: a pointer to a constant pointer to int. The const says that the function will not re-point any list entry, but it may still change the integers they refer to. The function receives the array of pointers by base address, plus the count, and loops through using *list[i].

Compare that with the earlier lectures. The array being passed now has pointer elements, so the parameter has one more level of indirection, but the story is identical: only the base address of the table travels to the callee.

Two Levels of Indirection in trim_all()

list→probe[0]→temp_c
list + 1→probe[1]→vbat_mv
list + 2→probe[2]→rpm

Real-World Use Cases in Embedded C Programming

  • Menu systems: a table of label strings for an LCD, indexed by menu position.
  • Error and state names: convert numeric codes to readable log text with one array lookup.
  • Peripheral lists: an array of pointers to hardware register blocks so one loop can configure several identical UARTs or timers.
  • Command parsers: a table of command names, kept next to a matching table of handlers.
  • Command-line arguments: argv in a Linux program is exactly an array of pointers to strings.

Common Mistakes and Troubleshooting

MistakeResultFix
Dereferencing an uninitialised elementCrash or wild writeInitialise every entry, or set unused ones to NULL and test before use
Storing the address of a local variable that goes out of scopeDangling pointer, garbage values laterPoint only at variables that outlive the table
Writing through a string literal pointerFault, as literals sit in read-only memoryUse a char array if you need to edit text
Writing probe[i] when you meant *probe[i]You get an address, not the valueDereference to reach the target
Printing pointers with %dWrong output on 64-bitUse %p with a (void *) cast

Best Practices, Performance and Security

  • Mark tables of strings static const char *const so they stay in flash and cannot be modified.
  • Terminate a pointer list with NULL when its length is not passed separately, the way argv works.
  • Check an index against the element count before using it, especially when it comes from a received command.
  • Prefer a lookup table to a long if–else or switch chain when you map numbers to text; it is smaller and faster to read.
  • Performance: each access costs one extra memory read, to fetch the pointer before following it, which is negligible on modern cores.

Key Takeaways

  • int *probe[3] is an array of three pointers to int.
  • *probe[i] reaches the variable that element i points to.
  • Tables of strings are the classic array of pointers in firmware.
  • The array holds addresses only; keep the targets alive as long as the table is in use.

Conclusion

An array of pointers in C is a compact way to organise things that live in scattered places: individual variables, strings of different lengths, register blocks, handlers. Declare it with the asterisk before the name, dereference through the subscripted element, and pass it to functions as a pointer to its first element together with a count. In the final lecture of this block we place it next to its look-alike, the pointer to an array, and finish with a quiz and interview questions.

Suggested Images for This Lecture

  • Diagram of three pointer cells pointing at separate variables. Alt text: “array of pointers in C with each element pointing to a different variable”.
  • Terminal output screenshot of the probe table demo. Alt text: “free embedded C course array of pointers in C program output”.
  • Illustration of a string table in flash. Alt text: “embedded C programming array of pointers to strings stored in flash memory”.

Frequently Asked Questions

What is an array of pointers in C?

It is an array whose elements are pointer variables, each able to hold the address of a variable of the declared type, for example int *probe[3].

How do I read the value that an element points to?

Use *probe[i]. The subscript selects the pointer, and the star follows it to the target.

Why is an array of pointers good for strings?

Each element stores one address, so strings of different lengths do not waste space the way a fixed-width character matrix would.

Can the pointers in the array change at run time?

Yes, unless you declare them const. You can re-point any element to another variable, which is useful for runtime-configurable tables.

What is the parameter type when I pass such an array to a function?

Pointer to pointer. For example int *list[] becomes int **list, and int *const list[] becomes int *const *list.

Is argv an array of pointers?

Yes. In a hosted C program, argv is an array of pointers to the command-line argument strings.

Finish the Pointer Block in Our Free C Course

The next lecture contrasts the array of pointers with the pointer to an array and ends with a quiz and interview questions.

Need Help or More Information?

Questions about this free C programming course, embedded C training or career guidance? Get in touch.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *