// Basically imports // <> import something from a standard library location // "" import something from an actual path #include #include // 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 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(); }