Discuss the good, the bad and the ugly aspects of their code.
Please be gentle in any criticism - we are all learning!
Do you have any questions? Have you learned anything that would be useful to share with the rest of the tutorial?
The function member tests if a specified value is a found in a specified list, i.e. the function should return 1 if the value occurs in the list 0 otherwise. It has this prototype:
int member(int value, struct node *list);Implement this function both iteratively (using a while/for loop) and recursively.
// return 1 iff value occurs in list, 0 otherwise int member(int value, struct node *head) { if (head == NULL) { return 0; } if (head->data == 1) { return 1; } return member(value, head->next); }Very terse recursive:
// return true iff value occurs in list int member(int value, struct node *list) { return list != NULL && (list->data == value || member(value, list->next)); }Iterative:
/* * return true iff value occurs in list */ int member(int value, struct node *list) { struct node *n; for (n = list; n != NULL; n = n->next) { if (n->data == value) { return 1; } } return 0; }
struct node *list_append(struct node *list1, struct node *list2);It should not create (malloc) any new list elements.
It should just change the appropriate next field in the first list.
struct node *list_append(struct node *list1, struct node *list2) { struct node *n; if (list1 == NULL) { return list2; } n = list1; while (n->next != NULL) { n = n->next; } n->next = list2; return list1; }
struct node *insert_ordered(int item, struct node *list);It should create (malloc) just 1 list element and change the appropriate next field in the list to insert it.
Implement this function.
struct node *insert_ordered(int item, struct node *list) { struct node *n; struct node *new = malloc(sizeof *new); if (new == NULL) { fprintf(stderr, "Out of memory"); exit(1); } new->data = item; if (list == NULL || item < list->data) { new->next = list; return new; } n = list; while (n->next != NULL && n->next->data < item) { n = n->next; } new->next = n->next; n->next = new; return list; }
struct node *merge_sorted(struct node *list1, struct node *list2);
It should not create (malloc) any list elements. It should change the appropriate next fields to combined the lists.
Implement this function both iteratively (using a while/for loop) and recursively.
struct node *merge_sorted(struct node *list1, struct node *list2) { struct node *start; struct node *n; if (list1 == NULL) { return list2; } else if (list2 == NULL) { return list1; } else if (list1->data < list2->data) { start = list1; n = list1; list1 = list1->next; } else { start = list2; n = list2; list2 = list2->next; } while (list1 != NULL && list2 != NULL) { if (list1->data < list2->data) { n->next = list1; n = list1; list1 = list1->next; } else { n->next = list2; n = list2; list2 = list2->next; } } if (list1 == NULL) { n->next = list2; } else { n->next = list1; } return start; }Recursive version:
struct node *merge_sorted(struct node *list1, struct node *list2) { if (list1 == NULL) { return list2; } else if (list2 == NULL) { return list1; } else if (list1->data < list2->data) { list1->next = merge_sorted(list1->next, list2); return list1; } else { list2->next = merge_sorted(list1, list2->next); return list2; } }
Your tutor may still choose to cover some of the questions time permitting.
double ff[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; double *fp = &ff[0];
What are the similarities between ff
and fp
? What are
the differences?
ff
.
They can both be used to access the array.
char s[] = "Hello World!"; char *cp = s; char *cp2 = &s[8];
What is the output when the following statements are executed?
printf("%s\n", cp); printf("%c\n", *cp); printf("%c\n", cp[6]); printf("%s\n",cp2); printf("%c\n",*cp2);
Hello World! H W rld! r
fines.txt
this format:
Linus Torvalds fined $98 for not attending lectures. Denis Ritchie fined $50 for eating in labs. Ken Thompson fined $150 for attending lecture in his underpants.Write a program
student_fine.c
which reads this file and prints the student with bigesst
fine including the amount and reason in this format.
a.out Biggest fine was $150 given to Ken Thompson for 'attending lecture in his underpants'.
student_fine.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE 1024 int main(int argc, char *argv[]) { FILE *f; char line[MAX_LINE]; int fine; int biggestFine = 0; char biggestFineStudentName[MAX_LINE]; char biggestFineReason[MAX_LINE]; int nStudents; char *p, *q; f = fopen("fines.txt", "r"); if (f == NULL) { perror(argv[0]); return 1; } nStudents = 0; while (fgets(line, MAX_LINE, f) != NULL) { // look for '$' to find the fine amount p = strchr(line, '$'); if (p == NULL) { fprintf(stderr, "No $ on line %d\n", nStudents + 1); exit(1); } fine = atoi(p + 1); // if it's the first student or fine is bigger than current maximum, // then we need to update our 'biggestFine' if (nStudents == 0 || fine > biggestFine) { biggestFine = fine; // put '\0' after the name, so that we can use strcpy p = p - 7; // move the pointer back so that it's immediately after the name if (p < line) { fprintf(stderr, "No name for fine on line %d\n", nStudents + 1); } p[0] = '\0'; strcpy(biggestFineStudentName, line); // move forward 3 words int i; i = 0; while (i < 3) { p = strchr(p + 1, ' '); if (p == NULL) { fprintf(stderr, "No reason for fine on line %d\n", nStudents + 1); exit(1); } i = i + 1; } // put '\0' after the reason, so that we can use strcpy q = strchr(p + 1, '.'); if (q == NULL) { fprintf(stderr, "Line %d too long\n", nStudents + 1); exit(1); } q[0] = '\0'; strcpy(biggestFineReason, p + 1); } nStudents = nStudents + 1; } if (nStudents > 0) { printf("Biggest fine was $%d given to %s for '%s'.\n", biggestFine, biggestFineStudentName, biggestFineReason); } fclose(f); return 0; }
int non_decreasing(int n, int a[n])which checks whether items in an array are sorted in non-decreasing order. (i.e. a[i] ≥ a[i-1], for 0<i<N). Your function should returns 1 if the items are in non-decreasing order, 0 otherwise.
int non_decreasing(int a[], int n) { int no_decrease = 1; for (int i = 0; i < n-1 && no_decrease; i = i + 1) { if (a[i] > a[i + 1]) { noDecrease = 0; } } return no_decrease; }
int find_index(int x, int n, int a[n])which takes two integers x and n together with an array a[] of n integers and searches for the specified value within the array. Your function should return the smallest index k such that a[k] is equal to x (or -1 if x does not occur in the array).
int find_index(int x, int n, int a[n]) { int k = -1; for (int i = 0; i < n && k == -1; i = i + 1) { if (a[i] == x) { k = i; } } return k; }
c
in the
string s.
It returns NULL if the character cannot be found.
char *strrchr(char s[], char c)
char *strrchr(char s[], char c) { char *ptr = NULL; int i; for (i = 0; i < strlen(s); i = i + 1) { if (s[i] == c) { ptr = &s[i]; } } return ptr; }
Use this function from the math.h library:
double fabs(double x);
#include <math.h> double manhattanDistance(double x1, double y1, double x2, double y2) { return fabs(x1 - x2) + fabs(y1 - y2); }
multiply.c
that performs addition or multiplication of integers, as follows.
Your program should continually read integers from the user until end-of-input
is encountered. Then it should print either the sum or the product of the input
numbers. The program behaviour is controlled by either of the following
command-line arguments:
-add, -multiply
. If the wrong command-line
argument(s) are supplied your program should do nothing.
multiply.c
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { int val, result; if (argc != 2) { return 0; // should print a message here } if (strcmp(argv[1], "-add") != 0 && strcmp(argv[1], "-multiply") != 0) { return 0; // should print a message here } result = 0; //If we are multiplying we need to initialise result to 1 //Since we have already checked argv[1] contains either //"-multiply" or "-add" we only need to check the second char if (argv[1][1] == 'm') { result = 1; } while (scanf("%d", &val) == 1) { if (argv[1][1] == 'a') { result = result + val; } else { result = result * val; } } if (argv[1][1] == 'a') { printf("Sum: %d\n", result); } else { printf("Product: %d\n", result); } return 0; }