C Pointer and Array Programming Exercises
Exercise 1: Finding Minimum and Maximum Values in Arrays
Implementation 1: Using Pointer Parameters
#include <stdio.h>
#define N 5
void input_data(int arr[], int n);
void display_data(int arr[], int n);
void find_min_max(int arr[], int n, int *pmin, int *pmax);
int main() {
int numbers[N];
int minimum, maximum;
printf("Enter %d integers:\n", N);
input_data(numbers, N);
printf("Original data: \n");
display_data(numbers, N);
printf("Processing data...\n");
find_min_max(numbers, N, &minimum, &maximum);
printf("Results:\n");
printf("min = %d, max = %d\n", minimum, maximum);
return 0;
}
void input_data(int arr[], int n) {
int i;
for (i = 0; i < n; ++i)
scanf("%d", &arr[i]);
}
void display_data(int arr[], int n) {
int i;
for (i = 0; i < n; ++i)
printf("%d ", arr[i]);
printf("\n");
}
void find_min_max(int arr[], int n, int *pmin, int *pmax) {
int i;
*pmin = *pmax = arr[0];
for (i = 0; i < n; ++i) {
if (arr[i] < *pmin)
*pmin = arr[i];
else if (arr[i] > *pmax)
*pmax = arr[i];
}
}
Analysis:
- The function finds both minimum and maximum values from the input array
- Both pointers initially point to the first element of the array
Implementation 2: Returning Pointer to Maximum
#include <stdio.h>
#define N 5
void input_data(int arr[], int n);
void display_data(int arr[], int n);
int *locate_maximum(int arr[], int n);
int main() {
int numbers[N];
int *pmax;
printf("Enter %d integers:\n", N);
input_data(numbers, N);
printf("Original data: \n");
display_data(numbers, N);
printf("Processing data...\n");
pmax = locate_maximum(numbers, N);
printf("Results:\n");
printf("max = %d\n", *pmax);
return 0;
}
void input_data(int arr[], int n) {
int i;
for (i = 0; i < n; ++i)
scanf("%d", &arr[i]);
}
void display_data(int arr[], int n) {
int i;
for (i = 0; i < n; ++i)
printf("%d ", arr[i]);
printf("\n");
}
int *locate_maximum(int arr[], int n) {
int max_index = 0;
int i;
for (i = 0; i < n; ++i)
if (arr[i] > arr[max_index])
max_index = i;
return &arr[max_index];
}
Analysis:
- This function returns the address of the maximum element in the array
- The return value is a pointer to an integer
Exercise 2: String Operations with Arrays vs Pointers
Implementation 1: Character Arrays
#include <stdio.h>
#include <string.h>
#define N 80
int main() {
char s1[N] = "Learning makes me happy";
char s2[N] = "Learning makes me sleepy";
char buffer[N];
printf("sizeof(s1) vs. strlen(s1): \n");
printf("sizeof(s1) = %d\n", sizeof(s1));
printf("strlen(s1) = %d\n", strlen(s1));
printf("\nbefore swap: \n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
printf("\nswapping...\n");
strcpy(buffer, s1);
strcpy(s1, s2);
strcpy(s2, buffer);
printf("\nafter swap: \n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
return 0;
}
Analysis:
- sizeof(s1) returns 80 (total allocated space for the array)
- strlen(s1) returns 23 (actual string length without null terminator)
- Direct asssignment like
s1 = "string";is illegal for character arrays - The swap operation works because strcpy copies actual contant
Implementation 2: Character Pointers
#include <stdio.h>
#include <string.h>
#define N 80
int main() {
char *s1 = "Learning makes me happy";
char *s2 = "Learning makes me sleepy";
char *tmp;
printf("sizeof(s1) vs. strlen(s1): \n");
printf("sizeof(s1) = %d\n", sizeof(s1));
printf("strlen(s1) = %d\n", strlen(s1));
printf("\nbefore swap: \n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
printf("\nswapping...\n");
tmp = s1;
s1 = s2;
s2 = tmp;
printf("\nafter swap: \n");
printf("s1: %s\n", s1);
printf("s2: %s\n", s2);
return 0;
}
Analysis:
- sizeof(s1) returns 4 or 8 (size of pointer variable on the system)
- strlen(s1) returns 23 (length of the string literal)
- No issues with this approach
- The swap exchanges pointer values, not the string data itself
Exercise 3: Two-Dimensional Arrays and Pointers
#include <stdio.h>
int main() {
int matrix[2][4] = {{1, 9, 8, 4}, {2, 0, 4, 9}};
int i, j;
int *ptr_element;
int (*ptr_row)[4];
printf("Output 1: Using array name with indices\n");
for (i = 0; i < 2; ++i) {
for (j = 0; j < 4; ++j)
printf("%d ", matrix[i][j]);
printf("\n");
}
printf("\nOutput 2: Using element pointer\n");
for (ptr_element = &matrix[0][0], i = 0; ptr_element < &matrix[0][0] + 8; ++ptr_element, ++i) {
printf("%d ", *ptr_element);
if ((i + 1) % 4 == 0)
printf("\n");
}
printf("\nOutput 3: Using row pointer\n");
for (ptr_row = matrix; ptr_row < matrix + 2; ++ptr_row) {
for (j = 0; j < 4; ++j)
printf("%d ", *(*ptr_row + j));
printf("\n");
}
return 0;
}
Analysis:
- ptr_element is a pointer to a single integer element
- ptr_row is a pointer to an array of 4 integers (array pointer)
Exercise 4: Character Replacement in Strings
#include <stdio.h>
#define N 80
void substitute(char *str, char old_char, char new_char);
int main() {
char text[N] = "Programming is difficult or not, it is a question.";
printf("Original text: \n");
printf("%s\n", text);
substitute(text, 'i', '*');
printf("Modified text: \n");
printf("%s\n", text);
return 0;
}
void substitute(char *str, char old_char, char new_char) {
while (*str) {
if (*str == old_char)
*str = new_char;
str++;
}
}
Analysis:
- The function replaces all occurrences of old_char with new_char
- Works correctly with pointer arithmetic
Exercise 5: String Truncation
#include <stdio.h>
#define N 80
char* truncate_string(char* str, char delimiter);
int main() {
char str[N];
char ch;
while (printf("Input string: "), gets(str) != NULL) {
printf("Enter delimiter character: ");
ch = getchar();
printf("Truncating...\n");
truncate_string(str, ch);
printf("Truncated string: %s\n\n", str);
getchar();
}
return 0;
}
char* truncate_string(char* str, char delimiter) {
while (*str) {
if (*str == delimiter) {
*str = '\0';
break;
}
str++;
}
return str;
}
-analysis:
- The function truncates the string at the first occurrence of the delimiter
- The leftover newline from getchar() needs to be consumed with an additional getchar() call
Exercise 6: ID Number Validation
#include <stdio.h>
#include <string.h>
#define N 5
int validate_id(char* str);
int main() {
char* id_list[N] = {
"31010120000721656X",
"3301061996X0203301",
"53010220051126571",
"510104199211197977",
"53010220051126133Y"
};
int i;
for (i = 0; i < N; ++i)
if (validate_id(id_list[i]))
printf("%s\tTrue\n", id_list[i]);
else
printf("%s\tFalse\n", id_list[i]);
return 0;
}
int validate_id(char* str) {
int position = 0;
while (*str) {
position++;
if (*str < '0' || *str > '9') {
if (*str != 'X' || position != 18) {
return 0;
}
}
str++;
}
if (position != 18) {
return 0;
}
return 1;
}
Enalysis:
- Validates Chinese ID numbers (should be 18 characters)
- Allows digits 0-9, and only allows 'X' at position 18
Exercise 7: Caesar Cipher Encoding and Decoding
#include <stdio.h>
#define N 80
void encode(char* str, int shift);
void decode(char* str, int shift);
int main() {
char text[N];
int n;
printf("Enter English text: ");
gets(text);
printf("Enter shift value: ");
scanf("%d", &n);
printf("Encoded text: ");
encode(text, n);
printf("%s\n", text);
printf("Decoded text: ");
decode(text, n);
printf("%s\n", text);
return 0;
}
void encode(char* str, int shift) {
while (*str) {
if (*str >= 'A' && *str <= 'Z') {
*str = (*str - 'A' + shift % 26 + 26) % 26 + 'A';
}
else if (*str >= 'a' && *str <= 'z') {
*str = (*str - 'a' + shift % 26 + 26) % 26 + 'a';
}
str++;
}
}
void decode(char* str, int shift) {
while (*str) {
if (*str >= 'A' && *str <= 'Z') {
*str = (*str - 'A' + 26 - shift % 26) % 26 + 'A';
}
else if (*str >= 'a' && *str <= 'z') {
*str = (*str - 'a' + 26 - shift % 26) % 26 + 'a';
}
str++;
}
}
Analysis:
- Implements Caesar cipher for letter substitution
- Handles both uppercase and lowercase letters
- Wraps around the alphabet using modulo arithmetic
Exercise 8: Command Line Arguments
Implementation 1: Simple Echo
#include <stdio.h>
int main(int argc, char* argv[]) {
int i;
for (i = 1; i < argc; ++i)
printf("hello, %s\n", argv[i]);
return 0;
}
Implementation 2: Sorting Arguments
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
int swapped;
char* temp;
int i, j;
for (i = 0; i < argc - 1; i++) {
swapped = 1;
for (j = 0; j < argc - i - 1; j++) {
if (strcmp(argv[j], argv[j + 1]) > 0) {
temp = argv[j];
argv[j] = argv[j + 1];
argv[j + 1] = temp;
}
swapped = 0;
}
if (swapped) break;
}
for (i = 1; i < argc; ++i)
printf("hello, %s\n", argv[i]);
return 0;
}
Analysis:
- argc contains the number of command line arguments
- argv[0] is the program name, argv[1] onwards are the actual arguments
- Implements bubble sort to order the arguments alphabetically