Topic 62 of 100 Arrays and Strings in C Interactive Tutorial

One-Dimensional Arrays in C: Declaration, Initialization, and Access

11 mins read Last updated: 22 Aug 2026 22,100 views
C Compiler 0.00%

What is One-Dimensional Arrays in C? Core Concept & Direct Summary

Core Objective & Problem Statement

How are 1D arrays declared, initialized using initializer lists, and manipulated in loops?

Direct Answer Summary

Of all the array shapes C supports, one-dimensional arrays do the heavy lifting. Real programs store lists constantly — test scores, prices, temperatures, player names, sensor readings — and a 1D array is the natural container for a single list of values.

The concept is simple enough (a row of boxes, numbered from zero), but there's real craft in the details: the different ways to declare and initialize, the difference between the size and the last index, how to safely compute an array's length, the input/output loops you'll write a thousand times. This tutorial covers all of it with the depth the pillar page couldn't fit — plus the memory picture that makes everything click.

(Suggested image: the hero graphic — a clean row of seven memory boxes labeled [0] through [6] holding values, with the single array name spanning them and the base address marked at the first box)


How Does One-Dimensional Arrays in C Work? In-Depth Mechanics & Architecture

Declaration: The Forms You Need to Know

The basic form:

main.c
Run Online
int marks[5];
// 5 integersfloat prices[10];
// 10 floatschar letters[26];
// 26 charactersdouble measurements[100];
// 100 doubles

Three rules for the size:

  1. It must be a positive integer. Zero or negative isn't allowed.
  2. It can be a constant expression — a literal (5) or a #defined value:
    main.c
    Run Online
    #define SIZE 10int arr[SIZE];
    // ✓ recommended — one place to change
  3. In strict C, it can't be a runtime variable for a standard array… well, with one modern exception called a VLA (variable-length array), which C99 added:
    main.c
    Run Online
    int n;
    scanf("%d", &n);
    int arr[n];
    // VLA — C99 extension, risky and easy to overflow
    Practical advice: if the size must be flexible, declare a generous fixed maximum and track the actual count separately. VLAs are legal but discouraged in real code because a large user-supplied n can blow the stack.

⚠️ Uninitialized arrays contain garbage. If you declare int marks[5]; and read from it immediately, you get whatever bytes were lying around in memory. This is the same behavior we saw with auto variables in the storage classes tutorial — arrays don't get zeroed for free.

(Suggested image: two side-by-side boxes — "int marks[5]; → garbage, garbage, garbage, garbage, garbage" vs "int marks[5] = {0}; → 0, 0, 0, 0, 0")


Initialization: Every Form in One Place

This is where a lot of small confusions live, so here's the complete set.

Form 1: Full initialization with explicit size

main.c
Run Online
int marks[5] = {
    45, 62, 78, 34, 90
}
;

Size 5, five values. Everything lines up.

Form 2: Size inferred from the values

main.c
Run Online
int marks[] = {
    45, 62, 78, 34, 90
}
;
// compiler counts: size = 5

Cleaner, and impossible to get the count wrong.

Form 3: Partial initialization — the rest become ZERO

main.c
Run Online
int scores[5] = {
    10, 20
}
;
// Result: {
10, 20, 0, 0, 0
}

This is genuinely useful, not just trivia — it's how the widely used zero-fill idiom works.

Form 4: The zero-fill idiom

main.c
Run Online
int counters[100] = {
    0
}
;
// ALL 100 elements set to 0

One value supplied, the rest auto-filled with zeros. Memorize this one — you'll write it dozens of times.

Form 5: Initialize after declaring (element by element)

main.c
Run Online
int arr[4];
arr[0] = 5;
arr[1] = 10;
arr[2] = 15;
arr[3] = 20;

Verbose, but legitimate — and it's how you'd fill an array with computed values.

Form 6: Designated initializers (C99) — sparse assignment

When you only want to set some positions:

