--- /dev/null
+src/arg
+src/args
+src/cond
+src/cpp
+src/data
+src/duff
+src/fun
+src/hello
+src/io
+src/jump
+src/loop
+src/main
+src/opts
+src/struct
+src/swap
+src/sm
--- /dev/null
+Intro:
+
+ 1. Hello, World -- src/hello.c
+ 2. Compiling -- src/cc.sh
+ 3. Functions -- src/fun.c
+ 4. Arguments -- src/arg.c
+ 5. Pre-processor -- src/cpp.c
+
+Control flow:
+
+ - do, while, for -- src/loop.c
+ - if, switch -- src/cond.c
+ - goto, labels, return -- src/jump.c
+ - duff's device -- src/duff.c
+
+Data types:
+
+ - Basic types -- src/data.c
+ - Structs and unions -- src/struct.c
+ - Unions -- src/union.c
+
+Argument parsing:
+
+ - src/args.c
+ - src/opts.c
+
+Multiple files:
+
+ - src/util.c
+ - src/util.h
+ - src/main.c
+
+Why C?:
+
+ - You *can* do anything in C.
+ - C programs never break.
+ - Embedded software.
+ - High performance.
+ - C programs just work better.
+ - C and Unix (and Linux)
+
+
+# vim: ft=txt
--- /dev/null
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("Hello, %s!\n", argv[1]);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ for (int i = 1; i < argc; i++)
+ printf("Hello, %s!\n", argv[i]);
+ return 0;
+}
--- /dev/null
+#!/bin/bash
+
+# Simplest complie
+cc hello.c
+./a.out
+
+# Standard CC compile
+gcc --std=c99 -Wall -o hello hello.c
+./hello
+
+# Bulding object files
+gcc -c -o hello.o hello.c
+gcc -o hello hello.o -lm
+./hello
+
+# Building with make
+make hello
+./hello
--- /dev/null
+#include <stdio.h>
+
+int main()
+{
+ int answer = 42;
+
+ /*
+ * If / else.
+ */
+ if (answer == 42)
+ printf("Right!\n");
+ else if (answer == 41)
+ printf("Close!\n");
+ else
+ printf("Wrong!\n");
+
+ /*
+ * Switch.
+ */
+ switch (answer) {
+ case 42:
+ printf("Right!\n");
+ break;
+ case 41:
+ case 43:
+ printf("Close!\n");
+ break;
+ default:
+ printf("Wrong!\n");
+ break;
+ }
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+#define ANSWER 42
+
+#define COUNTER counter++
+
+#define DONT printf("Don't"
+#define DO " do "
+#define THIS "this!\n");
+
+#define HELLO1(name) printf("Hello, %s\n", name)
+
+#define HELLO2(name) printf("Hello, " #name "\n")
+
+int main()
+{
+ int counter = 0;
+
+ printf("The answer is %d.\n", ANSWER);
+ printf("\n");
+
+ printf("The counter is %d.\n", COUNTER);
+ printf("The counter is %d.\n", COUNTER);
+ printf("The counter is %d.\n", COUNTER);
+ printf("\n");
+
+ DONT DO THIS
+ printf("\n");
+
+ HELLO1("Andy");
+ HELLO2(Andy);
+ HELLO2("Andy");
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+
+int main()
+{
+ /*
+ * Numeric types.
+ */
+ int the_answer = 42;
+
+ signed negative = -100;
+
+ unsigned positive = 100;
+
+ long long trillion = 1000000000000;
+
+ unsigned long long int neg_trillion = -1000000000000;
+
+ short two_bytes = 65000;
+
+ char one_byte = 123;
+
+ printf("Numbers\n");
+ printf(" the_answer = %d\n", the_answer);
+ printf(" positive = %d\n", positive);
+ printf(" negative = %u\n", negative);
+ printf(" trillion = %lld\n", trillion);
+ printf(" neg_trillion = %lld\n", neg_trillion);
+ printf(" two_bytes = %hd\n", two_bytes);
+ printf(" one_byte = %hhd\n", one_byte);
+ printf("\n");
+
+ /*
+ * Standard integers.
+ */
+ int8_t signed_8bit = 1;
+
+ uint8_t unsigned_8bit = 2;
+
+ int64_t signed_64bit = 3;
+
+ uint64_t unsigned_64bit = 4;
+
+ printf("Standard Ints\n");
+ printf(" signed_8bit = %hhd\n", signed_8bit);
+ printf(" unsigned_8bit = %hhu\n", unsigned_8bit);
+ printf(" signed_6bit_ = %ld\n", signed_64bit);
+ printf(" unsigned_64bit = %lu\n", unsigned_64bit);
+ printf("\n");
+
+ /*
+ * Characeters.
+ */
+ char a_char = 'a';
+
+ char a_int = 97;
+
+ char a_hex = 0x61;
+
+ printf("Standard Ints\n");
+ printf(" as integers = %2d %2d %2d\n", a_char, a_int, a_hex);
+ printf(" as chars = %2c %2c %2c\n", a_char, a_int, a_hex);
+ printf(" as hex = %2x %2x %2x\n", a_char, a_int, a_hex);
+ printf("\n");
+
+ /*
+ * Arrays.
+ */
+ int fixed_size[100] = {1, 2, 3};
+
+ int auto_sized[] = {1, 2, 3};
+
+ int tables[][32] = {
+ {1, 2, 3},
+ {4, 5, 6},
+ };
+
+ printf("Array sizes\n");
+ printf(" fixed_size = %zd\n", sizeof(fixed_size));
+ printf(" auto_sized = %zd\n", sizeof(auto_sized));
+ printf(" table size = %zd\n", sizeof(tables));
+ printf(" first = %d\n", fixed_size[0]);
+ printf(" third = %d\n", fixed_size[2]);
+ printf(" last = %d\n", fixed_size[99]);
+ printf(" tables = %d\n", tables[0][0]);
+ printf("\n");
+
+ /*
+ * Strings.
+ */
+ char hello_char[] = {'h', 'e', 'l', 'l', 'o', '\0'};
+
+ char hello_str[] = "hello";
+
+ char *hello_ptr = "hello";
+
+ printf("Strings\n");
+ printf(" as strings = %s %s %s\n",
+ hello_char,
+ hello_str,
+ hello_ptr);
+ printf(" as arrays = %c %c %c\n",
+ hello_char[0],
+ hello_str[0],
+ hello_ptr[0]);
+ printf(" sizes = %zd %zd %zd\n",
+ sizeof(hello_char),
+ sizeof(hello_str),
+ sizeof(hello_ptr));
+ printf("\n");
+
+ /*
+ * Pointers.
+ */
+ int one = 1;
+
+ int two = 2;
+
+ int *pointer = &one;
+
+ *pointer = 100;
+
+ printf("Strings\n");
+ printf(" one = %d\n", one);
+ printf(" two = %d\n", two);
+ printf(" pointer = %llx\n", (long long)pointer);
+ printf(" pointer = %p\n", pointer);
+ printf(" value = %d\n", *pointer);
+
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+void duff(const char *str)
+{
+ int len = strlen(str);
+ int div = len / 8;
+ int rem = len % 8;
+
+ switch (rem) {
+ case 0: while (div--) {
+ putchar(*str++);
+ case 7: putchar(*str++);
+ case 6: putchar(*str++);
+ case 5: putchar(*str++);
+ case 4: putchar(*str++);
+ case 3: putchar(*str++);
+ case 2: putchar(*str++);
+ case 1: putchar(*str++);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ duff("Hello, World\n");
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+void hello_world(void)
+{
+ printf("Hello, World!\n");
+}
+
+void hello_name(char *name)
+{
+ printf("Hello, %s!\n", name);
+}
+
+void hello_hello(int n)
+{
+ printf("Hello, World!\n");
+ if (n > 1)
+ hello_hello(n - 1);
+}
+
+int main()
+{
+ hello_world();
+ printf("\n");
+
+ hello_name("World");
+ hello_name("Andy");
+ printf("\n");
+
+ hello_hello(10);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello, World\n");
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+void cat(char *name)
+{
+ FILE *fd = fopen(name, "r");
+ if (!fd) {
+ printf("Error opening '%s': %s\n",
+ name, strerror(errno));
+ return;
+ }
+
+ int len = 0;
+ char buf[32] = {};
+ while (!feof(fd)) {
+ len = fread(buf, 1, sizeof(buf), fd);
+ printf("{{ Read %d bytes }}", len);
+ fwrite(buf, 1, len, stdout);
+ }
+
+}
+
+int main()
+{
+ cat("io.c");
+ cat("junk.c");
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+void bad_hello(int count)
+{
+ int i = 0;
+hello:
+ printf("Hello, %d!\n", i);
+ i++;
+ if (i < count)
+ goto hello;
+}
+
+int ok_hello(int count)
+{
+ if (count == 0)
+ goto error_zero;
+ if (count < 0)
+ goto error_neg;
+
+ for (int i = 0; i < count; i++)
+ printf("Hello, %d!\n", i);
+
+ return 0;
+
+error_zero:
+ printf("Count is zero!\n");
+ return 1;
+
+error_neg:
+ printf("Count is negative!\n");
+ return 1;
+}
+
+int main()
+{
+ bad_hello(3);
+ printf("\n");
+
+ ok_hello(1);
+ ok_hello(0);
+ ok_hello(-1);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+#define N_ELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+struct list {
+ const char *name;
+ struct list *next;
+};
+
+int main()
+{
+ int i = 0;
+
+ /*
+ * While loops.
+ */
+ i = 0;
+ while (i < 3) {
+ printf("Hello, %d!\n", i);
+ i = i + 1;
+ }
+ printf("\n");
+
+ /*
+ * Do loops.
+ */
+ i = 0;
+ do {
+ printf("Hello, %d!\n", i);
+ i = i + 1;
+ } while (i < 3);
+ printf("\n");
+
+ /*
+ * For loops.
+ */
+ for (i = 0; i < 3; i++)
+ printf("Hello, %d!\n", i);
+ printf("\n");
+
+ /*
+ * C99 only.
+ */
+ for (int j = 0; j < 3; j++)
+ printf("Hello, %d!\n", j);
+ printf("\n");
+
+ /*
+ * Arrays
+ */
+ char *names[] = {"one", "two", "three"};
+ for (int i = 0; i < N_ELEM(names); i++)
+ printf("Hello, %s!\n", names[i]);
+ printf("\n");
+
+ /*
+ * Linked lists.
+ */
+ struct list three = {"three"};
+ struct list two = {"two", &three};
+ struct list one = {"one", &two};
+ for (struct list *cur = &one; cur; cur = cur->next)
+ printf("Hello, %s!\n", cur->name);
+ printf("\n");
+
+ return 0;
+}
--- /dev/null
+#include "util.h"
+
+int main()
+{
+ hello("Andy");
+ return 0;
+}
--- /dev/null
+GCC := gcc
+CFLAGS := -g -Wall -Wno-unused-variable --std=c99
+
+SRCS := $(wildcard *.c)
+OBJS := ${SRCS:%.c=%.o}
+BINS := $(filter-out main util,${SRCS:%.c=%})
+
+all: $(BINS) main
+
+%-test: %
+ ./$<
+
+main: main.o util.o
+ $(GCC) $(CFLAGS) -o $@ $+
+
+$(BINS): %: %.o
+ $(GCC) $(CFLAGS) -o $@ $+
+
+%.o: %.c
+ $(GCC) $(CFLAGS) -c -o $@ $+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+/* Options */
+static int opt_verbose = 0;
+static char *opt_greeting = "Hello";
+static char *opt_name = "World";
+
+/* Parsing */
+static char *short_options = "hvg:n:";
+
+static struct option long_options[] = {
+ {"help", 0, NULL, 'h'},
+ {"verbose", 0, NULL, 'v'},
+ {"greeting", 1, NULL, 'g'},
+ {"name", 1, NULL, 'n'},
+};
+
+/* Show usage information */
+static void usage(int status)
+{
+ printf("opts -[OPTIONS]\n");
+ printf("\n");
+ printf("Options:\n");
+ printf(" -h,--help Show usage information\n");
+ printf(" -v,--verbose Print debug output messages\n");
+ printf(" -n,--greeting=STR Use the given greeting\n");
+ printf(" -n,--name=NAME Greet the given person\n");
+ exit(status);
+}
+
+/* Parse command line arguments */
+static void parse(int argc, char **argv)
+{
+ while (1) {
+ int c = getopt_long(argc, argv,
+ short_options, long_options, 0);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'h': usage(0); break;
+ case 'v': opt_verbose = 1; break;
+ case 'g': opt_greeting = optarg; break;
+ case 'n': opt_name = optarg; break;
+ default: usage(1); break;
+ }
+ }
+ if (argc != optind)
+ usage(1);
+
+ if (opt_verbose) {
+ printf("Options:\n");
+ printf(" verbose = %d\n", opt_verbose);
+ printf(" greeting = %s\n", opt_greeting);
+ printf(" name = %s\n", opt_name);
+ printf("\n");
+ }
+}
+
+/* Main entry point */
+int main(int argc, char **argv)
+{
+ parse(argc, argv);
+ printf("%s, %s\n", opt_greeting, opt_name);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+int (*state)(typeof(state));
+
+int sm_first(state_t *state);
+int sm_second(state_t *state);
+int sm_third(state_t *state);
+int sm_done(state_t *state);
+
+int sm_first(state_t *state)
+{
+ printf("first\n");
+ *state = &sm_second;
+ return 1;
+}
+
+int sm_second(state_t *state)
+{
+ *state = &sm_third;
+ printf("second\n");
+ return 1;
+}
+
+int sm_third(state_t *state)
+{
+ *state = &sm_done;
+ printf("third\n");
+ return 1;
+}
+
+int sm_done(state_t *state)
+{
+ printf("done\n");
+ return 0;
+}
+
+int main()
+{
+ state_t state = sm_first;
+ while (state(&state));
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+
+int main()
+{
+ /*
+ * Structs
+ */
+ struct person {
+ char *name;
+ int age;
+ };
+
+ struct person andy = { "Andy", 33 };
+
+ printf("%s is %d years old!\n",
+ andy.name, andy.age);
+ printf("\n");
+
+ /*
+ * Typedefs
+ */
+ typedef struct {
+ char *name;
+ int age;
+ } person_t;
+
+ person_t andys = { "Andy Spencer", 33 };
+
+ printf("%s is %d years old!\n",
+ andys.name, andys.age);
+ printf("\n");
+
+ /*
+ * Pointers.
+ */
+ person_t *who = &andys;
+
+ printf("%s is %d years old!\n",
+ (*who).name, (*who).age);
+
+ printf("%s is %d years old!\n",
+ who->name, who->age);
+ printf("\n");
+
+ /*
+ * Unions.
+ */
+ union cake {
+ char *have;
+ char *eat;
+ };
+
+ union cake chocolate = {};
+
+ chocolate.have = "Yes please";
+ printf("Chocolate? %s!\n", chocolate.have);
+ chocolate.eat = "Yum";
+ printf("Chocolate? %s!\n", chocolate.eat);
+ printf("Chocolate? %s!\n", chocolate.have);
+ printf("\n");
+
+ /*
+ * Unions.
+ */
+ union types {
+ uint32_t number;
+ char string[4];
+ };
+
+ union types abc = {
+ .string = "abc"
+ };
+
+ printf("Number: %08x\n", abc.number);
+ printf("String: %s\n", abc.string);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+
+void swap(int *a, int *b)
+{
+ *a ^= *b;
+ *b ^= *a;
+ *a ^= *b;
+}
+
+int main(int argc, char **argv)
+{
+ int a = 5678;
+ int b = 1234;
+
+ swap(&a, &b);
+ printf("%d %d\n", a, b);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include "util.h"
+
+void hello(char *name)
+{
+ printf("Hello, %s\n", name);
+}
--- /dev/null
+#ifndef UTIL_H
+#define UTIL_H
+
+void hello(char *name);
+
+#endif /* UTIL_H */