COMP1511 19T2
COMP1511 19T2
  1. Tuts from now on will start with code reviews.

    This week your tutor will show you how it is to be done in future weeks.

    Your tutor will nominate a lab pair this week to do next week's code review.

    How a code review works:

    • The reviewees show their code on the projector, and briefly walk through how it works.
    • The class and tutor (the reviewers) give feedback, ask questions, make suggestions. You tutor will show you how to do this at first but then will expect the other reviewers to take over.
    • Reviewers are NOT negative, a review is to be supportive and constructive and helpful to the reviewees.
    • The reviewees should speak very little, just give a brief overview of the code they want reviewed.
    • Let everyone have a turn to speak, don’t dominate the conversation.
    • Contribute and participate, don’t be silent. If you don’t understand anything then that doesn’t mean be silent - it means ASK for an explanation. By asking you are helping the coders to see how to be clearer.
  2. Which of the following are valid variable names in C?

    If they are valid, would they be a good name?

    • THX1138 Valid, not good - doesn't start with a lower-case letter
    • 2for1 Invalid - doesn't start with a letter or underscore
    • mr_bean Valid, good if the variable has something to do with Mr Bean
    • my space Invalid - you can't have spaces in variables names
    • event_counter Valid in C, good
    • ^oo^ Invalid - only letters, numbers and underscore allowed
    • _MEMLIMIT Valid not good - doesn't start with a lower-case letter
    • return Invalid - this is a special keyword in C
  3. C is a typed language. What does this mean? Why is this useful?

    In a typed language, program entities (variables, functions, etc.) are declared to be of particular types. This allows additional checks (type-checking) to be performed that ensure the validity of programs. If a type mismatch is detected, then the programmer is warned by the compiler. Typed code is easier to understand and debug since there are guarantees about the kinds of values that are being manipulated. Giving a variable a type also lets the compiler determine the amount of storage space (memory) to set aside for storing values in the variable.
  4. Write a C program cm2feet.c which reads a height in centimetres and prints it in feet.

    Reminder: there 2.54 centimetres in an inch and 12 inches in a foot.

    Use only int variables.

    Your program should behave like this:

    ./cm2feet
    Enter your height in centimetres: 183
    Your height in feet is 6
    

    Sample solution for cm2feet.c
    // Author: anonymous
    // Date created: ?
    // Convert height from centimetres to feet.
    
    #include <stdio.h>
    
    #define INCHES_IN_FOOT  12
    #define CM_IN_INCH      2.54
    
    int main (void) {
        int height_centimetres;
        int height_feet;
    
        printf("Enter your height in centimetres: ");
        scanf("%d", &height_centimetres);
    
        height_feet = (height_centimetres / CM_IN_INCH) / INCHES_IN_FOOT;
    
        printf("Your height in feet is %d\n", height_feet);
    
        return 0;
    }
    
    
    

    Would double variables have been a better choice?

    Double variables would probably be a better choice because we lose a lot of precision representing height as feet.
  5. Write a C program count42.c which prints the integers 1..42, one per line. For example:
    dcc -o count42 count42.c
    ./count42
    1
    2
    3
    
    Sample solution for count42.c
    // Print the integers 1..42, one per line.
    // COMP1511 tutorial example
    // Andrew Taylor - andrewt@unsw.edu.au
    
    #include <stdio.h>
    
    int main(void) {
        int i;
        
        i = 1;
        while (i <= 42) {
            printf("%d\n", i);
            i = i + 1;
        }
        
        return 0;
    }
    
    
  6. Write a C program count_up.c which reads an integer n and then prints the integers 1..n, one per line. For example:
    dcc -o count_up count_up.c
    ./count_up
    Enter finish: 3
    1
    2
    3
    ./count_up
    Enter finish: 7
    1
    2
    3
    4
    5
    6
    7
    
    Sample solution for count_up.c
    // Print the integers 1..n, one per line.
    // COMP1511 tutorial example
    // Andrew Taylor - andrewt@unsw.edu.au
    // 25/3/2018
    
    #include <stdio.h>
    
    int main(void) {
        int i, finish;
        
        printf("Enter finish: ");
        scanf("%d", &finish);
        
        i = 1;
        while (i <= finish) {
            printf("%d\n", i);
            i = i + 1;
        }
        
        return 0;
    }
    
    
  7. Write a C program range.c which reads integers n and m and then prints the integers n..m, one per line. For example:
    dcc -o range range.c
    ./range
    Enter start: 3
    Enter finish: 7
    3
    4
    5
    6
    7
    
    Sample solution for range.c
    // Print the integer n..m one per line
    // COMP1511 tutorial example
    // Andrew Taylor - andrewt@unsw.edu.au
    
    #include <stdio.h>
    
    int main(void) {
        int i, start, finish;
        
        printf("Enter start: ");
        scanf("%d", &start);
        
        printf("Enter finish: ");
        scanf("%d", &finish);
        
        i = start;
        while (i <= finish) {
            printf("%d\n", i);
            i = i + 1;
        }
        
        return 0;
    }
    
    
  8. Write a C program range7.c which reads 2 integers n and m, and then prints the integers between n and m (including n and m) which are divisible by 7.

    Hint: if x is divisible by 7, then x % 7 == 0

    dcc -o range7 range7.c
    ./range7
    Enter start: 3
    Enter finish: 49
    7
    14
    21
    28
    35
    42
    49
    
    Sample solution for range7.c
    // Print multiples of 7 between two numbers
    // COMP1511 tutorial example
    // Andrew Taylor - andrewt@unsw.edu.au
    
    #include <stdio.h>
    
    int main(void) {
        int i, start, finish;
        
        printf("Enter start: ");
        scanf("%d", &start);
        
        printf("Enter finish: ");
        scanf("%d", &finish);
        
        i = start;
        while (i <= finish) {
            if (i % 7 == 0) {
                printf("%d\n", i);
            }
            i = i + 1;
        }
        
        return 0;
    }
    
    
  9. Write a C program range_divisible.c which reads 3 integers n, m and x then prints the integers between n and m (including n and m) which are divisible by x.
    dcc -o range_divisible range_divisible.c
    ./range_divisible
    Enter start: 20
    Enter finish: 100
    Enter divisor: 13
    26
    39
    52
    65
    78
    91
    ./range_divisible
    Enter start: 80
    Enter finish: 120
    Enter divisor: 5
    80
    85
    90
    95
    100
    105
    110
    115
    120
    
    Sample solution for range_divisible.c
    // Print multiples of given number between two numbers
    // COMP1511 tutorial example
    // Andrew Taylor - andrewt@unsw.edu.au
    
    #include <stdio.h>
    
    int main(void) {
        int i, start, finish, divisor;
        
        printf("Enter start: ");
        scanf("%d", &start);
        
        printf("Enter finish: ");
        scanf("%d", &finish);
        
        printf("Enter divisor: ");
        scanf("%d", &divisor);
        
        i = start;
        while (i <= finish) {
            if (i % divisor == 0) {
                printf("%d\n", i);
            }
            i = i + 1;
        }
        
        return 0;
    }
    
    

    Revision questions

    The remaining tutorial questions are primarily intended for revision - either this week or later in session.

    Your tutor may still choose to cover some of the questions time permitting.

  10. Modify rectangle_area.c from last week so that it reads floating-point (decimal) numbers and prints the area as a floating-point number.
    ./rectangle_area
    Please enter rectangle length: 3.14159
    Please enter rectangle width: 2.71828
    Area = 8.539721
    
    Note carefully the changes.
    A sample solution for rectangle_area.c
    // Compute area of a rectangle using doubles
    // Modified 3/3/2017 by Andrew Taylor (andrewt@unsw.edu.au)
    // as a lab example for COMP1511
    
    // Note this program doesn't check whether
    // the two scanf calls successfully read a number.
    // This is covered later in the course.
    
    #include <stdio.h>
    
    int main(void) {
        double length, width, area;
    
        printf("Please enter rectangle length: ");
        scanf("%lf", &length);
        printf("Please enter rectangle width: ");
        scanf("%lf", &width);
    
        area = length * width;
    
        printf("Area = %lf\n", area);
    
        return 0;
    }
    
    
  11. What is output by the following C program? Why? Make sure you compile the program and run it to confirm your answer.

    #include <stdio.h>
    
    #define FIRST_NUMBER     10
    #define SECOND_NUMBER    20
    #define TOTAL   FIRST_NUMBER + SECOND_NUMBER
    #define AVERAGE TOTAL / 2
    
    int main(void) {
        printf("The average of %d and %d is %d\n",
               FIRST_NUMBER, SECOND_NUMBER, AVERAGE);
    
        return 0;
    }
    

    The average of 10 and 20 is 20

    Notes: Average is not 15, because the compiler replaces AVERAGE with TOTAL/2, then replace this TOTAL by FIRSTNUMBER + SECONDNUMBER and the printf line turns out to be
    printf("...",FIRSTNUMBER,SECONDNUMBER, FIRSTNUMBER + SECONDNUMBER/2);

    We need to fix it for this situation by putting brackets around the expression (FIRST_NUMBER + SECOND_NUMBER) and to be safe in general around (TOTAL / 2) also eg:

    #include <stdio.h>
    
    #define FIRST_NUMBER     10
    #define SECOND_NUMBER    20
    #define TOTAL   (FIRST_NUMBER + SECOND_NUMBER)
    #define AVERAGE (TOTAL / 2)
    
    int main(void) {
        printf("The average of %d and %d is %d\n",
               FIRST_NUMBER, SECOND_NUMBER, AVERAGE);
    
        return 0;
    }
    
  12. The value of C  arithmetic operations depends on the types of the operand. If the types of the operands differ, C automatically converts the types as appropriate.

    Determine the value of each expression and sub-expression:

    1. 1 / 2 * 500
      1 / 2 = 0; 0 * 500 = 0
    2. 1 / 2.0 * 500
      1/2.0 = 0.5; 0.5 * 500 = 250.0
    3. (17 / 5) * 5 + (17 % 5)
      17 / 5 = 3; 17 % 5 = 2; 3 * 5 = 15; 15 + 2 = 17
    4. (12 - 17) % 6 - 4
      12 - 17 = -5; -5 % 6 = -5; -5 - 4 = -9
  13. Write a C program decompose.c that prompts the user to enter an integer, reads it from the input and prints out the number in individual digits. Allow the program to work for input numbers up to 5 digits, i.e. up to 99999. You should be able to write this program using some divisions and remainder (modulo '%') operations, if statements and simple comparisons.

    Your program should behave as follows:

    ./decompose
    Please enter an integer: 25
    You entered 25 which is decomposed: 2 5
    ./decompose
    Please enter an integer: 2825
    You entered 2825 which is decomposed: 2 8 2 5
    ./decompose
    Please enter an integer: 2
    You entered 2 which is decomposed: 2
    

    Your program should handle all integers in range (0 to 99999).

    Hint: use if, divide (/) and mod (%).

    Sample solution for decompose.c
    #include <stdio.h>
    
    int main(void) {
        int val, orig_val;
        printf("Please enter an integer: ");
        scanf("%d", &val);
    
        printf("You entered %d which is decomposed:", val);
        orig_val = val;
    
        if (orig_val > 9999) {
            printf(" %d", val / 10000);
            val = val % 10000;
        }
        if (orig_val > 999) {
            printf(" %d", val / 1000);
            val = val % 1000;
        }
        if (orig_val > 99) {
            printf(" %d", val / 100);
            val = val % 100;
        }
        if (orig_val > 9) {
            printf(" %d", val / 10);
            val = val % 10;
        }
        printf(" %d\n", val);
    
        return 0;
    }
    
    
    A more general solution for decompose.c
    #include <stdio.h>
    
    int main(void) {
        int input;
        printf("Please enter an integer: ");
        scanf("%d", &input);
        printf("You entered %d which is decomposed:", input);
    
        if (input <= 0) {
            // edge case
            printf(" %d", input);
        } else {
            int divisor = 10000; // can generalize this
            int in_number = 0;
            while (divisor != 0) {
                if (input / divisor != 0) {
                    // avoid leading zeroes
                    in_number = 1;
                }
                if (in_number) {
                    printf(" %d", input / divisor);
                }
                input %= divisor;
                divisor /= 10;
            }
        }
    
        printf("\n");
        return 0;
    }
    
    
  14. Discuss the concept of short-circuit evaluation for the C logical operators || and &&. Give examples. Why is this feature useful?

    Short-circuit evaluation means that the operators || and && perform the minimum amount of work required to establish their return value. In particular, if the LHS of || evaluates to true then the RHS is not examined and if the LHS of && evaluates to false then the RHS is not examined. This features means that we can safely write the following: if ((x != 0) && ((y / x) > 10)) {

    If x happens to have the value 0 then the illegal divide by 0 operation will not be performed!