What is Array Name vs Pointer- Free Embedded Systems and C Programming Course

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 · Pointers · Lecture 19

Array Name vs Pointer

Subscript a pointer variable, learn what an array name can and cannot do, and finish with a quiz and interview questions. The closing lecture of this group in our free C tutorial for embedded systems.

Topics in This Lecture

array name vs pointer variable subscripting a pointer array decay sizeof array vs pointer C interview questions free embedded C course

Arrays and pointers look so alike in C that many learners assume they are the same thing. They are not, and the difference between an array name vs pointer variable is one of the most tested topics in C interviews and one of the most common sources of bugs in embedded C programming. In this final lecture of the group from our free C programming course we show where the two behave identically, where they differ, and why. You will also find a hands-on quiz and a set of interview questions with answers.

Like the earlier lectures in this free embedded C course, every program and every compiler message below was produced by real GCC runs on 64-bit Linux.

What You Will Learn

  • How to point a pointer variable at an array and subscript it with ptr[i]
  • Why *(ptr + i) and ptr[i] are equivalent
  • What an array name cannot do that a pointer variable can
  • How sizeof tells an array and a pointer apart
  • Why an array parameter silently becomes a pointer inside a function
  • How dynamic arrays rely on pointer subscripting
  • Quiz questions and interview answers to test yourself

Prerequisites

Complete the previous three lectures first: array memory layout, array address arithmetic, and pointer notation for arrays. You should also know how to declare a pointer and use ++ on it.

Subscripting a Pointer Variable

Suppose you declare an array and a pointer, then store the array’s base address in the pointer. From that moment the pointer is a second route to the same memory.

int lut[4] = {10, 20, 30, 40};
int *p = lut;      /* same as p = &lut[0] */

With p holding the base address, p + i is the address of element i and *(p + i) is its value. Since x[i] is defined as *(x + i) for any pointer x, you can also write p[i]. The subscript operator never cared whether the left side was an array or a pointer; it only needs an address and an index.

Two names, one block of memory

p (pointer variable)holdsbase address→lut[0]lut[1]lut[2]lut[3]
lut (array name)is the block itself, and decays to the same base address

This equivalence is what makes dynamic arrays practical. When memory comes from malloc, all you ever receive is a pointer, yet you happily write buf[i]. And when you pass an array to a function, the function receives a pointer and uses the same notation.

Array Name vs Pointer Variable: The Differences

An array name is not a variable that stores an address. It names the whole block of elements. The address you get from it is computed by the compiler when the name appears in an expression. A pointer variable, in contrast, is a real object with its own storage that contains an address and can be changed.

PropertyArray name lutPointer variable p
What it isThe whole block of elementsA variable holding an address
Occupies extra storage for an addressNoYes, one pointer-size object
Can be assigned a new addressNoYes
Can be incremented or decrementedNoYes
sizeof resultTotal bytes of all elementsSize of the pointer itself
Can use [ ]YesYes
Can use * and +Yes (via decay)Yes

What you may do with each

lutread elements ✔lut[i] ✔lut + i ✔lut++ ✘lut = other ✘
pread elements ✔p[i] ✔p + i ✔p++ ✔p = other ✔

Example 1: sizeof and Pointer Moves

This program shows sizeof for both, subscripts the pointer, moves the pointer around freely, and then passes the array to a function to reveal array decay.

#include <stdio.h>

static void show_param(int a[])
{
    printf("inside function : sizeof a = %zu\n", sizeof a);
}

int main(void)
{
    int lut[4] = {10, 20, 30, 40};
    int *p = lut;

    printf("sizeof lut = %zu, sizeof p = %zu\n", sizeof lut, sizeof p);
    printf("p[2] = %d, *(p + 2) = %d\n", p[2], *(p + 2));

    p++;
    printf("after p++ : p[0] = %d\n", p[0]);
    p--;
    p = lut + 3;
    printf("after p = lut + 3 : *p = %d\n", *p);

    show_param(lut);
    return 0;
}

Build and run

gcc -Wall -Wextra -std=c11 -o l19_ptr l19_ptr.c
./l19_ptr

GCC prints a helpful warning at the sizeof a line, which we will explain below:

l19_ptr.c:5:57: warning: 'sizeof' on array function parameter 'a' will return size of 'int *' [-Wsizeof-array-argument]

Expected output (64-bit Linux)

sizeof lut = 16, sizeof p = 8
p[2] = 30, *(p + 2) = 30
after p++ : p[0] = 20
after p = lut + 3 : *p = 40
inside function : sizeof a = 8

What each line teaches

  • sizeof lut is 16 because the array holds four 4-byte integers. sizeof p is 8 because a pointer on this machine is 8 bytes. On a 32-bit microcontroller it would be 4.
  • p[2] and *(p + 2) print the same value, so a pointer variable can be subscripted just like the array.
  • p++ makes p point at the second element, so p[0] is now 20. The pointer can walk, and it can also be reset or reassigned to any element.
  • Inside show_param, sizeof a gives 8, not 16. The parameter looks like an array but the compiler treats it as int *a. The size information is gone, and that is exactly what the warning says.

