C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
176: Implementing Linear Search
Let's say we're building a simple inventory system for a small shop. We've got an array of product IDs, and we need a way to check if a specific ID exists in that list so we can pull up the product details. Since the list isn't sorted—new items just get tacked onto the end—we can't do anything fancy. We just have to look at every single item until we find what we're looking for. This is what we call a Linear Search.
Just walking through the list
I'll start with the most basic approach: a simple loop. I've got a handful of IDs here, and I want to find ID 702.
int productIds[] = {101, 505, 702, 303, 808};
int target = 702;
for (int i = 0; i < 5; i++) {
if (productIds[i] == target) {
printf("Found it!\n");
}
}
That works, but it's a bit naive. If 702 is the second element in a list of a million items, my code will still check the other 999,998 elements even though it already found the answer. That's just wasted CPU cycles. I should stop the moment I hit the target.
Stopping early and capturing the location
In a real program, simply printing "Found it!" isn't helpful. I need to know where the item is—the index—so I can use that index to look up the product's price or description in a parallel array. I'll use a variable to store the index and a break statement to kill the loop early.
int productIds[] = {101, 505, 702, 303, 808};
int target = 702;
int foundIndex = -1; // Use -1 to signify "not found"
for (int i = 0; i < 5; i++) {
if (productIds[i] == target) {
foundIndex = i;
break;
}
}
if (foundIndex != -1) {
printf("Product found at index %d\n", foundIndex);
} else {
printf("Product not in inventory.\n");
}
I chose -1 as the default for foundIndex because array indices in C start at 0. Any negative number is a safe "sentinel value" to tell me the search failed. If I had initialized it to 0, and the item was actually at index 0, I wouldn't be able to tell if the search succeeded or if the variable just stayed at its default.
Turning it into a reusable tool
Hardcoding the array size (like i < 5) is a recipe for bugs. If I add a sixth product to the array, I have to hunt down every loop in my code and change the number. I'll wrap this logic into a function. Remember, in C, when you pass an array to a function, it decays into a pointer, so the function has no idea how large the array is. I have to pass the size explicitly.
int linearSearch(int arr[], int size, int target) {
for (int i = 0; i < size; i++) {
if (arr[i] == target) {
return i; // Return the index immediately
}
}
return -1; // We hit the end of the loop without finding anything
}
By returning i immediately, I've effectively combined the "find" and the "break" into one action. It's cleaner and more idiomatic. Now, my main logic can just be a simple if-statement checking the result of this function.
The trade-off
Linear search is the most honest algorithm there is: it doesn't assume anything about the data. But it's slow for large datasets. In big-O notation, we call this O(n) time complexity. If your list grows 10x, the search takes 10x longer. For a few hundred product IDs? It's perfectly fine. For a database of a billion users? You'd be waiting a long time. But before you can move to faster searches, you have to master this one.
📋 Practical Task
Implementing a Temperature Threshold Search
You are writing software for a climate control system. You have an array of temperature readings recorded every hour. Your task is to find the first instance where the temperature hit exactly 25 degrees Celsius to determine when the cooling system first triggered.
Create a program that does the following:
- Defines an array of floats called
readings(e.g.,{21.5, 22.1, 24.8, 25.0, 25.3, 24.9}). - Implements a function
int findFirstOccurrence(float arr[], int size, float target)that returns the index of the first match or -1 if not found. - In
main, call this function to search for25.0. - Print the index if found, or a message saying "Threshold not reached" if it wasn't.
There are no comments for now.