Due 3 November 7 pm
Resources and links
-
activity1.c
-
activity2.c
-
activity3.c
-
activity4.c
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?
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:
- 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
- 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.
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:
- 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
- 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.
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.
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.