Labsheet 2 - some sample solutions
This page provides some sample solutions and discussion on
some of the tasks of
Labsheet 2.
- Write programs to print simple patterns.
As each of these tasks is quite short (typically fewer than 6 lines),
we'll write the solution to each inside the main() function of each
program.
As many tasks write twenty lines, and occasionally 10 asterisks,
we'll assume that each program has the same structure:
#include <stdio.h>
#define NLINES 20
#define NSTARS 10
int main(int argc, char *argv[])
{
// print our patterns here
return 0;
}
|
|
- One line containing 10 asterisks.
Well, we could "cheat", and just print a single string:
or do as the task probably wanted:
for(int i=1 ; i <= NSTARS ; i=i+1) {
printf("*");
}
printf("\n");
|
|
- Twenty lines, each line containing 1 asterisk.
for(int i=1 ; i <= NLINES ; i=i+1) {
printf("*\n");
}
|
|
- Twenty lines, each line containing 10 asterisks (i.e. a filled
rectangle of asterisks).
for(int i=1 ; i <= NLINES ; i=i+1) {
printf("**********\n");
}
|
|
or using two nested loops:
for(int i=1 ; i <= NLINES ; i=i+1) {
for(int j=1 ; j <= NSTARS ; j=j+1) {
printf("*");
}
printf("\n");
}
|
|
- Twenty lines, each line containing <line-number> asterisks.
This time, the number of asterisks to print on each line is equal to the
line-number.
Thus our inner loop, controlled by j,
iterates from 1 up to i
(previously 1 up to NSTARS)
and we finally print a newline at the end of each line.
for(int i=1 ; i <= NLINES ; i=i+1) {
for(int j=1 ; j <= i ; j=j+1) {
printf("*");
}
printf("\n");
}
|
|
- The same as iv., except that the asterisks are aligned at the
right.
This time, to print right-aligned,
we need to print a certain number of spaces before
we print any asterisks.
- On line 1 we'll require 19 (= 20-1) spaces followed by 1 asterisk,
- on line 2 we'll require 18 (= 20-2) spaces followed by 2 asterisks,
- and so on.
Thus our outer loop, controlled by i,
will require two inner loops - one to print the spaces
and then another to print the asterisks.
These two loops are not nested.
Because we're writing for loops that introduce their own control
variable,
and because that variable "disappears" after the loop has finished,
it's OK to introduce a new variable named j for each loop.
for(int i=1 ; i <= NLINES ; i=i+1) {
for(int j=1 ; j <= (NLINES-i) ; j=j+1) {
printf(" ");
}
for(int j=1 ; j <= i ; j=j+1) {
printf("*");
}
printf("\n");
}
|
|
- Twenty lines, each line containing <line-number> asterisks
provided the <line-number> is odd.
This task is very similar to part iv),
but we not only print something if the line number is 1, 3, 5, 7...
We could specifically test for each of the odd values of i>,
but there is a far easier way.
Remember that a number is odd if, when it is divided by 2,
there exists a remainder (which will be 1!).
In C we may use the modulus operator,
represented by the percent character '%',
to perform this "perform the division, and find the remainder" operation:
for(int i=1 ; i <= NLINES ; i=i+1) {
if( i%2 == 1 ) {
for(int j=1 ; j <= i ; j=j+1) {
printf("*");
}
printf("\n");
}
}
|
|
- The same as vi., except the asterisks are centred aligned.
- The same as vii., except the "pyramid" is additionally "reflected"
to form a "diamond".
- The same as vii., except only the asterisks at the edge of the
pyramid are printed.
- The same as vii., except the bottom rows of the pyramid are
"interlaced" in reverse order with the top rows.
- A year is a leap year if it is divisible by 400, or if it is
divisible by 4 and not divisible by 100. Write a program that determines
if the year supplied as the single argument to the program is a leap year
or not. For example 1896, 2000, and 2004 are leap years, while 1897, 1900,
and 1902 are not.
Here we'll use the new bool data type of C99 to write a simple
function to return true or false is an indicated year is
a leap year.
We use the modulus operator,
represented by the percent character '%',
to determine if the year is a multiple of values 4, 100, and 400.
Note that we have used many parentheses (probably more than strictly necessary)
to aid readability of the condition.
#include <stdbool.h>
static bool leap(int year)
{
if(((year % 4) == 0) && ( (year % 100) || ((year % 400)==0) ))
return true;
else
return false;
}
|
|
Even the developed function can be simplified.
Instead of explicitly returning true or false,
we can "immediately" return the value of the condition,
with the single statement:
return(((year % 4) == 0) && ( (year % 100) || ((year % 400)==0) ));
- Consider the following statement: a child's parents promise to
give the child $2 on her 12th birthday and double the gift on every
subsequent birthday until the gift exceeds $1000, at which time the amount
would be capped at $1000 and remain constant there-after (yes, the child's
parents are generous!). Write a program to calculate the size of the gift
at any given age and the total received by the child up to that age.
There's not really much difficulty with this task;
a loop containing some conditional evaluation,
basic integer artithmetic,
and the printing of 3 integer values.
Note that this sample solution is slightly different than the one
presented in the lunchtime tutorial.
#include <stdio.h>
int main(int argc, char *argv[])
{
int gift = 0;
int total = 0;
// ITERATE OVER A SUITABLE RANGE OF AGES
for(int age=1 ; age <= 100 ; age = age+1) {
// ONCE THE CHILD GETS TO 12, THE PARENTS START GIVING
if(age == 12) {
gift = 2;
}
else {
gift = gift * 2;
}
// IF THE YEARLY GIFT EXCEEDS $1000, CAP IT AT $1000
if(gift > 1000) {
gift = 1000;
}
// CALCULATE TOTAL GIFT, AND PRINT THE YEARLY DETAILS
total = total + gift;
printf("age=%d, thisyear=$%d, total=$%d\n", age, gift, total);
}
return 0;
}
|
|
- Write a program to reverse the digits of a positive integer number
supplied as the single argument to the program. For example, if the number
is 1234, the reversed number should be 4321. To reverse the digits,
"decompose" the number into two parts: the units digit (found by % 10),
and the multiples of ten (found by / 10) and repeat the process on the
multiples of ten part. Your function should return the reversed number,
not simply print it out.
- Write a program that determines the minimum, maximum, and average
of the (assumed to be numerical) arguments supplied to the program.
- Write a program that prints out the ordinal description of the
(assumed to be numerical) arguments supplied to the program. For example:
csse2100% ./myprog 1 6 11 12 21 22 23
1st
6th
11th
12th
21st
22nd
23rd
There's no "automatic" way to print this,
other than to perform an analysis of which integer values are
followed by which suffix:
st, nd, rd, or th.
When used in applications such as the printing of calendar dates,
a function to print these suffixes can make your application much friendlier.
static void ordinal(int value)
{
if(value >= 4 && value <= 20) {
printf("%dth\n", value); // 13th
}
else {
int rem = value % 10;
if(rem == 1) {
printf("%dst\n", value); // 21st
}
else if(rem == 2) {
printf("%dnd\n", value); // 22nd
}
else if(rem == 3) {
printf("%drd\n", value); // 43rd
}
else {
printf("%dth\n", value); // 50th
}
}
}
|
|
- Write a program that prints out the "byte size" description of the
(assumed to be numerical) arguments supplied to the program. For example:
csse2100% ./myprog 1 1200 2444555 5666777888
1Byte
1KByte
2MByte
5GByte
This task looks simple enough,
until we realize that the last argument (when considered as an integer)
is bigger than can be represented in the standard int datatype on
our labs' PowerPCs (for Mac-OSX) or Pentiums (for Linux or Windows) -
those architectures will employ a 32-bit value to hold integers,
giving a maximum value of 2147483647.
Instead we can use a new feature of C99,
the 64-bit integer datatype named int64_t,
which is defined in the standard header file <stdint.h>.
This datatype supports values up to 9223372036854775807
(should be enough!).
While we can perform all "standard" arithmetic on the int64_t values,
C99 doesn't provide a whole new set of functions to support them,
so we often need to write our own.
Two functions to support this task are provided below,
and may just be called from main().
We need to perform basic tests and printing,
similar to that of the previous task.
Incidently (though not needed for this task),
to print an int64_t value, we can write:
printf("%lld\n", bigvalue);
Then we just need to remember our powers of two:
210 is Kilo...,
220 is Mega...,
230 is Giga...,
240 is Tera...
#include <stdint.h>
#include <ctype.h>
static int64_t string_to_big_int(char string[])
{
int i = 0;
int64_t result = 0;
while( isdigit(string[i] )) {
result = result * 10 + (string[i] - '0');
i = i+1;
}
return result;
}
static int64_t big_power_of_2(int power)
{
int64_t result = 1;
for(int i=1 ; i<=power ; i=i+1) {
result = result * 2;
}
return result;
}
|
|
- Write a program that prints out all "roman numeral" equivalents of
the numbers between 1 and the single argument supplied to the program.
|
Top of Page
|
|
CRICOS Provider Code: 00126G
|
|
|