Systems Programming (XMUT)
Exercise 2: Intermediate C Program Development

days Due 3 November 7 pm

To Submit:

  • activity1.c
  • activity2.c
  • activity3.c
  • activity4.c

ALERT! Do not rename these files.

Debugging in Code::Blocks

In the previous exercise, you learned basic debugging by looking at compiler messages. There are many cases where this form of debugging is not sufficient. For instance, a program may compile without errors and warnings, but during runtime, it crashes or behaves unexpectedly on certain inputs. This situation requires the use of a more advanced tool.

The debugger operates by examining your code as it runs, showing you what’s happening, both internally to the program as well as the output.

Exercises

Download a copy of the base source files used in the activities from Zip Files

Activity 1: Debugging [50 Marks]

Import the base source file activity1.c into the Code::Blocks and open it. activity1.c should contain the following code:

1 #include <stdio.h>
2 #include <ctype.h>
3
4 void capitalize(char *str)
5 {
6   int i=0;
7   while(str[i] != '\0') {
8      if (islower(str[i])) str[i] = toupper(str[i]);
9      i++;
10   }
11 }
12
13 int main(void)
14 {
15    char *s = "ABC123 is the most common password";
16    capitalize(s);
17    printf("%s\n", s);
18    return 0;
19 }

Save the file as activity1.c. Compile and run the program. The program should crash, with the rather terse message Segmentation fault.

Now, you will need to find out why the program is crashing. Recompile and run the program with the debugger. What line does the program crash? What is the value of i when the program crashes? Why do you think the program crashes?

right Fix the program so that it will not crash. You are only allowed to change one line: line 15 to be exact. Submit the fixed program to the Assessment System for marking. Click Run checks to initiate auto-marking.

Activity 2: Structure [15 Marks]

Import the base source file activity2.c into the Code::Blocks and open it. activity2.c should contain the following code:

#include <stdio.h>

// Define structure record

// Implement print_record() function

int main(void)
{
   struct record rec;
   
   scanf("%s %d %f", rec.name, &rec.age, &rec.height);
   print_record(rec);
   return 0;
}

Study the source file and do the following within the file:

  1. Define a structure named record with the following fields:
    • name: a string variable that can hold 40 characters (including null terminator)
    • age: a short integer
    • height: a single precision floating point number
  2. Implement a function named print_record() which accepts a single argument of type struct record and does not return anything. The function should use printf() to display the name, age and height fields. The output must follow this format:
Name⍽⍽:⍽name
Age⍽⍽⍽:⍽age
Height:⍽height
Note that ⍽ denotes a single space character. The height should be displayed with the precision of 2 decimal places. As your submission will be auto-marked, do not add any extra characters in the output, including \n after the last line.

right Compile and run the program. If you are happy with the program, submit it to the Assessment System for marking. Click Run checks to initiate auto-marking.

Activity 3: Passing Pointer to a Structure [10 Marks]

One disadvantage of the code in Activity 2 is that the entire structure is copied to the function. This can be highly inefficient, especially when the structure being passed is large. An approach to address this issue is to pass a pointer to a structure.

In this activity, you will repeat Activity 2, except that you will pass a pointer to a structure in the function invocation. To begin, import the base source file activity3.c into the Code::Blocks and open it. activity3.c should contain the following code:

#include <stdio.h>

// Define structure record

// Implement print_record_ptr() function

int main(void)
{
   struct record rec;

   scanf("%s %d %f", rec.name, &rec.age, &rec.height);
   print_record_ptr(&rec);
   return 0;
}

Study the source file and do the following within the file:

  1. Define a structure named record with the following fields:
    • name: a string variable that can hold 40 characters (including null terminator)
    • age: a short integer
    • height: a single precision floating point number
  2. Implement a function named print_record_ptr() which accepts a single argument of type pointer to struct record and does not return anything. The function should use printf() to display the name, age and height fields. The output must follow this format:
Name⍽⍽:⍽name
Age⍽⍽⍽:⍽age
Height:⍽height

Note that that ⍽ denotes a single space character. The height should be displayed with the precision of 2 decimal places. Do not add any extra characters in the output, including \n after the last line.

right Compile and run the program. If you are happy with the program, submit it to the Assessment System for marking. Click Run checks to initiate auto-marking.

Activity 4: Pointers [25 Marks]

In this activity, you will use pointers to traverse an array and access array elements. Begin by importing the base source file activity4.c into the Code::Blocks and open it. activity4.c should contain the following code:

#include <stdio.h>

#define MAX   100

// Implement find_max() function using pointer
int *find_max(int *a, int alen)
{
   // These variables should be enough. Do not declare any other variable.
   int *max = a, *p = a;

   // Use pointer p to iterate over arrays and access arrays elements
   // Use max to point to the latest maximum value found
   // Use either while-loop or for-loop to iterate


   // max should point to the maximum
   return max;
}

int main(void)
{
   int n, array[MAX];
   scanf("%d", &n);
   for(int i=0; i<n; i++)
      scanf("%d", array+i);
   int *max = find_max(array, n);
   printf("%d", *max);
   return 0;
}

Study the source file and implement the find_max() function using pointers. The function accepts two input arguments: the first argument is a pointer to the first element of the array, and the second argument specifies the number of elements in the array. The function must return a pointer to the element with maximum value.

right Compile and run the program. If you are happy with the program, submit it to the Assessment System for marking. Click Run checks to initiate auto-marking.