CS 330 Lecture 15 – Makefiles, For Real


  • what ?s
  • the need for separate compilation
  • the way to manage separate compilation: make
  • polymorphism in C: unions


  • Write a midterm exam question on something you read or something discussed in lecture. Turn it in on a quarter sheet. Some portion of the upcoming midterm will be comprised of your questions. In addition to turning them in, you are encouraged to post them in the comments. Aim for conceptual or at least interesting questions. Bad examples include “How big is an int in Java?”, “What year was C standardized?”, and “What utility dumps a file to the console?” Better examples include “Write a line of code that demonstrates why C is weakly typed,” “What Ruby regex would match strings of bits?”, “The cut utility takes option -f <field-number> and -d <delimiter>. Suppose you’ve got text in the following form… Write a shell command that extracts the 2nd, comma-separated field from the file and sorts the results. Use pipe redirection in your answer.”
  • Browse http://bits.stephan-brumme.com and http://graphics.stanford.edu/~seander/bithacks.html. No quarter sheet on this material.



#ifndef STACK_H
#define STACK_H

struct stack_t {
  int size;
  int capacity;
  int *items;

typedef struct stack_t stack_t;

stack_t *make_stack(int capacity);
void stack_push(stack_t *stack, int item);
int stack_pop(stack_t *stack);
void stack_free(stack_t *stack);



#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "stack.h"

#define EZMALLOC(type, n) \
  (type *) malloc((n) * sizeof(type))

stack_t *make_stack(int capacity) {
  stack_t *stack = EZMALLOC(stack_t, 1);  
  stack->size = 0;
  stack->capacity = capacity;
  stack->items = EZMALLOC(int, stack->capacity);

void stack_push(stack_t *stack, int item) {
  if (stack->size >= stack->capacity) {
    fprintf(stderr, "Stack full, you foo bag.\n");

  stack->items[stack->size] = item;

int stack_pop(stack_t *stack) {
  if (stack->size == 0) {
    fprintf(stderr, "Stack empty, you foo bag.\n");

  int item = stack->items[stack->size - 1];
  return item;

void stack_free(stack_t *stack) {


Note to copy and pasters: makefiles rules need to be indented with real tabs, not spaces.

CFLAGS = -std=c99 -g

all: calc

stack.o: stack.c stack.h
  gcc $(CFLAGS) -c stack.c

calc: calc.c stack.o
  gcc $(CFLAGS) -o calc calc.c stack.o

test: calc
  valgrind --leak-check=full ./calc
  # 2 7 / 

  rm -f *.o calc ./a.out


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "stack.h"

int main(int argc, char **argv) {

  stack_t *stack = make_stack(10);

  for (int i = 1; i < argc; ++i) {
    if (strcmp(argv[i], "+") == 0 ||
        strcmp(argv[i], "-") == 0 ||
        strcmp(argv[i], "*") == 0 ||
        strcmp(argv[i], "/") == 0) {
      int a = stack_pop(stack);
      int b = stack_pop(stack);
      if (argv[i][0] == '+') {
        stack_push(stack, a + b);
      } else if (argv[i][0] == '-') {
        stack_push(stack, b - a);
      } else if (argv[i][0] == '*') {
        stack_push(stack, a * b);
      } else if (argv[i][0] == '/') {
        stack_push(stack, b / a);
    } else {
      stack_push(stack, atoi(argv[i]));

    // if argv[i] is operator
    //   pop
    //   pop
    //   eval
    //   push
    // else
    //   push

  printf("stack_pop(stack): %d\n", stack_pop(stack));

  return 0;


Robots water plants
School teachers raise our children
Programs build programs


  1. Mitchell Wood says:

    My guess for a midterm question:

    What is the difference between the stack and the heap? In which situation would you want to use each?

  2. Isaac Schemm says:

    Given a char* named from_string and another char* named to_string (already allocated and at least as big as from_string), write one line of code (using strcpy) that will copy all except the first two characters of from_string into to_string.
    Hint: keep in mind that a char* is a pointer to the first character in a string, and C will read from that pointer until it finds a null terminator (0x00).

    Note: the strcpy function takes two arguments – a char* to write to, and a char* to copy from, in that order.

  3. Nolan Kriener says:

    Exam Problem:
    Write ruby code to validate an ip address (i.e XXX.XXX.XXX.XXX where the X’s are numbers from 0-9 and the values all between 0 and 255)

  4. Travis Boettcher says:

    My question:
    “Which parameter mode does C use, call-by-reference or call-by-value? Explain, and provide an example illustrating how to modify the value of a variable passed to a function without using a return statement.”

  5. Di says:

    Write EZMALLOC to make the line shorter:

    (char *) s = (char *) malloc ((strlen(s) + 1) * sizeof(char));

  6. Jack says:

    Write a line of assembly code that would create 3 local variables on the stack, in a function.

  7. John says:

    Write a regular expression for all words ending in “-ing”

  8. yakun says:

    Write assembly code to add all the odd numbers in 100.

  9. Nick Hasz says:

    Create a regular expression to validate an email address of the form (letters, numbers, and symbols – any length)@(letters and numbers only – any length).(letters only – 3 chars only). Alternatively, create a script to search through a file and pull out any email addresses and redirect them into a mailto function.

  10. Adam King says:

    Explain the difference between declarative and imperative programming. What are some examples of implementations or languages for each of these paradigms?

  11. Jordan says:

    Explain how functions work in Assembly and write a short function that will add 10 to whatever number is passed in.

  12. Karlie says:

    What is malloc and why would you use it? Write in pseudocode how to define an EZMALLOC macro.

  13. Thomas Kokemoor says:

    Write two equivalent regular expressions to match string literals, e.g. “\”\””.

  14. Benjamin Singer says:

    My Question:

    Write a script that accepts a path to a text file as its only command-
    line argument and prints out the file with every digit replaced with its inverse. Ex:
    Before: “0123456789”
    After: “9876543210”

  15. Jake says:

    What does Mario have in common with assembly code?

    1. Chris Johnson says:

      Are you going to leave us hanging on this one?

      1. Jake says:

        They both Jump!

  16. Nate says:

    Given two char*: string1=”concrete” and string2=”nation” write code in C using string manipulation functions such as strcpy or strcat to build the char* “concatenation”.

  17. Sam Dobias says:

    Midterm question:
    Write assembly code that will sort an array using functions and explain how the machine reads the function calls

    1. basemath says:


  18. Corey Feiock says:

    Midterm Question:

    Gmail allows a user to append text to the end of their username with the following format: originalEmailHandle+extraText@gmail.com. This is useful if you want to track which companies are selling your information to advertisers.

    You own a devious company that wants to circumvent this system. Write Ruby code that will delete everything after a “+” and before the “@” in an email address.

  19. Christian says:

    Write a regular expression in ruby that matches a valid ipv4 address. (e.g. matches but not or 1.2.3)

    1. Matthew says:

      That’s a cool question, Christian, but wouldn’t the “valid” ipv4 address be an issue for those of us without networking experience? Why can’t it be

      I do like the regex matching of a wide array of acceptable entries, though :) I just don’t know jack about networking.

      1. thepoynt says:

        Each of the four sections (between the .’s) can be in the range of 0-255.

  20. Matthew says:

    What are the unique uses of the following:




Leave a Reply

Your email address will not be published. Required fields are marked *