main.c
Run Online
int arr[10] = {
    [2] = 30, [5] = 60, [9] = 90
}
;
// Everything else is 0// {
0, 0, 30, 0, 0, 60, 0, 0, 0, 90
}

Handy for lookup tables with mostly-empty slots.

What you CANNOT do

main.c
Run Online
int a[3] = {
    1,2,3
};
int b[3];
b = a;
// ✗ ERROR — arrays can't be assigned wholesale
int c[3] = a;
// ✗ ERROR — can't initialize from another array either

To copy, you loop:

main.c
Run Online
for (int i = 0;
i < 3;
i++) b[i] = a[i];
// ✓ element by element

That's a real limitation C beginners from Python/JavaScript run into — and a genuine interview question.

(Suggested image: a comparison table graphic of all six initialization forms with their resulting arrays drawn out — very shareable and useful as a bookmark)


Accessing Elements: The Index Rules

main.c
Run Online
int marks[5] = {
    45, 62, 78, 34, 90
}
;
marks[0] // 45  — firstmarks[4]      // 90  — last (size - 1)marks[2]      // 78marks[1] = 70;
// overwrite

The boundary rule, stated once and for all:

Array sizeValid indexesLast valid index
int a[5]0, 1, 2, 3, 44
int a[10]0 … 99
int a[1]00

The declared number is the count, not the last index. int a[5] has five elements; the highest you may touch is a[4].

And C will not stop you from going out of bounds:

main.c
Run Online
int a[5] = {
    1,2,3,4,5
}
;
printf("%d\n", a[5]);
// ✗ compiles! prints garbage from adjacent memorya[10] = 99;                // ✗ compiles! silently corrupts something else

