-
-
Save Ellpeck/6a08274b6f88636dbc3a7d3ed7afcbc7 to your computer and use it in GitHub Desktop.
A cheat sheet that I use for C programming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Basically imports | |
// <> import something from a standard library location | |
// "" import something from an actual path | |
#include <stdio.h> | |
#include <stdlib.h> | |
// Preprocessor instructions with ifdef and ifndef, needs endif at the end | |
// ifndef = if not defined | |
#ifndef OOF | |
// Define a variable just to do the if check | |
#define OOF | |
// Define a variable to be replaced in source code | |
// This means that BUFFER_SIZE will be replaced by 16 everywhere on compile | |
#define BUFFER_SIZE 16 | |
#endif | |
// Pointers can be useful for pass by reference | |
// addNum takes a poiner and increases the value at its memory location | |
void addNum(int *a) { | |
*a += 20; | |
} | |
void usePassByReference() { | |
int x = 10; | |
// Calling addNum with the location of the variable will increase it | |
// without having to return the changed value later | |
addNum(&x); | |
// meaning that x will be 30 here, not 10 like it would be without pointers | |
printf("x is %d\n", x); | |
} | |
// Function pointers exist! | |
void someMethod(int d) { | |
printf("d is %d\n", d); | |
} | |
// You can create a function pointer with a return type (in this case void) | |
// and a variable name (in this case "function") that takes a certain number | |
// of parameters (in this case one integer, so "(int)") | |
void callAMethodWithAnIntParam(void (*function)(int), int parameter) { | |
// You can then call the function that the pointer points to by doing this | |
// and giving it the parameters like with a normal function | |
(*function)(parameter); | |
} | |
void useFunctionPointers() { | |
//Now these two calls do the same, basically | |
someMethod(10); | |
callAMethodWithAnIntParam(someMethod, 10); | |
} | |
// Static function variables | |
// Much like in Java, static variables stay put | |
// But the difference here is that you can actually have static variables | |
// in methods that still stay | |
int addToSum(int add) { | |
static int sum = 0; | |
// Calling this method will add to the total sum | |
sum += add; | |
return sum; | |
} | |
// Structs to store more data at once | |
struct vec2 { | |
double x; | |
double y; | |
}; | |
void useStruct() { | |
// When making a variable of a struct, you still have to put "struct" in front | |
struct vec2 point; | |
// When making a struct variable, you can directly set its data without | |
// having to call a constructor or anything | |
point.x = 10.0; | |
point.y = 20.0; | |
// Structure pointers can be useful for linked lists etc. | |
struct vec2 *pointRef; | |
// Instead of using ., you can use -> to access the value of a structure | |
// pointer. The call below is equivalent to the call (*pointRef).x = 0.25; | |
pointRef->x = 0.25; | |
pointRef->y = 0.5; | |
printf("point is %.2f, %.2f\n", point.x, point.y); | |
printf("pointRef is %.2f, %.2f\n", pointRef->x, pointRef->y); | |
} | |
// Enums to make a list of things | |
enum color { | |
RED, BLACK | |
}; | |
void useEnum() { | |
// When making a variable, you still have to put "enum" in front | |
// Assignment also possible using integers (enums are just integers basically) | |
enum color c = RED; | |
printf("c is %d\n", c); | |
} | |
// Typedef allows you to define an actual type based on a struct or enum | |
// To use typedef, you need the first argument to be the thing you want to | |
// define a type of, and the second argument ("vec3") to be the name of the | |
// new type | |
typedef struct vector3 { | |
double x; | |
double y; | |
double z; | |
} vec3; | |
// Type definition like this has multiple parts: | |
// struct vector3 { double x; double y; double z; } is the struct itself | |
// typedef <something> <name> makes it so that you don't have to write "struct vector3 point;" to create a variable | |
// These two can be combined into the following to make it shorter as well: | |
typedef struct { | |
double x; | |
double y; | |
} vec2; | |
// You can also define a type that just mirrors another one | |
typedef int address; | |
void useTypedef() { | |
// Creating variables of structs | |
vec3 point; | |
point.x = 5.0; | |
point.y = 10.0; | |
point.z = 0.0; | |
printf("point is %.2f, %.2f, %.2f\n", point.x, point.y, point.z); | |
// Creating variables of custom types | |
address testAddress; | |
testAddress = 7; | |
} | |
// The main method that gets called when executing the program | |
// Receives the amount of arguments and an array of arrays of chars | |
// (so an array of strings) which stores the actual arguments | |
int main(int argumentAmount, char **arguments) { | |
// Prints something out to the console | |
// f stands for formatted -> you can use %s etc to format your output | |
printf("Hello World my dudes\n"); | |
// sizeof gets the size of a data type - so the amount of bytes it takes up | |
// This can also be done on a malloc'd array to find the size in bytes | |
// directly! | |
int size = sizeof(int); | |
// Unsigned variables | |
unsigned int i = 10; | |
// There are no boolean data types | |
// Doing an if check with an integer will return | |
// true if the integer is != 0, false otherwise | |
int booln = 0; | |
// Pointers: They're confusing, so strap in | |
int c = 0; | |
// Pointer variable intialization - d is going to point to something | |
// rather than be something | |
int *d; | |
// & is the referencing operator - it gives back the address of a variable | |
// In this case, d will not be set to c = 0, but to the address where the 0 | |
// sits in memory | |
d = &c; | |
// d is pointing to an address in memory that stores a value (in this case | |
// the address that stores the 0 that c was assigned to) | |
// * is the dereferencing operator - it gives back the value at an address | |
// In this case, c will be set to 0, because d points to its address | |
c = *d; | |
// Array arithmetics work as you'd want them to | |
// This creates an array for 16 ints, so 16*sizeof(int) bytes of storage | |
int array[16]; | |
// If you increase the value of a pointer, then it will shift the address | |
// in memory that it looks at - by the amount of bytes of its type | |
// In this case, pointer will be moved by sizeof(int) bytes, not just one! | |
int *pointer; | |
pointer++; | |
// Allocates space that shouldn't be overriden by something else | |
// This is useful if you want an array that you fill later | |
// Keep in mind that this is only necessary for arrays! | |
// malloc(x) reserves x bytes | |
char *buffer = malloc(sizeof(char) * BUFFER_SIZE); | |
// After you're done with the data, free the memory for different use | |
free(buffer); | |
usePassByReference(); | |
useFunctionPointers(); | |
useStruct(); | |
useEnum(); | |
useTypedef(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Really nice overview! Thank you!