Skip to content

Instantly share code, notes, and snippets.

@eatonphil
Last active March 16, 2024 16:41
Show Gist options
  • Save eatonphil/21b3d6569f24ad164365 to your computer and use it in GitHub Desktop.
Save eatonphil/21b3d6569f24ad164365 to your computer and use it in GitHub Desktop.
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
Copy link

jxub commented Mar 15, 2018

Really nice writeup, thanks!

@mFrankowicz
Copy link

Wow, c is cool! thanks!

@taimoorgit
Copy link

Good examples of function pointers. Saved.

@OmkarKirpan
Copy link

thanks

@fengzj0528
Copy link

Good examples! But there is no definition of 'sayLegs' function in functions2.c

@firasuke
Copy link

Nice examples!

On line 24, it should be // and returns a pointer to a function that takes....

@Guaderxx
Copy link

thanks, good example for function pointer

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