DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C BasicsTopic 44 of 64
←PreviousPrevNextNext→

C Pointers & Arrays

Relationship Between Pointers and Arrays

In C, arrays and pointers are closely related. In most expressions, an array "decays" to a pointer to its first element.

Key relationships (after decay):

- array_name ≈ &array_name[0]

- array_name[i] ≡ *(array_name + i)

- &array_name[i] ≡ array_name + i

Important: the array itself is not a pointer (it's a distinct type and not assignable); it only decays to a pointer in expressions.

Array-to-Pointer Decay: Common Exceptions

Array-to-pointer decay does NOT happen in a few cases:

• With sizeof: sizeof array yields total bytes of the array

• With unary &: &array yields a pointer to the whole array (type like int (*)[N])

• When initializing another array from a string literal (e.g., char s[] = "hi";)

Example
#include <stdio.h>
int main(void){
    int a[5];
    printf("sizeof a: %zu\n", sizeof a);           // total size of array
    printf("&a type is pointer-to-array; sizeof &a: %zu\n", sizeof &a);
    return 0;
}
Output
sizeof a: 20
&a type is pointer-to-array; sizeof &a: 8

Array Access Using Pointers

Example
#include <stdio.h>
int main(void){
    int numbers[] = {10, 20, 30, 40, 50};
    int *ptr = numbers; // decay to &numbers[0]
    printf("Element 0: %d %d\n", numbers[0], *ptr);
    printf("Element 1: %d %d\n", numbers[1], *(ptr + 1));
    printf("Element 2: %d\n", *(numbers + 2));
    return 0;
}
Output
Element 0: 10 10
Element 1: 20 20
Element 2: 30

Pointer Arithmetic with Arrays

Pointer arithmetic traverses arrays by element size automatically (compiler scales by sizeof(*ptr)).

Example
#include <stdio.h>
int main(void){
    float values[] = {1.1f, 2.2f, 3.3f, 4.4f, 5.5f};
    float *ptr = values;
    for (int i = 0; i < 5; i++){
        printf("Element %d: %.1f at address %p\n", i, *(ptr + i), (void*)(ptr + i));
    }
    return 0;
}
Output
Element 0: 1.1 at address 0x7ffd4f9c7b20
Element 1: 2.2 at address 0x7ffd4f9c7b24
Element 2: 3.3 at address 0x7ffd4f9c7b28
Element 3: 4.4 at address 0x7ffd4f9c7b2c
Element 4: 5.5 at address 0x7ffd4f9c7b30
ℹ️ Note: Each float is typically 4 bytes; addresses increase by 4.

Array Parameters as Pointers

When arrays are passed to functions, they decay to pointers. The function receives a pointer to the first element, not a copy of the array.

⚠️ Warning: Inside such functions, sizeof(arr) is the size of a pointer, not the array. Always pass the array length separately.
Example
#include <stdio.h>

void printArray(int *arr, int size){
    for (int i = 0; i < size; i++) printf("%d ", arr[i]);
}

void printArrayBracket(int arr[], int size){ // same as int *arr
    for (int i = 0; i < size; i++) printf("%d ", *(arr + i));
}

int main(void){
    int numbers[] = {1,2,3,4,5};
    printArray(numbers, 5);
    printf("\n");
    printArrayBracket(numbers, 5);
    return 0;
}
Output
1 2 3 4 5 
1 2 3 4 5 

Pointer to Array vs Array of Pointers

These are different types:

• Array of pointers: each element is an independent pointer (e.g., int *ptrs[3])

• Pointer to array: points to an entire array object (e.g., int (*p)[3])

Pointer arithmetic differs: (p+1) with p of type int (*)[3] advances by 3 ints.

Example
#include <stdio.h>
int main(void){
    int a=1,b=2,c=3;
    int *ptrArray[3] = {&a,&b,&c}; // array of pointers
    int arr[3] = {10,20,30};
    int (*arrayPtr)[3] = &arr;      // pointer to array of 3 ints

    printf("Array of pointers: ");
    for (int i=0;i<3;i++) printf("%d ", *ptrArray[i]);

    printf("\nPointer to array: ");
    for (int i=0;i<3;i++) printf("%d ", (*arrayPtr)[i]);

    return 0;
}
Output
Array of pointers: 1 2 3 
Pointer to array: 10 20 30 

Best Practices & Pitfalls

1. Do not write arr = other; arrays are not assignable (use memcpy or loops).

2. Keep pointer arithmetic within the array bounds (or one past the end) to avoid undefined behavior.

3. Prefer passing lengths alongside array pointers; do not rely on sentinel values unless intentional.

4. Remember the decay exceptions (sizeof, unary &, array initialization) to avoid type surprises.

5. Use const where appropriate (e.g., const int *p) when you don’t intend to modify elements.

Test your knowledge: C Pointers & Arrays
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
C BasicsTopic 44 of 64
←PreviousPrevNextNext→