Arrays
Declaring, initializing, and accessing elements of arrays. Working with single and multi-dimensional arrays.
Arrays and Strings in C
Arrays
An array is a data structure that stores a fixed-size sequential collection of elements of the same type. Each element in an array can be accessed using its index, which typically starts from 0 in C.
Key characteristics of arrays:
- Homogeneous: All elements must be of the same data type.
- Contiguous memory allocation: Elements are stored in adjacent memory locations.
- Fixed size: The size of the array must be known at compile time (or dynamically allocated using functions like
malloc
, but even then, the maximum size is typically known when allocating). - Indexed access: Elements are accessed using their index, starting from 0.
Example of array declaration and initialization:
int numbers[5]; // Declares an integer array of size 5
numbers[0] = 10; // Assigns the value 10 to the first element
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;
// Alternatively, initialize during declaration:
int scores[] = {95, 87, 92, 78, 99}; // Size is implicitly 5
for (int i = 0; i < 5; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}
for (int i = 0; i < 5; i++) {
printf("scores[%d] = %d\n", i, scores[i]);
}
Strings
In C, strings are not a built-in data type like in some other languages. Instead, they are represented as arrays of characters. The end of a string is marked by a special character called the null terminator, which is represented by '\0'
.
C-style Strings as Character Arrays and Null Termination
A C-style string is simply an array of characters that is terminated by a null character ('\0'
). This null terminator signals the end of the string to functions that process it.
Example of a string declaration:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Explicit null termination
char message[] = "Hello"; // Equivalent to the above; null termination is implicit
printf("%s\n", greeting); // Output: Hello
printf("%s\n", message); // Output: Hello
In the second example, the compiler automatically adds the null terminator to the end of the string literal "Hello"
.
Important: When declaring a character array to store a string, you need to allocate enough space for all the characters in the string *plus* the null terminator. Failing to do so can lead to buffer overflows and unpredictable behavior.
Common String Manipulation Functions
The string.h
header file provides a number of functions for working with C-style strings.
strlen(str)
: Returns the length of the stringstr
(excluding the null terminator).strcpy(dest, src)
: Copies the stringsrc
to the stringdest
. Important: Ensure thatdest
has enough space to holdsrc
, including the null terminator, to avoid buffer overflows.strncpy(dest, src, n)
: Copies at mostn
characters from stringsrc
to stringdest
. Ifsrc
has fewer thann
characters, the rest ofdest
will be padded with null characters. Ifsrc
hasn
or more characters,dest
may not be null-terminated; you may need to manually add the null terminator.strcat(dest, src)
: Appends the stringsrc
to the end of the stringdest
. Important: Ensure thatdest
has enough space to hold the combined string, including the null terminator, to avoid buffer overflows.strncat(dest, src, n)
: Appends at mostn
characters from stringsrc
to the end of the stringdest
. Ensuresdest
is null-terminated.strcmp(str1, str2)
: Compares the stringsstr1
andstr2
lexicographically. Returns:- 0 if
str1
andstr2
are equal. - A negative value if
str1
comes beforestr2
. - A positive value if
str1
comes afterstr2
.
- 0 if
strncmp(str1, str2, n)
: Compares at mostn
characters of the stringsstr1
andstr2
lexicographically.strstr(haystack, needle)
: Finds the first occurrence of the substringneedle
in the stringhaystack
. Returns a pointer to the beginning of the located substring, orNULL
if the substring is not found.strchr(str, character)
: Finds the first occurrence of the charactercharacter
in the stringstr
. Returns a pointer to the location of the character, or NULL if not found.strrchr(str, character)
: Finds the last occurrence of the charactercharacter
in the stringstr
. Returns a pointer to the location of the character, or NULL if not found.
Buffer Overflow Considerations: The strcpy
and strcat
functions are particularly prone to buffer overflows if the destination buffer is not large enough. It's generally safer to use strncpy
and strncat
, which allow you to specify a maximum number of characters to copy, helping to prevent overflows. However, remember that strncpy
might not null-terminate the destination string, so you may need to add the null terminator manually.
Examples of String Processing Using Arrays
Example 1: Counting vowels in a string
#include <stdio.h>
#include <string.h>
#include <ctype.h> // For tolower()
int countVowels(char str[]) {
int count = 0;
int len = strlen(str);
for (int i = 0; i < len; i++) {
char ch = tolower(str[i]); // Convert to lowercase for case-insensitive counting
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
count++;
}
}
return count;
}
int main() {
char text[] = "Hello World!";
int vowelCount = countVowels(text);
printf("Number of vowels in '%s': %d\n", text, vowelCount);
return 0;
}
Example 2: Reversing a String
#include <stdio.h>
#include <string.h>
void reverseString(char str[]) {
int len = strlen(str);
int i, j;
char temp;
for (i = 0, j = len - 1; i < j; i++, j--) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
int main() {
char text[] = "Reverse me!";
printf("Original string: %s\n", text);
reverseString(text);
printf("Reversed string: %s\n", text);
return 0;
}
Example 3: Checking if a string is a palindrome.
#include #include #include #include bool isPalindrome(char str[]) {
int len = strlen(str);
int i, j;
// Convert string to lowercase and remove non-alphanumeric characters (optional)
char cleanStr[len + 1]; // +1 for the null terminator
int cleanIndex = 0;
for (i = 0; i < len; i++) {
if (isalnum(str[i])) { // Check if alphanumeric
cleanStr[cleanIndex++] = tolower(str[i]);
}
}
cleanStr[cleanIndex] = '\0'; // Null-terminate the clean string
len = strlen(cleanStr); // Update len to new string length
for (i = 0, j = len - 1; i < j; i++, j--) {
if (cleanStr[i] != cleanStr[j]) {
return false;
}
}
return true;
}
int main() {
char str1[] = "racecar";
char str2[] = "A man, a plan, a canal: Panama";
char str3[] = "hello";
if (isPalindrome(str1)) {
printf("\"%s\" is a palindrome.\n", str1);
} else {
printf("\"%s\" is not a palindrome.\n", str1);
}
if (isPalindrome(str2)) {
printf("\"%s\" is a palindrome.\n", str2);
} else {
printf("\"%s\" is not a palindrome.\n", str2);
}
if (isPalindrome(str3)) {
printf("\"%s\" is a palindrome.\n", str3);
} else {
printf("\"%s\" is not a palindrome.\n", str3);
}
return 0;
}