Arrays are contiguous memory blocks. Strings in C are char arrays terminated by a null byte ('\0'). There is no bounds checking.

One-Dimensional Arrays

  int nums[5] = {1, 2, 3, 4, 5};
int zeros[10] = {0};           /* all zero */
int partial[] = {1, 2};        /* size deduced: 2 */

printf("%d\n", nums[0]);
printf("%zu\n", sizeof nums / sizeof nums[0]);  /* element count */
  

Multidimensional

  int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

for (int r = 0; r < 3; r++)
    for (int c = 0; c < 4; c++)
        printf("%d ", matrix[r][c]);
  

Memory layout is row-major: matrix[1][2] is the 7th element in flat order.

Strings

  char greeting[] = "Hello";     /* mutable, includes '\0' */
const char *msg = "World";     /* string literal — often read-only */

char buf[32];
strncpy(buf, "Hi", sizeof buf - 1);
buf[sizeof buf - 1] = '\0';   /* ensure null termination */
  

string.h Functions

  #include <string.h>

size_t len = strlen("hello");           /* 5 */
strcmp("abc", "abd");                   /* negative */
strncmp(a, b, n);                       /* bounded compare */
strcpy(dest, src);                      /* unsafe if dest too small */
strncpy(dest, src, n);
char *p = strstr("hello world", "world");
  

Safe String Patterns

  /* Prefer snprintf over sprintf */
char buf[64];
snprintf(buf, sizeof buf, "Value: %d", 42);

/* Never use gets() — removed in C11 */
char line[256];
if (fgets(line, sizeof line, stdin))
    line[strcspn(line, "\n")] = '\0';  /* strip newline */
  

Common Pitfalls

  • Treating compiler warnings as optional rather than actionable feedback.
  • Skipping error checks on library and system calls.
  • Copy-pasting examples without adapting to your project’s conventions.

Best Practices

  • Enable strict compiler warnings and fix them before merging.
  • Write small, testable units with clear input/output contracts.
  • Document non-obvious invariants and preconditions.
  • Use version control and code review for every change.

Memory and Performance Notes

String literals may live in read-only memory. Writing to char *s = "hi" causes a crash on many systems.

Exercise

Write reverse_string(char *s) that reverses a string in place. Test with palindromes and empty strings.

Hint: Use two pointers — one at start, one at end — swapping characters until they meet.

Summary

Apply these concepts in small programs before moving to larger projects. Combine with adjacent topics in the learning path for deeper mastery.

Real-World Application

These concepts appear in production codebases — from operating system kernels to embedded firmware. Study open-source projects that use this topic extensively to see idiomatic patterns at scale.

Debugging Checklist

  1. Reproduce the issue with the smallest possible input.
  2. Enable compiler warnings and sanitizers.
  3. Use a debugger to inspect state at the failure point.
  4. Verify assumptions about types, sizes, and return values.
  5. Compare working and broken code paths side by side.
  6. Write a regression test once the bug is fixed.

Further Reading

Consult the ISO C standard, Effective C by Robert C. Seacord, and your compiler documentation for platform-specific behavior.

Quick Reference

Review the code examples on this page before starting the exercise. Type them manually to build muscle memory.

Additional Examples

Consider how this topic applies in a larger project:

  // Break the problem into smaller functions
// Test each function independently
// Integrate incrementally
  

Working through variations of the examples above builds deeper understanding than reading alone.

Interview and Review Questions

  1. Explain the core concept of this topic in your own words.
  2. What happens when this code runs with edge-case input (empty, null, zero, max value)?
  3. How would you debug a bug related to this topic in production?
  4. What are the performance implications of the approach shown here?
  5. How does this feature compare to the equivalent in another language you know?