No runtime error. No warning (unless your compiler's static analysis happens to catch the literal case). Just wrong values and mysterious crashes. Array bounds discipline is entirely your responsibility in C — a fact that's responsible for a large share of real-world security vulnerabilities, from the gets() buffer overflow onward.

(Suggested image: the valid-index diagram with green boxes 0–4 and a red out-of-bounds arrow labeled "no checking, memory corruption risk")


Getting the Size: The sizeof Idiom

Hard-coding 5 in your loops works until the array changes size. The robust pattern:

main.c
Run Online
int marks[] = {
    45, 62, 78, 34, 90
}
;
int n = sizeof(marks) / sizeof(marks[0]);
// 20 bytes / 4 bytes = 5
  • sizeof(marks) — the array's total size in bytes
  • sizeof(marks[0]) — one element's size in bytes
  • Divide → element count

Important caveat: this only works where the array is a real array — in the same scope where it was declared. Once you pass an array to a function, it decays to a pointer and sizeof gives the pointer's size (usually 8), not the array's. That's why array functions need the count passed separately — a detail we'll explore fully in the "Passing Arrays to Functions" tutorial.

(Suggested image: the sizeof division shown as a literal calculation over a memory diagram)


Input and Output: The Loops You'll Write Forever

Reading values into an array:

main.c
Run Online
int marks[5];
for (int i = 0;
i < 5;
i++) {
    printf("Enter marks for student %d: ", i + 1);
    scanf("%d", &marks[i]);
    // note the & — we're storing INTO a slot
}

Printing an array:

main.c
Run Online
for (int i = 0;
i < 5;
i++) {
    printf("%d ", marks[i]);
    // no & here — just reading the value
}
putchar('\n');

That & distinction is worth pausing on: scanf needs the address of the element (&marks[i]) to write into it, while printf just needs the value (marks[i]). Same "& means address" rule from our scanf tutorial, applied per-element.

The Name-Only Print: A Fun Trap

main.c
Run Online
printf("%p\n",(void *)marks);
// address of element 0 — fineprintf("%d\n", marks[0]);
// first element — fineprintf("%s\n", marks);
// ✗ WRONG for an int array — treats it as a string!

Printing marks with %d won't give you the whole array — C has no built-in "print entire array" feature. That's exactly why loops exist. (For char arrays, %sdoes work — because strings are special — but that's the Strings cluster.)


Memory Layout, Revisited (The Part That Unlocks Pointers)

main.c
Run Online
int nums[4] = {
    10, 20, 30, 40
}
;
main.c
Run Online
Index: 0 1 2 3Value: 10 20 30 40Address: 1000 1004 1008 1012(4-byte ints)

Two facts to carry forward:

1. Element address = base + (index × size).nums[2] = 1000 + (2 × 4) = 1008. Direct arithmetic, which is why nums[i] is O(1) no matter how big the array.

2. The array name is the address of element 0.nums ≡ &nums[0]. This is why:

  • You pass arrays to functions by writing just func(nums) (no & needed — it's already an address)
  • printf("%p", nums) prints the base address
  • Array indexing and pointer arithmetic are two views of the same thing

You'll see *(nums + i) written instead of nums[i] in older and lower-level code — identical in meaning. That's a pointers-cluster topic, but now you can see why it works.

(Suggested image: the address diagram with the formula base + i × size annotated — keep it consistent with the pillar page's version for visual continuity)


Core Example Set: The Five Patterns Everyone Needs

1. Sum and average

main.c
Run Online
int total = 0;
for (int i = 0;
i < n;
i++) total += arr[i];
printf("Average: %.2f\n",(float)total / n);

2. Largest and smallest

main.c
Run Online
int max = arr[0], min = arr[0];
// start with the FIRST element!for (int i = 1;
i < n;
i++) {
    // start at 1 — element 0 is already in    if (arr[i] > max) max = arr[i];
    if (arr[i] < min) min = arr[i];
}

Starting from arr[0] rather than 0 (or some huge sentinel) is the robust choice — it works for any data, including all-negative arrays where a 0 start would fail.

3. Reverse the array in place

main.c
Run Online
for (int i = 0, j = n - 1;
i < j;
i++, j--) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

Two indexes meeting in the middle — swap until they cross. This is the classic in-place reversal, and the two-variable for header (from our for-loop tutorial) makes it compact.

4. Copy an array

main.c
Run Online
for (int i = 0;
i < n;
i++) dest[i] = src[i];
// the ONLY way in standard C

5. Count occurrences / search linearly

main.c
Run Online
int target = 78, found = -1;
for (int i = 0;
i < n;
i++) {
    if (arr[i] == target) {
        found = i;
        break;
    }
    // break — we covered this in the break tutorial
}

(Suggested image: mini-diagrams for each pattern — especially the two-pointer reversal, which is a favorite exam/programming question)


A Complete Example: A Temperature Analyzer

main.c
Run Online
#include <stdio.h>
#define DAYS 7
int main(void) {
    float temps[DAYS];
    float total = 0, highest, lowest;
    int hottestDay = 0, coldestDay = 0;
    puts("Weekly Temperature Analyzer");
    puts("---------------------------");
    // Input
    for (int i = 0; i < DAYS; i++) {
        printf("Day %d temperature (°C): ", i + 1);
        scanf("%f", &temps[i]);
        total += temps[i];
    }
    // Analysis (starting from element 0 — safe for any values)
    highest = temps[0];
    lowest = temps[0];
    for (int i = 1; i < DAYS; i++) {
        if (temps[i] > highest) {
            highest = temps[i];
            hottestDay = i;
        }
        if (temps[i] < lowest) {
            lowest = temps[i];
            coldestDay = i;
        }
    }
    float average = total / DAYS;
    // Report
    puts("\n===== WEEKLY REPORT =====");
    for (int i = 0; i < DAYS; i++) {
        printf("Day %d: %6.1f°C", i + 1, temps[i]);
        if (i == hottestDay) printf("  ← hottest");
        else if (i == coldestDay) printf("  ← coldest");
        if (temps[i] > average) printf("  (above avg)");
        else if (temps[i] < average) printf("  (below avg)");
        putchar('\n');
    }
    puts("-------------------------");
    printf("Average : %.1f°C\n", average);
    printf("Highest : %.1f°C (day %d)\n", highest, hottestDay + 1);
    printf("Lowest  : %.1f°C (day %d)\n", lowest, coldestDay + 1);
    return 0;
}

Sample Run:

main.c
Run Online
Weekly Temperature Analyzer
---------------------------
Day 1 temperature(°C): 28.5
Day 2 temperature(°C): 31.2
Day 3 temperature(°C): 26.8
Day 4 temperature(°C): 33.9
Day 5 temperature(°C): 29.4
Day 6 temperature(°C): 24.1
Day 7 temperature(°C): 30.0
===== WEEKLY REPORT =====
Day 1: 28.5°C(below avg)
Day 2: 31.2°C(above avg)
Day 3: 26.8°C(below avg)
Day 4: 33.9°C ← hottest(above avg)
Day 5: 29.4°C(below avg)
Day 6: 24.1°C ← coldest(below avg)
Day 7: 30.0°C(above avg)
-------------------------
Average : 29.1°C
Highest : 33.9°C(day 4)
Lowest : 24.1°C(day 6)

This one program exercises the whole page: fixed-size declaration with #define, array input with &, single-pass statistics starting from element 0, tracking which index holds the extreme values, and multi-way output logic combining the if-else and printf-formatting skills from earlier clusters. That's what real array code looks like.


Common 1D Array Mistakes

  1. Off-by-one in loops — i <= n reads/writes a nonexistent element. i < n, always.
  2. Confusing size with last index — int a[5] → last index 4.
  3. Assuming zeroed memory — uninitialized arrays hold garbage. Use = {0}.
  4. b = a for copying — illegal for arrays; loop instead.
  5. Comparing with == — compares addresses, not contents.
  6. Using sizeof after passing to a function — gives the pointer size, not the array size. Pass the count explicitly.
  7. Variable-length arrays with user input and no validation — int a[n] where n is 10 million can overflow the stack. Prefer #define maxima.
  8. Using %s on a non-char array — reads past the array looking for a null terminator, with predictably bad results.

(Suggested image: "8 Array Mistakes" checklist graphic — consistent with the series)


Final Thoughts

One-dimensional arrays are the plainest data structure in C — a row of same-typed boxes, numbered from zero — and somehow they still do most of the work in real programs. Master the declaration and initialization forms, internalize the boundary rule, get comfortable with the input/analyze/report loop pattern, and you've got a tool you'll use in literally every project from here on.

The two facts to keep closest: the size is a count, not an index, and C will not catch you going out of bounds. Everything else is practice.

Next in this cluster: two-dimensional arrays — where a single index becomes row and column, and grids and matrices open up.

Runnable C Code Example & Practical Implementation

main.c
Run Online
#include <stdio.h>
int main() {
    int values[] = {
        10, 20, 30, 40, 50
    };
    int size = sizeof(values) / sizeof(values[0]);
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += values[i];
    }
    printf("Sum of array elements: %d (Average: %.1f)\
", sum,(double)sum / size);
    return 0;
}

Key Takeaways, Best Practices & Memory Safety Rules

Best Practice & Key Takeaways
Use memset(arr, 0, sizeof(arr)); or {0} initialization to clear arrays cleanly before use.

Frequently Asked Questions & Technical Interview Insights

Technical Interview & Viva Questions

Frequently asked C programming interview questions
Q

Q: What is the effect of `int arr[100] = {0};`?

A: It sets the first element to 0 and all remaining 99 elements to 0 as well (zeroing the whole array).
Q

Q: Can you assign one array directly to another (`arr1 = arr2;`) in C?

A: No, arrays cannot be assigned directly; copy elements using a loop or `memcpy()`.

Related Tools, Tutorials & Authoritative References

Recommended Interactive Tools

Authoritative Standards & Citations