Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Introduction to "Fun" C (using GCC)
/**
* This are a collection of examples for C 201.
* These combine concepts you may or may not be
* familiar with and are especially useful for
* students new to C. There is a lot of really
* cool stuff you can do in C without any cool
* languages.
*
* This is file in particular is an introduction
* to fun function usage in C.
*/
#include <stdio.h>
int sum(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
// This function "get_operator" takes a *char expression
// and returns a function that takes two ints and returns
// an int.
int (*get_operator(char* expression)) (int, int) {
int i;
// char pointers are automatically given a final character '\0'
// to allow us to know when the char* ends.
for (i = 0; expression[i] != '\0'; i++) {
switch (expression[i]) {
case '+':
return sum;
case '-':
return sub;
}
}
}
void print_operator(char* expression) {
// get_operator will return a function that takes two ints
// and returns an int.
int (*operator)(int, int) = get_operator(expression);
// sum is automatically converted to a pointer,
// you could also say "operator == &sum", but that is longer.
if (operator == sum) { // comparing functions!
printf("Expression %s is a sum.\n", expression);
} else if (operator == sub) { // comparing functions again!!
printf("Expression %s is a sub.\n", expression);
} else {
printf("Expression %s has an unknown operation.\n", expression);
}
// Challenge:
// Instead of just printing out which operation it is,
// find the two operands and perform the operation on them.
// Then print the result of the expression instead.
}
int main() {
char* expression1 = "2 + 2";
char* expression2 = "5 - 3";
char* expression3 = "9 * 7";
print_operator(expression1);
print_operator(expression2);
print_operator(expression3);
}
/**
* This is an example of more complex function usage in C.
* Read structs.c before continuing.
*/
#include <stdio.h>
// Good reference:
// http://www.dirac.org/linux/programming/tutorials/function_pointers/
typedef struct {
int legs;
void (*sayName)(void);
} Animal;
void catSayName() {
printf("I am a cat.\n");
}
void dogSayName() {
printf("I am a dog.\n");
}
int sub(int a, int b) {
return a - b;
}
int sum(int a, int b) {
return a + b;
}
double sum_d(double a, double b) { return a + b; } // would fail if passed to operate: operate(sum_d, 1, 2)
int operate(int (*f)(int, int), int a, int b) {
return f(a, b);
}
void do_nothing(void) {
return;
}
int main() {
Animal cat;
cat.legs = 4;
cat.sayName = catSayName;
Animal cat1;
cat1.legs = 4;
cat1.sayName = catSayName;
Animal dog;
dog.legs = 3;
dog.sayName = dogSayName;
cat.sayName(); // I am a cat.
dog.sayName(); // I am a dog.
cat.sayLegs(cat.legs);
int my_sum = operate(sum, 1, 2);
printf("%d\n", my_sum); // Prints 3
int my_sub = operate(sub, 11, 2);
printf("%d\n", my_sub); // Prints 9
do_nothing();
}
/**
* This is a collection of pointer examples.
* It is a fun way to test yourself. I'm
* sorry I couldn't think of a better way
* to show the answers.
*/
#include <stdio.h>
void print(int i) {
printf("%d\n", i);
}
int main() {
int* myInt;
int myIntsValue = 3;
myInt = &myIntsValue; // int* somePointer; *somePointer = myIntsValue; myInt = somePointer;
print(*myInt); // prints 3
int mySecondInt = 2;
*myInt = mySecondInt;
print(*myInt); // prints 2
print(mySecondInt); // prints 2
print(myIntsValue); // prints 2
myInt = &mySecondInt; // int* somePointer; *somePointer = mySecondInt; myInt = somePointer;
mySecondInt = 5;
print(*myInt); // prints 5
myIntsValue = 7;
print(*myInt); // prints 5
mySecondInt = myIntsValue;
print(*myInt); // prints 7
}
/**
* This is a continuation of (more complex)
* pointer examples.
*/
#include <stdio.h>
void print(int i) {
printf("%d\n", i);
}
void swap1(int a, int b) {
int temp = b;
b = a;
a = temp;
}
void swap2(int* p_a, int* p_b) {
int temp = *p_b;
*p_b = *p_a;
*p_a = temp;
}
int main() {
int a = 1;
int b = 2;
swap1(a, b);
print(a); // prints 1
print(b); // prints 2
swap2(&a, &b);
print(a); // prints 2
print(b); // prints 1
int* c;
int* d;
c = &a; // c = some address... but *c = 2
d = &b; // d = some address... but *d = 1
swap1(*c, *d);
print(*c); // prints 2
print(*d); // prints 1
swap2(c, d);
print(*c); // prints 1
print(*d); // prints 2
}
/**
* This is a brief example of typedef-ing and structs in C.
*/
typedef int Int; // int or Int
struct Person {
char* name;
Int age;
};
typedef struct Person APerson; // struct Person or APerson
typedef struct Animal {
int legs;
} Animal; // struct Animal or Animal
typedef struct {
int mpg;
} Car; // cannot use struct Car, can only use Car... the struct is anonymous
int main() {
APerson person; // could use "struct Person person"
person.name = "Phil";
person.age = 10;
Animal cat; // could use "struct Animal cat;"
cat.legs = 4;
Car car; // could not use "struct Car car;" because the struct was anonymous
car.mpg = 30;
}
@jxub

This comment has been minimized.

Show comment Hide comment
@jxub

jxub Mar 15, 2018

Really nice writeup, thanks!

jxub commented Mar 15, 2018

Really nice writeup, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment