UWA Logo Computer Science & Software Engineering
C Programming (CITS1210) - Labsheet 2 sample solutions
   Faculty Home  |  CSSE Home  |  csentry  |  CITS1210  |  help1210

Labsheet 2 - some sample solutions

This page provides some sample solutions and discussion on some of the tasks of Labsheet 2.
  1. 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;
    }
    

    1. One line containing 10 asterisks.

      Well, we could "cheat", and just print a single string:

      
      printf("*********\n");
      

      or do as the task probably wanted:

      
      for(int i=1 ; i <= NSTARS ; i=i+1) {
          printf("*");
      }
      printf("\n");
      

    2. Twenty lines, each line containing 1 asterisk.

      
      for(int i=1 ; i <= NLINES ; i=i+1) {
          printf("*\n");
      }
      

    3. 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");
      }
      

    4. 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");
      }
      

    5. 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.

      1. On line 1 we'll require 19 (= 20-1) spaces followed by 1 asterisk,
      2. on line 2 we'll require 18 (= 20-2) spaces followed by 2 asterisks,
      3. 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");
      }
      

    6. 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");
          }
      }
      

    7. The same as vi., except the asterisks are centred aligned.

    8. The same as vii., except the "pyramid" is additionally "reflected" to form a "diamond".

    9. The same as vii., except only the asterisks at the edge of the pyramid are printed.

    10. The same as vii., except the bottom rows of the pyramid are "interlaced" in reverse order with the top rows.

  2. 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) ));
    
  3. 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;
    }
    

  4. 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.

  5. Write a program that determines the minimum, maximum, and average of the (assumed to be numerical) arguments supplied to the program.

  6. 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
            }
        }
    }
    

  7. 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;
    }
    

  8. 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