COMP1911 23T2 Introduction to Programming
    Note: The tutorial questions are designed so that your tutor can choose a selection of questions to go through during class and leave the rest for you to use for your own home study.

    1. Which of the following are valid variable names in C? Which are not? Which variable names conform to the Style Guide used in this subject?

      • THX1138 Valid in C , but does not conform to the style guide
      • 2for1 Invalid
      • mrBean Valid in C and conforms to the style guide
      • My Space Invalid
      • still_counting Valid in C , but does not conform to the style guide
      • ^oo^ Invalid
      • _MEMLIMIT Valid in C , but does not conform to the style guide
    2. C is a typed language. What does this mean? Why is this useful?

      In a typed language, program entities such as variables, functions(we have not really seen these yet), etc. are declared to be of particular types. Giving a variable a type lets the compiler determine the amount of storage space (memory) to set aside for storing values in the variable. It also 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. The only types we have considered so far are int and double, but we will see more types soon.
    3. What is the most likely cause of the following compile time error and how would you fix it?

      example.c: In function 'main':
      example.c:4:5: error: 'num' undeclared (first use in this function)
           num = 3;
           ^
      example.c:4:5: note: each undeclared identifier is reported only once for each function it appears in
      
      This means that you are using the variable, num on line 4, but you have not declared it. You must declare you variable and give it a type before you use it. Adding line with something like int num; to declare num as an int before you use the variable would work
      int num;
      num = 3;
      etc
      
      You may even wish to declare it and initialise it all on one link is this situation
      int num = 3;
      etc
      

    4. What is an uninitialised variable? What is the value of an uninitialised variable? What sort of problems can be caused by using uninitialised variables in programs?

      An uninitialised variable is a variable that has been declared but has not been give a value yet.
      int x; //At this stage in the program, x is uninitialised
      
      An uninitialised local variable holds an undefined value. It is not legal to examine the value of an uninitialised variable and hence doing so may result in arbitrary behaviour from your program including immediate termination.

      In practice usually the value will be what happens to be stored at the memory address the variable is allocated - which will be seemingly random value. This value may differ between executions and typically will differ between between machines.

    5. What does precedence of an operator mean? Make the precedence explicit in the following expressions by adding parentheses and evalute the expressions:
      1. 3 + 5 * 10 - 12
        ( ( 3 + (5 * 10) ) - 12 ) The result is 41
      2. 3 + 15 % 10 - 12 / 2
        ( ( 3 + (15 % 10) ) - (12 /2) ) The result is 2

        Note: The precedence rules of arithmetic operators in C follow the conventions used in mathematics, as detailed in Chapter 3.1 of Moffat and in C_Basics lecture notes.

    6. 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 type and value of each expression and sub-expression:

      1. 1 / 2 * 500
        All operands and subexpressions and the final expressions are of type int
        1 / 2 = 0; 0 * 500 = 0
      2. 1 / 2.0 * 500
        Because 2.0 is of type double, 1 will be converted to double and then because 0.5 is double, 500 gets converted to double, so the final exression will be of type double
        1/2.0 = 0.5; 0.5 * 500 = 250.0
      3. (17 / 5) * 5 + (17 % 5)
        All operands and subexpressions and the final expressions are of type int
        17 / 5 = 3; 17 % 5 = 2; 3 * 5 = 15; 15 + 2 = 17
      4. (12 - 17) % 6 - 4
        All operands and subexpressions and the final expressions are of type int
        12 - 17 = -5; -5 % 6 = -5; -5 - 4 = -9
      5. 10/(1/2)
        All operands and subexpressions and the final expressions are of type int
        10/(1/2) = 10/0 = ???? division by 0 is illegal. You will get a warning in this example when you compile. If you used dcc you will get an error when you run the program "runtime error: division by zero". If you used gcc you will get an error when you run the program "Floating point exception".
    7. What is wrong with each of the following fragments of code
      1. int num1 = 3;
        int num2 = 8;
        printf("The numbers are %d\n",num1,num2);
        
        There are two variable arguments given, num1 and num2, but only 1 conversion specifier (ie %d)

      2. int num1 = 3;
        int num2 = 8;
        printf("The numbers are %d %d\n",num1);
        
        There is only one variable arguments given, num1 , but there are 2 conversion specifiers (ie %d)

      3. double num1 = 3;
        int num2 = 8;
        printf("The numbers are %d %d\n",num1,num2);
        
        There are 2 conversion specifiers and 2 variable arguments, but num1 is double so the first %d should be changed to a %lf

    8. Suppose I am running the following program and the user types in incorrect input such as "hello". What will the program output?
      int num;
      printf("Enter a number: ");
      scanf("%d",&num);
      printf("Your number was %d\n",num);
      
      The scanf function is expecting to read in an int (%d), so it can't read in the 'h' so it stops and fails. The variable num would be left uninitialised so we would end up printing out a garbage value.

    9. Write a program nextBirthday.c which reads someones age and prints out the age they will turn on their next birthday. Assume they are entering their age as integers.

      For example:

      ./nextBirthday
      Please enter your age: 2
      On your next birthday you will turn 3
      
      Sample solution for nextBirthday
      // A simple program to calculate age next year
      // Author: Angela Finlaysonangf@cse.unsw.edu.au
      // Date: 1/03/2017
      
      
      #include <stdio.h>
      
      int main(void)
      {
          int age;
      
          printf("Please enter your age: ");
          scanf("%d", &age);
      
          printf("On your next birthday you will turn %d\n", age+1);
      
          return 0;
      }
      
      
    10. Write a C program cm2feet.c which reads a height in centimetres and prints it in feet.

      Reminder: there are 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
      // Convert height from centimetres to feet.
      // Author: anonymous
      // Date created: ?
      
      
      #include <stdio.h>
      
      #define INCHES_IN_FOOT  12
      #define CM_IN_INCH      2.54
      
      int main (void) {
          int heightCentimetres;
          int heightFeet;
      
          printf("Enter your height in centimetres: ");
          scanf("%d", &heightCentimetres);
      
          heightFeet = (heightCentimetres / CM_IN_INCH) / INCHES_IN_FOOT;
      
          printf("Your height in feet is %d\n", heightFeet);
      
          return 0;
      }
      
      
      

      Would double variables have been a better choice?

      Double variables would have been a better choice because we lose a lot of precision representing height in feet as an int.
    11. Write a program that reads in a real number and prints out its square-root.

      Hint: Use the math.h library function sqrt. How would you compile this if you were using gcc?

      Sample solution for printSqrt
      // A simple program to calculate the square root
      // Note: This does not check for negative numbers
      // For negative input it will give a result of -nan (not a number)
      // We will learn later how to check for this case.
      // Author: Angela Finlayson angf@cse.unsw.edu.au
      // Date: 1/03/2018
      
      
      #include <stdio.h>
      #include <math.h>
      
      int main(void) {
          double number;
          double result;
      
          printf("Please a real value: ");
          scanf("%lf", &number);
      
          result = sqrt(number);
      
          printf("The square root of %lf is %lf\n",number,result);
      
          return 0;
      }
      
      
      You would compile with gcc using
      gcc -Wall -Werror -O -o printSqrt printSqrt.c -lm
      
      If you were using dcc you would compile as usual.
    12. Consider the following expressions:

      • (x == 4) && (y == 4)
        (5 == 4) && (5 == 4); 0 && 0; 0
        (5 == 4) && (4 == 4); 0 && 1; 0
        (4 == 4) && (3 == 4); 1 && 0; 0
        (4 == 4) && (4 == 4); 1 && 1; 1
        
      • (x == 4) || (y == 4)
        (5 == 4) || (5 == 4); 0 || 0; 0
        (5 == 4) || (4 == 4); 0 || 1; 1
        (4 == 4) || (3 == 4); 1 || 0; 1
        (4 == 4) || (4 == 4); 1 || 1; 1
        
      • !((x == 4) || (y == 4))
        !((5 == 4) || (5 == 4)); !(0 || 0); !0; 1
        !((5 == 4) || (4 == 4)); !(0 || 1); !1; 0
        !((4 == 4) || (3 == 4)); !(1 || 0); !1; 0
        !((4 == 4) || (4 == 4)); !(1 || 1); !1; 0
        
      • (!(x == 4)) && (!(y == 4))
        (!(5 == 4)) && (!(5 == 4)); !0 && !0; 1 && 1; 1
        (!(5 == 4)) && (!(4 == 4)); !0 && !1; 1 && 0; 0
        (!(4 == 4)) && (!(3 == 4)); !1 && !0; 0 && 1; 0
        (!(4 == 4)) && (!(4 == 4)); !1 && !1; 0 && 0; 0
        

      What do each of the expressions evaluate to given the following values of x and y

      • x = 5; y = 5;
      • x = 5; y = 4;
      • x = 4; y = 3;
      • x = 4; y = 4;

      Compare the evaluation of the last 2 expressions on the given inputs. What do you notice?

      The output is the same for the last 2 expressions. This is because they are logically equivalent. Note: (Not examinable but good to know), this is called De Morgan's law - assume we have conditions P and Q
      ! (P || Q) is the same as !P && !Q
      ! (P && Q) is the same as !P || !Q
      

    13. What is the role of if statements in programs?
      If statements allow branching in programs, i.e., selecting and executing different blocks of code according to certain conditions.
    14. Write a program odd_even.c that reads in an integer and prints out whether it is odd or even. For example:
      ./odd_even
      Please enter an integer: 42
      EVEN
      ./odd_even
      Please enter an integer: 1
      ODD
      ./odd_even
      Please enter an integer: -3
      ODD
      ./odd_even
      Please enter an integer: 0
      EVEN
      
      Sample solution 1 for odd_even.c
      #include <stdio.h>
      
      int main(void)
      {
          int num;
      
          printf("Please enter an integer: ");
          scanf("%d", &num);
      
          if (num % 2 ==  0) {
              printf("EVEN\n");
          } else {
              printf("ODD\n");
          }
      
          return 0;
      }
      
      
      Another possible solution for odd_even.c
      #include <stdio.h>
      
      // If num is odd (and positive) then num % 2 will evaluate to 1 which also means true
      // So the first condition could be written as
      // if(num % 2 || num % 2 == -1)
      // As a beginner the condition used below is clearer and encouraged
      
      int main(void)
      {
          int num;
      
          printf("Please enter an integer: ");
          scanf("%d", &num);
      
      
          //Note: %2 of a negative odd number gives -1
          if (num % 2 == 1 || num % 2 == -1) {
              printf("ODD\n");
          } else {
              printf("EVEN\n");
          }
      
          return 0;
      }
      
      
    15. Write a program classifyNumber.c that reads in an integer and prints out whether it is odd or even and also whether it is positive, negative or zero. For example:
      ./classifyNumber
      Please enter an integer: 42
      EVEN, POSITIVE
      ./classifyNumber
      Please enter an integer: 1
      ODD, POSITIVE
      ./classifyNumber
      Please enter an integer: -3
      ODD, NEGATIVE
      ./classifyNumber
      Please enter an integer: 0
      EVEN, ZERO
      ./classifyNumber
      Please enter an integer: -2
      EVEN, NEGATIVE
      
      
      Sample solution for classifyNumber.c
      #include <stdio.h>
      
      
      int main(void)
      {
          int num;
      
          printf("Please enter an integer: ");
          scanf("%d", &num);
      
          if (num % 2 == 0) {
              printf("EVEN, ");
          } else {
              printf("ODD, ");
          }
      
          if (num == 0) {
              printf("ZERO\n");
          } else if (num < 0) {
              printf("NEGATIVE\n");
          } else {
              printf("POSITIVE\n");
          }
      
          return 0;
      }
      
      
    16. Write a program pass_fail.c that reads in an integer and prints out "PASS" if the integer is between 50 and 100 (exclusive) and fail if it is between 49 and 0 (exclusive). It should print out ERROR if the number is less than 0, more than 100, or if the user does not enter a number. For example:
      ./pass_fail
      Please enter your mark: 42
      FAIL
      ./pass_fail
      Please enter your mark: 50
      PASS
      ./pass_fail
      Please enter your mark: 256
      ERROR
      
      Sample solution 1 for pass_fail.c
      #include <stdio.h>
      
      int main(void)
      {
          int mark;
      
          printf("Please enter your mark: ");
          scanf("%d", &mark);
      
          if (mark <= 0) {
              printf("ERROR\n");
          } else if (mark > 100) {
              printf("ERROR\n");
          } else if (mark >= 50) {
              printf("PASS\n");
          } else {
              printf("FAIL\n");
          }
      
          return 0;
      }
      
      
      Another possible solution for pass_fail.c
      #include <stdio.h>
      
      int main(void)
      {
          int mark;
      
          printf("Please enter your mark: ");
          scanf("%d", &mark);
      
          if (mark <= 0 || mark >= 100) {
              printf("ERROR\n");
          } else if (mark < 50) {
              printf("FAIL\n");
          } else {
              printf("PASS\n");
          }
      
          return 0;
      }
      
      
    17. Write a C program is_triangle.c to read 3 integers and indicate whether they can be the sides of a triangle.

      Reminder: 3 numbers can be the sides of a triangle if the sum of any two of the numbers is larger than the third.

      Sample solution for is_triangle.c
      #include <stdio.h>
      
      int main(void)
      {
          int a, b, c;
      
          printf("Please enter three integers: ");
          scanf("%d %d %d", &a, &b, &c);
      
          if ((a + b > c) && (a + c > b) && (b + c > a)) {
              printf("Numbers are the sides of a triangle\n");
          } else {
              printf("Numbers are not the sides of a triangle\n");
          }
      
          return 0;
      }
      
      
    18. At a theme park there are rides that anyone who is 120cm or over can go on ("Green Rides"), rides that anyone who is 130cm or over can go on ("Yellow Rides") and rides that anyone who is 140cm or over can go on ("Red Rides"). Write an application that asks the user to enter their height to the nearest cm and displays all the types of rides they can go on.For example:

      ./rides
      Please enter your height: 130
      Green Rides
      Yellow Rides
      ./rides
      Please enter your height: 119
      Sorry, no rides are safe for you!
      ./rides
      Please enter your height: 256
      Green Rides
      Yellow Rides
      Red Rides
      
      Sample solution for rides.c
      #include <stdio.h>
      
      #define GREEN_HEIGHT 120
      #define YELLOW_HEIGHT 130
      #define RED_HEIGHT 140
      
      int main(void)
      {
          int height;
      
          printf("Please enter your height: ");
          scanf("%d", &height);
      
          if(height < GREEN_HEIGHT) {
              printf("Sorry, no rides are safe for you!\n");
          }
      
          if (height >= GREEN_HEIGHT) {
              printf("Green Rides\n");
          }
      
          if (height >= YELLOW_HEIGHT) {
              printf("Yellow Rides\n");
          }
      
          if (height >= RED_HEIGHT) {
              printf("Red Rides\n");
          }
      
          return 0;
      }
      
      
    19. 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!