Array Decay in Function Parameters

The syntax int a[] and even int a[10] in a function parameter list is just another way of writing int *a. The number inside the brackets is ignored by the compiler. The function therefore cannot know how many elements the caller’s array has.

This is why C library functions and your own functions usually take a pointer plus a separate length argument, for example void process(const uint16_t *samples, size_t count). Always pass the count; never compute it with sizeof inside the callee.

Example 2: What the Compiler Says About lut++

Try to move the array name like a pointer and the compiler stops you.

int main(void)
{
    int lut[4] = {10, 20, 30, 40};
    lut++;
    return 0;
}
gcc -Wall -std=c11 l19_bad.c -o bad
l19_bad.c:4:8: error: lvalue required as increment operand
    4 |     lut++;
      |        ^~

“Lvalue required” means the operand must be something that can be assigned to. An array name is not such an object, so lut++, lut-- and lut = &other are all rejected. If you need a movable position, create a pointer and move that instead.

Example 3: Dynamic Array With Pointer Subscripts

A heap-allocated array has no array name at all. You only have a pointer, and subscripting is how you use it.

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

int main(void)
{
    size_t n = 5;
    int *sq = malloc(n * sizeof *sq);
    if (sq == NULL)
        return 1;

    for (size_t i = 0; i < n; i++)
        sq[i] = (int)(i * i);

    for (size_t i = 0; i < n; i++)
        printf("sq[%zu] = %d\n", i, sq[i]);

    free(sq);
    return 0;
}
gcc -Wall -Wextra -std=c11 -o l19_heap l19_heap.c
./l19_heap
sq[0] = 0
sq[1] = 1
sq[2] = 4
sq[3] = 9
sq[4] = 16

Writing malloc(n * sizeof *sq) instead of repeating the type is a good habit: if you later change the pointer type, the allocation size follows automatically. Many small embedded systems avoid malloc altogether, but the same pointer-subscript pattern applies to static buffers handed around as pointers.

Real-World Embedded Use Cases

  • A UART driver receives a uint8_t * and a length, then indexes it with buf[i].
  • A DMA setup function takes the base address of the array as a pointer.
  • A sensor library exposes const int16_t *samples and walks it with a moving pointer.
  • A table in flash is declared as an array in one file and accessed through a pointer parameter in another.

Common Mistakes and Troubleshooting

MistakeSymptomFix
Using sizeof on an array parameterGets pointer size, loop covers too few elementsPass the element count as a separate argument
Incrementing the array nameCompile error: lvalue requiredUse a separate pointer variable
Assuming sizeof(p) is the array size when p is a pointerWrong buffer lengthsTrack length yourself
Forgetting to check malloc resultCrash on first writeTest for NULL before use
Returning a pointer to a local arrayDangling pointer, garbage dataUse static storage, caller buffer or heap

Best Practices, Performance and Security

Best practices

  • Declare read-only array parameters as const T * plus a size_t count.
  • Use sizeof(arr) / sizeof(arr[0]) only where the real array is in scope.
  • Keep the original array name or base pointer unchanged, and walk with a second pointer.
  • Compile with -Wall -Wextra to catch sizeof misuse.

Performance: passing a pointer copies only an address, not the whole array, so function calls stay cheap even for large buffers.

Security: because a pointer parameter carries no length, always validate the count against the real buffer capacity. A wrong count is the classic cause of buffer overflows in network and file parsers.

Summary and Key Takeaways

  • A pointer variable pointing at an array can be subscripted: p[i] equals *(p + i).
  • An array name is not a modifiable variable; it cannot be incremented or reassigned.
  • sizeof of an array is the total bytes; sizeof of a pointer is the pointer size.
  • Array parameters in functions are really pointers, so length must be passed separately.
  • Dynamic arrays are used through pointers with the same subscript notation.

Conclusion

You have now seen both sides of the array and pointer relationship. They share notation and arithmetic, yet an array is a block of storage while a pointer is a variable holding an address. Keeping that distinction clear will save you from subtle bugs in embedded C programming and from missed questions in technical interviews. Work through the quiz and the interview section below, then try writing your own small function that takes a pointer and a count and returns the largest element.

Quiz: Test Your Understanding

Quick Quiz: Arrays and Pointers

