|
|
@@ -1,43 +1,43 @@ |
|
|
//Basically imports |
|
|
//<> import something from a standard library location |
|
|
//"" import something from an actual path |
|
|
// 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 |
|
|
// 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 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 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 |
|
|
// 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 |
|
|
// 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 |
|
|
// meaning that x will be 30 here, not 10 like it would be without pointers |
|
|
printf("x is %d\n", x); |
|
|
} |
|
|
|
|
|
//Function pointers exist! |
|
|
// 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)") |
|
|
// 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 |
|
|
// 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() { |
|
|
@@ -46,121 +46,134 @@ void useFunctionPointers() { |
|
|
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 |
|
|
// 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 |
|
|
// Calling this method will add to the total sum |
|
|
sum += add; |
|
|
return sum; |
|
|
} |
|
|
|
|
|
//Structs to store more data at once |
|
|
// 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 |
|
|
// 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 |
|
|
// 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. |
|
|
// 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; |
|
|
// 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 |
|
|
// 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) |
|
|
// 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 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() { |
|
|
//You can then just make variables like this, without having to put the type |
|
|
// 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 |
|
|
// 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 |
|
|
// 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! |
|
|
// 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 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 |
|
|
// 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 |
|
|
// Pointers: They're confusing, so strap in |
|
|
int c = 0; |
|
|
//Pointer variable intialization - d is going to point to something |
|
|
//rather than be something |
|
|
// 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 |
|
|
// & 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 |
|
|
// 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 |
|
|
// 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! |
|
|
// 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 |
|
|
// 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 |
|
|
// After you're done with the data, free the memory for different use |
|
|
free(buffer); |
|
|
|
|
|
usePassByReference(); |
|
|
|