C Programming: Arrays, Functions, and String Handling

One-Dimensional Arrays

A one-dimensional array is a linear collection of elements of the same data type, stored in contiguous memory locations.

1. Declaration

Declaring an array tells the compiler its name, data type, and size.

data_type array_name[size];
  • Example: int scores[5]; // Declares an array named scores that can hold 5 integers.

2. Initialization

You can initialize an array at the time of declaration or assign values later.

MethodExampleDescription
Declaration with Sizeint marks[3] = {90, 85, 95};The values are assigned to elements marks[0], marks[1], and marks[2].
Omitting Sizefloat weights[] = {55.5, 60.0, 72.3};The compiler automatically determines the size (3) based on the number of elements provided.
Partial Initializationchar letters[5] = {'A', 'B'};The first two elements are initialized; the remaining elements (letters[2] to letters[4]) are initialized to zero (or null character \0 for char).

3. Memory Representation

  • Elements of an array are stored in contiguous (adjacent) memory locations.
  • Array indexing starts at 0.
  • If int scores[5] is declared, and the base address (address of scores[0]) is 1000, and an int takes 4 bytes:
    • scores[0] is at address 1000
    • scores[1] is at address 1004
    • scores[2] is at address 1008
    • The address of any element A[i] can be calculated as: Base Address + (i * size of data type)

Two-Dimensional Arrays

A two-dimensional array (or matrix) is an array where the elements are organized in rows and columns. It is essentially an array of one-dimensional arrays.

1. Declaration

You must specify both the number of rows and the number of columns.

data_type array_name[row_size][column_size];
  • Example: float matrix[3][4]; // Declares a 3×4 matrix (3 rows, 4 columns) that can hold 12 floating-point numbers.

2. Initialization

Initialization can be done by providing a list of values. Grouping them by row is optional but improves readability.

MethodExampleDescription
Row by Row (Recommended)int m[2][3] = { {10, 20, 30}, {40, 50, 60} };Values are clearly grouped into rows.
Continuous Listint m[2][3] = {10, 20, 30, 40, 50, 60};The values are assigned sequentially (first 3 for row 0, next 3 for row 1).
Omitting Row Sizeint m[][3] = { {1, 2, 3}, {4, 5, 6} };The compiler determines the number of rows (2), but the column size must always be specified.

3. Memory Representation

Even though a 2D array is conceptualized as a grid, C stores it in memory in a contiguous, linear fashion using Row-Major Order. This means the elements of the first row are stored sequentially, followed by the elements of the second row, and so on.

  • For an array A[R][C], the element A[i][j] (row i, column j) is located at:
  • Example: For matrix[3][4]:
    • Row 0: matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3]
    • Row 1: matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3] (immediately after the last element of Row 0)
    • …and so on.

That’s the final set of core C fundamentals! Here is a concise overview of Functions and Strings in C.

Functions in C

A function is a self-contained block of code that performs a specific, well-defined task. Functions help break down complex programs into smaller, manageable units (modularity).

1. Function Definition

The function definition provides the actual body of the function—the code that executes when the function is called.

return_type function_name(parameter_list) {
    // Function Body
    // Statements to perform the task
    return value; // Optional, depends on return_type
}

2. Function Prototype (Declaration)

A function prototype informs the compiler about a function’s name, return type, and the number/types of its parameters before the function is actually defined or used. Prototypes are usually placed at the start of a program (before main()).

return_type function_name(type1 param1, type2 param2); // or just: return_type function_name(type1, type2);

3. Function Call

A function is executed when it is called by its name within another function (like main()).

result = function_name(argument_list);

4. Passing Arguments

Arguments (the values passed during the call) can be transferred to the parameters of the function in two ways:

A. Call by Value

  • The function receives only the value of the argument.
  • The function works on a copy of the original variable.
  • Changes made inside the function do not affect the original variable in the calling function.
  • Example: void change_val(int x) { x = x + 10; } // Calling: int a = 5; change_val(a); a remains 5.

B. Call by Reference

  • The function receives the memory address (reference) of the argument. This is achieved by passing pointers (* and & operators).
  • The function directly works on the original variable stored at that address.
  • Changes made inside the function directly affect the original variable.
  • Example: void change_val_ref(int *x) { *x = *x + 10; } // *x refers to the value at the address. // Calling: int a = 5; change_val_ref(&a); a becomes 15.

5. Recursive Functions

A recursive function is a function that calls itself to solve a problem. It requires a base case to stop the recursion, otherwise it leads to an infinite loop. Recursion is often used for problems that can be broken down into smaller, similar sub-problems (e.g., calculating factorials or Fibonacci numbers).

Strings in C

In C, a string is simply a one-dimensional array of characters terminated by a special character called the null character (\0).

1. Declaration and Initialization

MethodExampleDescription
Array of Characterschar name[6] = {'H', 'e', 'l', 'l', 'o', '\0'};Explicitly includes the null terminator.
String Literal (Common)char name[] = "Hello";Most common. The compiler automatically calculates the size (6, including \0) and appends the null terminator.
Fixed Sizechar city[20];Declares space for a string up to 19 characters, plus \0.

2. String I/O

  • Input (scanf): Use the %s format specifier. Note: scanf stops reading at the first white space (space, newline, tab).
    scanf("%s", city); // No & needed for arrays/strings
  • Input (gets / fgets): gets() reads a line including spaces (but is unsafe). fgets() is preferred as it limits input size, preventing buffer overflow.
  • Output (printf): Use the %s format specifier.
    printf("City: %s", city);
  • Output (puts): Prints the string and automatically adds a newline character.

3. Array of Strings

This is a two-dimensional character array, where each row holds a separate string.

char names[3][10] = {
    "Alice",   // Row 0
    "Bob",     // Row 1
    "Charlie"  // Row 2
};

String Manipulation Functions

C provides a standard library, <string.h>, which contains many useful functions for manipulating strings.

FunctionPurposeExample
strlen(s)String Length: Returns the length of the string s (the number of characters, excluding \0).int len = strlen(str);
strcpy(dest, src)String Copy: Copies the contents of the source string (src) to the destination string (dest).strcpy(dest_str, "New Text");
strcat(dest, src)String Concatenate: Appends (joins) the source string (src) to the end of the destination string (dest).strcat(s1, s2);
strcmp(s1, s2)String Compare: Compares two strings lexicographically. Returns: 0 if strings are equal; < 0 if s1 comes before s2; > 0 if s1 comes after s2.if (strcmp(s1, s2) == 0)
strstr(s1, s2)Search for a Substring: Finds the first occurrence of string s2 (substring) in string s1.Returns a pointer to the first character of the matching substring in s1, or NULL if not found.