Try each question first, then open the answer. Assume a 64-bit Linux system where int is 4 bytes and a pointer is 8 bytes.

  1. If int a[6]; has base address B, what is the address of a[4]?
    Show answer

    B + 16 bytes, because 4 elements of 4 bytes each lie before it.

  2. Which of these is NOT equivalent to a[2]: *(a + 2), *(2 + a), 2[a], *a + 2?
    Show answer

    *a + 2. It reads element 0 and adds 2 to the value, instead of reading element 2.

  3. True or false: an array name can be incremented to walk through the array.
    Show answer

    False. The array name is not a modifiable lvalue. Use a pointer variable.

  4. What does sizeof return for int x[10] in the same function where it is declared?
    Show answer

    40, which is ten elements of 4 bytes.

  5. A function is declared void f(int a[10]). What is sizeof a inside it?
    Show answer

    8 on this system. The parameter is really int *a, so you get the pointer size.

  6. Predict the output:
    int a[4] = {3, 6, 9, 12};
    int *p = a + 1;
    printf("%d %d %d\n", *p, p[1], *(p - 1));
    Show answer

    6 9 3. The pointer starts at element 1; p[1] is element 2; p – 1 is element 0.

  7. Predict the output:
    int a[4] = {3, 6, 9, 12};
    int *p = a;
    p += 2;
    printf("%d %td\n", *p, p - a);
    Show answer

    9 2. After adding 2 the pointer references element 2, and the difference from the base is 2 elements.

  8. Predict the output:
    int a[3] = {10, 20, 30};
    int *p = a;
    p++;
    *p = 99;
    printf("%d %d %d\n", a[0], a[1], a[2]);
    Show answer

    10 99 30. Writing through the moved pointer changes the original array’s element 1.

  9. Which loop condition is safe for a pointer walk over n elements starting at p = a, with end = a + n: p <= end or p != end?
    Show answer

    p != end. Using <= would run one step too far and read the one-past-the-end position.

  10. Why should you pass a length alongside an array to a function?
    Show answer

    The array decays to a pointer, which carries no size information, so the function has no other way to know the element count.

Interview Questions on Arrays and Pointers

C Interview Questions With Answers

1. Are arrays and pointers the same thing in C?

No. An array is a contiguous block of elements; a pointer is a variable that stores an address. They are related because an array name converts to a pointer to its first element in most expressions, and because the subscript operator works on any pointer.

2. Why is arr[i] equal to i[arr]?

The subscript operator is defined as *(arr + i), and addition is commutative, so *(i + arr) is identical. It is valid but should not be used in real code.

3. When does an array NOT decay to a pointer?

When it is the operand of sizeof, the operand of unary &, or a string literal used to initialise a character array. In those cases the array keeps its identity as the whole block.

4. Why does sizeof give a different answer inside a function?

Array parameters are adjusted to pointer parameters, so sizeof sees a pointer. Pass the number of elements separately.

5. What is the difference between &arr and &arr[0]?

They hold the same numeric address but have different types. &arr[0] is a pointer to one element, while &arr is a pointer to the whole array. Adding 1 to them moves by one element or by the whole array size respectively.

6. What is a one-past-the-end pointer?

It is the address just after the last element. You may form and compare it but must not dereference it. Loops use it as a termination marker.

7. How do you compute the number of elements in an array?

sizeof(arr) / sizeof(arr[0]), only where arr is a true array and not a function parameter.

8. What does pointer subtraction return?

The number of elements between two pointers into the same array, as a ptrdiff_t.

9. Why use const in a pointer parameter such as const uint8_t *buf?

It promises the function will not modify the data, allows passing read-only data such as tables in flash, and lets the compiler detect accidental writes.

10. How would you move a pointer by exactly one byte through a 32-bit array?

Cast it to a byte pointer first, for example (uint8_t *)arr + 1. Adding 1 to a uint32_t pointer would move four bytes.

11. Why is returning the address of a local array a bug?

The array lives on the function’s stack frame, which is gone after return. The pointer then dangles, and any use is undefined behaviour.

12. Why do embedded teams prefer stdint types for arrays shared with hardware?

The size of int and short varies by target. Fixed-width types guarantee the same element size and layout across compilers and processors.

Frequently Asked Questions

Can I subscript a pointer variable in C?

Yes. For any pointer p, p[i] means *(p + i). It works whether p points into an array, a malloc block or a static buffer.

What is the difference between an array name and a pointer variable?

An array name stands for the whole block and cannot be modified; a pointer variable is an object that stores an address and can be changed, incremented and reassigned.

Why can’t I do arr++ on an array?

An array name is not a modifiable lvalue. The compiler reports an error such as lvalue required as increment operand. Use a separate pointer to walk the array.

What is array decay?

It is the automatic conversion of an array name to a pointer to its first element when it appears in most expressions or is passed to a function.

Does passing an array to a function copy it?

No. Only the address of the first element is passed, so the function works on the original data, and it does not know the length.

Is this lecture useful for an embedded C interview?

Yes. Array versus pointer, sizeof behaviour and array decay appear in almost every embedded C interview. This free C tutorial covers them with runnable examples.

Keep Building Your Embedded C Skills

You have completed arrays and pointers in this group. Continue with the next topic in our free C programming course for embedded systems.

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 *