Week 01 Tutorial Questions

Getting Started and Recap!

Command Line Arguments/IO
  1. Consider a program called myprog which is invoked as:

    ./myprog hello there, 'John Shepherd' > myFile
    
    1. What are the values of argc and argv?
    2. Where would the statement printf("%s", argv[1]); place its output?
    3. Where would the statement ch = getchar(); get its input?
C Revision
  1. What is the effect of the following assignment statement?

    int a, b, c, d, e;
    a = b = c = d = e = 0;
    

    Would it make any difference if the assignments were not done?

  2. Consider the following two sets of definitions and statements:

    int x, y;
    char *c, *d, *e, *f;
    
    x = y = 2;
    c = d = "abc";
    e = "xyz"; f = "xyz";
    
    x++;
    *c = 'A';
    
    1. Show the state of the memory after the first set of assignments.
    2. Would anything be different if we had done c = "abc"; d = c;?
    3. Show the state of memory after x++;.
    4. What happens when *c = 'A'; is executed? Why?
  3. Define a swap() function that exchanges two elements in an array

    For an array a[] and two indexes i and j, we could exchange the i'th and j'th elements by the call:

    swap(a, i, j)
    
  4. Consider the following program (adapted from Sedgewick). Don't worry, we will cover assert in the lectures:

    #include <stdlib.h>
    #include <stdio.h>
    #include <assert.h>
    
    int main(int argc, char *argv[]) {
    	int i, j, *a;
    	int N = 0;
    
    	// initialisation
    	assert(argc > 1);
    	sscanf(argv[1], "%d", &N);
    	assert(N > 0);
    	
    	a = malloc(N * sizeof(int));
    	assert(a != NULL);
    	
    	for (i = 2; i < N; i++) {
    		a[i] = 1;
    	}
    
    	// computation
    	for (i = 2; i < N; i++) {
    		if (a[i]) {
    			for (j = i; i * j < N; j++) {
    				a[i * j] = 0;
    			}
    		}
    	}
    
    	// results
    	for (i = 2; i < N; i++) {
    		if (a[i]) {
    			printf("%d\n", i);
    		}
    	}
    	return EXIT_SUCCESS;
    }
    

    Try to answer each of the following questions about this program:

    1. what is the line of code sscanf(argv[1], "%d", &N); doing?
    2. suggest an alternative for the sscanf(...) statement?
    3. for each of the asserts ...
      • describe what error is being checked for and why
      • suggest a better error message than what you get from assert
    4. what are the values of a[0] and a[1] during execution?
    5. why don't the values of a[0] and a[1] matter?
    6. what is the purpose of this program?
New C Syntax
  1. Describe the difference in behaviour (and in the final result) of the following two switch statements:

    // S1
    switch (ch) {
        case 'a': printf("eh? "); break;
        case 'e': printf("eee "); break;
        case 'i': printf("eye "); break;
        case 'o': printf("ohh "); break;
        case 'u': printf("you "); break;
    }
    printf("\n");
    
    // S2
    switch (ch) {
        case 'a': printf("eh? ");
        case 'e': printf("eee ");
        case 'i': printf("eye ");
        case 'o': printf("ohh ");
        case 'u': printf("you ");
    }
    printf("\n");
    

    What will be printed for each of the following values for ch: 'u', 'o', 'e'?

  2. Consider the following function to convert a number in the range 0..6 into a weekday name. 0 returns "Sun", 1 returns "Mon", 2 returns "Tue", and so on.

    char *numToDay(int n) {
    	assert(0 <= n && n <= 6);
    	char *day;
    	if (n == 0) {
    		day = "Sun";
    	} else if (n == 1) {
    		day = "Mon";
    	} else if (n == 2) {
    		day = "Tue";
    	} else if (n == 3) {
    		day = "Wed";
    	} else if (n == 4) {
    		day = "Thu";
    	} else if (n == 5) {
    		day = "Fri";
    	} else if (n == 6) {
    		day = "Sat";
    	}
    	return day;
    }
    

    Suggest at least two alternative and more concise ways of achieving the same result. Include the assert(...) in each case.

    For each function, including the one above, explain what would happen if the assert(...) was removed and the function was invoked via numToDay(7).

  3. Give an if statement equivalent to the following switch statement:

    assert(islower(ch));
    switch (ch) {
    	case 'a':
    	case 'e':
    	case 'i':
    	case 'o':
    	case 'u':
    		printf("vowel"); break;
    	default:
    		printf("consonant"); break;
    }
    
  4. Use a conditional expression to replace the if in the following code:

    int ch = getchar();
    
    char *type;
    if (isdigit(ch)) {
        type = "digit";
    } else {
        type = "non-digit";
    }
    
    printf("'%c' is a %s\n", ch, type);
    
  5. What while loop is equivalent to the following for statement:

    for (ch = getchar(); ch != EOF; ch = getchar()) {
        putchar(ch);
    }
    
  6. Consider a function to check whether the elements in an array occur in ascending order. Duplicates are allowed in the array, as long as they are adjacent.

    The condition we are testing for can be stated more formally as a post-condition on the function as below:

    // Pre:
    // - a[] is a valid pointer to the start of an array of ints
    // - n is a positive int indicating how many elements in a[]
    // Post:
    // - return value = a[i] <= a[i + 1] for all i in [0..n - 2]
    bool isSorted(int *a, int n) {
        ...
    }
    

    Implement this function in two styles:

    1. using COMP1511 C Style
    2. using for, break/return to exit the loop early
Linked List Revision
  1. Consider the following two list representations:

    // Representation 1
    struct node {
        int value;
        struct node *next;
    };
    
    
    
    
    
    typedef struct node *List;
    
    // Representation 2
    struct node {
        int value;
        struct node *next;
    };
    
    struct list {
        struct node *head;
    };
    
    typedef struct list *List;
    
    1. Compare the two representations diagramatically.
    2. How is an empty list represented in each case?
    3. Suppose we want to write a function that inserts a number into a list at a given position. What would the function prototype look like for each representation?
    4. What are the advantages of having a separate list struct as in Representation 2?
  2. Consider the following simple linked-list representation and a function that sums the values in the list:

    typedef struct node {
    	int value;
    	struct node *next;
    } Node;
    
    typedef Node *List; // pointer to first node
    

    Write a function to sum the values in the list. Implement it first using while and then using for. Finally, implement it using recursion (can leave this for next week).

  3. Implement a function to delete the first instance of a value from a list, if it exists. Use the following list representation and prototype:

    struct node {
        int value;
        struct node *next;
    };
    
    struct list {
        struct node *head;
    };
    
    void listDelete(struct list *l, int value);
    

Before starting this week's lab, make sure you properly understand the following topics: