├── .gitignore ├── BitwiseOperationsInC └── BitChange.c ├── C_programming_readings ├── C_Arrays.pdf ├── C_Bit_manipulation.pdf ├── C_Date_Types.pdf ├── C_Pointers.pdf ├── C_operators.pdf ├── Starting off in C.doc └── Starting off in C.pdf ├── DataStructuresInC └── LinkedList.c ├── FileOperationsInC ├── FileIO.c └── example.txt ├── FunctionsInC └── Recursion.c ├── HeaderFileExamples ├── HeaderExample.c ├── HeaderExample.h └── HeaderExampleDefine.c ├── KeyWordsInC ├── Const.c ├── Static.c ├── Switch.c ├── Typedef.c └── Union.c ├── LinkedList ├── list.c └── list.h ├── MacrosInC └── Macros.c ├── MemoryAllocation └── Malloc.c ├── PointersInC ├── FuncsWithPointers.c ├── PointerArithmetic.c ├── PointerMethods.c ├── PointerToFunctions.c ├── Pointers.c ├── README.md └── VoidPointer.c ├── PracticeProblems └── README.md ├── README.md ├── StringsInC ├── StringArray.c ├── StringCompare.c └── StringCounter.c ├── StructuresInC ├── hello.c ├── structExample1.c └── structExample2.c ├── SystemLevelInterfacing └── fork.c ├── TestingInC └── Assert.c └── Threading ├── Mutexes.c └── threadIntro.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | 5 | # Libraries 6 | *.lib 7 | *.a 8 | 9 | */.DS* 10 | .DS_Store 11 | 12 | 13 | # Shared objects (inc. Windows DLLs) 14 | *.dll 15 | *.so 16 | *.so.* 17 | *.dylib 18 | 19 | # Executables 20 | *.exe 21 | *.out 22 | *.app 23 | /Debug 24 | /.settings 25 | 26 | .cproject 27 | .project 28 | -------------------------------------------------------------------------------- /BitwiseOperationsInC/BitChange.c: -------------------------------------------------------------------------------- 1 | /* 2 | * BitChange.c 3 | * 4 | * Created on: Mar 21, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | int main(void) { 10 | 11 | signed int i = 10; // represented in binary as 1010. 12 | 13 | signed int j = 5; //represented in binary as 0101 14 | 15 | /** 16 | * if EITHER binary position contains a 1 (true) a 17 | * 1 is put in the bit position and put together with the 18 | * other positions 19 | * so in the case I am comparing 1010 or 0101 and returning 1111. 20 | */ 21 | printf("%d \n", i | j); // prints out 15 (1111). 22 | 23 | /** 24 | * Checks to see if both respective bit positions 25 | * contain a 1 (true), if that is correct, a 1 is 26 | * put in that bit position, if not a 0 is returned. 27 | */ 28 | printf("%d \n", i & j); // prints out 0 (0000) 29 | 30 | /** 31 | * The "^" is the exclusive-or symbol 32 | * it holds true if one is true but NOT both 33 | * so will return a if there is only one 1 in 34 | * the respective binary position. 35 | */ 36 | printf("%d \n", i ^ j); // prints out 15 too. 37 | 38 | /** 39 | * the format is ALWAYS (variable/value) (<< OR >>) (parameter of shift) 40 | * 41 | * 42 | * 43 | * Shifts all bits the RIGHT by the indicated parameter. 44 | * Depending on the size of the bit it is possible to lose 45 | * bits as they fall off the length of the variable. 46 | * What this does is essentially multiply your 47 | * number by (2^n) where n is the parameter 48 | */ 49 | printf("%d \n", i << 2); //prints out 40, multiplies 10 by 2^2 = 4 50 | 51 | /** 52 | * Shifts all bits the LEFT by the indicated parameter. 53 | * Depending on the size of the bit it is possible to lose 54 | * bits as they fall off the length of the variable. 55 | * 56 | */ 57 | printf("%d", j >> 2); // prints out 1. 58 | 59 | return 0; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /C_programming_readings/C_Arrays.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/C_Arrays.pdf -------------------------------------------------------------------------------- /C_programming_readings/C_Bit_manipulation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/C_Bit_manipulation.pdf -------------------------------------------------------------------------------- /C_programming_readings/C_Date_Types.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/C_Date_Types.pdf -------------------------------------------------------------------------------- /C_programming_readings/C_Pointers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/C_Pointers.pdf -------------------------------------------------------------------------------- /C_programming_readings/C_operators.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/C_operators.pdf -------------------------------------------------------------------------------- /C_programming_readings/Starting off in C.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/Starting off in C.doc -------------------------------------------------------------------------------- /C_programming_readings/Starting off in C.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajn123/C_Tutorial/f6c87c034cc593ea3687e44abd9be6d89d0d6f0d/C_programming_readings/Starting off in C.pdf -------------------------------------------------------------------------------- /DataStructuresInC/LinkedList.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | 6 | /** 7 | * This is an example of a VERY simple linked list to show how you can create a list and then 8 | * have a pointer to another node in the list. 9 | */ 10 | 11 | struct node{ 12 | int a; 13 | struct node *next; 14 | 15 | }; 16 | typedef struct node Node; 17 | 18 | 19 | 20 | int main() 21 | { 22 | Node *current, *head; 23 | head = NULL; 24 | 25 | for(int i = 1; i <= 10;i++) 26 | { 27 | current = (Node *) malloc(sizeof(Node)); 28 | current->a = i; 29 | current->next = head;// NULL the first time 30 | head = current; 31 | } 32 | 33 | current = head; 34 | while(current) 35 | { 36 | printf("%d \n", current->a); 37 | current = current->next; 38 | } 39 | return 0; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /FileOperationsInC/FileIO.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FileIO.c 3 | * 4 | * Created on: Jan 20, 2014 5 | * Author: marknorton 6 | */ 7 | /* 8 | ============================================================================ 9 | Name : C_tutorial.c 10 | Author : aj 11 | Version : 12 | Copyright : Your copyright notice 13 | Description : Hello World in C, Ansi-style 14 | ============================================================================ 15 | */ 16 | 17 | #include 18 | 19 | int main(void) { 20 | 21 | FILE *filePtr = fopen("example.txt", "rw"); 22 | char line[1000]; 23 | 24 | if (fPtr == NULL) { 25 | /* Handle error for if fopen failed to find a file */ 26 | printf("Could not open file %s", FILE_NAME); 27 | return EXIT_FAILURE; 28 | } 29 | 30 | while (fgets(line, sizeof(line), filePtr)) { 31 | printf("%s", line); 32 | } 33 | 34 | if (fclose(filePtr) == EOF) { 35 | /* Handle error for if closed before returning to the caller*/ 36 | puts("Was not closed before returning to the caller!"); 37 | return 1; 38 | } 39 | return 0; 40 | } 41 | 42 | // 43 | //int main(void) { 44 | // 45 | // FILE *outputFile = (FILE *) fopen("INTERMEDIATE2MIPSASSEMBLER.asm", "w+"); 46 | // 47 | // fprintf(outputFile, "%s", "hinnnnnn yolo \nsdsdff"); 48 | // fclose(outputFile); 49 | // 50 | // char line[1000]; 51 | // FILE * inputFile = (FILE *) fopen("INTERMEDIATE2MIPSASSEMBLER.asm", "r+"); 52 | // 53 | // while (fgets(line, sizeof(line), inputFile)) { 54 | // printf( "%s", line); 55 | // } 56 | // fclose(inputFile); 57 | // 58 | // return 1; 59 | //} 60 | -------------------------------------------------------------------------------- /FileOperationsInC/example.txt: -------------------------------------------------------------------------------- 1 | yolo i love kittens 2 | lol hi my name is slim yolo i love kittens 3 | lol 4 | -------------------------------------------------------------------------------- /FunctionsInC/Recursion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Recursion.c 3 | * 4 | * Created on: Mar 21, 2013 5 | * Author: Aj Norton 6 | 7 | 8 | */ 9 | #include 10 | 11 | int factorial(int i);// method header so the the compiler knows the function is defined below main 12 | 13 | int main(void) 14 | { 15 | printf("%d", factorial(5)); 16 | return 0; 17 | } 18 | 19 | /** 20 | Calculates the factorials (n!) of a given number. 21 | */ 22 | int factorial(int i) 23 | { 24 | if(i <= 1) 25 | { 26 | return 1; 27 | } 28 | else 29 | { 30 | return factorial(i-1)*i; //returns factorial times the inputed value, effectively multiplying n*(n-1)*(n-2)*(n-3) = n! 31 | } 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /HeaderFileExamples/HeaderExample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HeaderExample.c 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | 9 | /** 10 | * I am including the contents of HeaderExample.h, this is literally taking the contents of my .h 11 | * file and pasting them where the include is for my C file to view. 12 | */ 13 | #include "HeaderExample.h" 14 | 15 | int main(void) { 16 | 17 | int i = 10; 18 | i = add(i); 19 | 20 | printf("%d", i); 21 | 22 | return 0; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /HeaderFileExamples/HeaderExample.h: -------------------------------------------------------------------------------- 1 | /* 2 | * HeaderExample.h 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | #ifndef HEADEREXAMPLE_H_ 9 | #define HEADEREXAMPLE_H_ 10 | #include 11 | 12 | 13 | //Method declaration not in HeaderExample.c 14 | int add(int i); 15 | 16 | 17 | #endif /* HEADEREXAMPLE_H_ */ 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /HeaderFileExamples/HeaderExampleDefine.c: -------------------------------------------------------------------------------- 1 | /* 2 | * HeaderExampleDefine.c 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include "HeaderExample.h" 8 | 9 | 10 | 11 | 12 | /** 13 | * Method defined in another file but will be linked with 14 | * the other c file through the h file at compile time. 15 | */ 16 | int add(int i) { 17 | return i += i; 18 | } 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /KeyWordsInC/Const.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Const.c 3 | * 4 | * Created on: Mar 25, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | //constant 10 | 11 | int main(void) { 12 | 13 | const int peter = 90;// constant integer unmodifiable 14 | 15 | int * const Ptr = &peter;//constant pointer, must always be pointing to that address. 16 | // So I can still change the VALUE stored at that address. I can not assign this pointer to another address. 17 | 18 | *Ptr = 22;//changes value of the pointer. This is legal as I am not changing the ADDRESS, which is constant 19 | 20 | 21 | /** 22 | * This is a double constant variable, that means that the dereference can NOT be changed or 23 | * the address can NOT be changed. 24 | */ 25 | const int * const alex = Ptr; 26 | 27 | 28 | printf("%d \n", *Ptr); 29 | printf("%d", *alex); 30 | 31 | return 0; 32 | 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /KeyWordsInC/Static.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Static.c 3 | * 4 | * Created on: Mar 29, 2013 5 | * Author: Aj Norton 6 | */ 7 | /** 8 | * Static variables can only be viewed and used in the file 9 | * ONLY they are declared in. 10 | */ 11 | #include 12 | 13 | static int increment(void); 14 | 15 | int sum; // Can be used in other files, has external linkage. has static storage. 16 | static int item; //Can only be used in this file. has internal linkage and static storage. 17 | 18 | int main(void) { 19 | 20 | for (int i = 0; i < 100; i++) { 21 | sum += increment(); // increases from the previous time increment was run 22 | //so 1+2+3+4....+99+100 = 5050. 23 | } 24 | 25 | printf("%d", sum);// prints out 5050, sum of 1 through 100 26 | 27 | return 0; 28 | } 29 | 30 | static int increment(void) { // Static methods can only be viewed in the file they are declared in. 31 | /** 32 | * A static variable is stored at the beginning of the execution of the 33 | * program and stays there indefinitely throughout the execution 34 | * and retains its value. 35 | */ 36 | static int pie = 1; // only initialized once, NOT every time the method is called. 37 | return pie++;//increments pie AFTER returning it. 38 | } 39 | 40 | -------------------------------------------------------------------------------- /KeyWordsInC/Switch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Switch.c 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | /** 9 | * A switch statement is a way to evaluate multiple conditions based on a variable without 10 | * using a huge if-else statement. 11 | */ 12 | #include 13 | 14 | int main(void) { 15 | 16 | int number; 17 | 18 | printf("what is the meaning of life? please pick 0,1, or 42. \n"); 19 | 20 | scanf("%d", &number); // asks for input on the number 21 | 22 | switch (number) { // based on your input in the switch statement, prints out the indicated block then breaks 23 | //out of the switch block. 24 | case 0: 25 | printf("INCORRECT"); 26 | break; 27 | case 1: 28 | printf("INCORRECT"); 29 | break; 30 | case 42: 31 | printf("CORRECT"); 32 | break; 33 | 34 | default://this is run in the switch statement if none of the cases are executed. 35 | printf("you selected none of the above"); 36 | break; 37 | 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /KeyWordsInC/Typedef.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Typedef.c 3 | * 4 | * Created on: Mar 29, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | 9 | #include 10 | 11 | typedef int score; //lets score take the type of int. 12 | typedef double cents;//cents can now be substituted for double. 13 | 14 | typedef int * roster;// You can do the same with pointers, just add a '*'. 15 | 16 | /** 17 | * You can use typedef on structs, unions, or enums to make declaring 18 | * them easier, just add a name after the declaration and a semicolon. 19 | */ 20 | typedef struct{ 21 | 22 | char name; 23 | 24 | }Cowboy; 25 | 26 | int main(void) 27 | { 28 | score team1 = 20; 29 | 30 | Cowboy cow = {'a'};// Initializing structure. 31 | 32 | roster ros = &team1; 33 | 34 | printf("%d \n", *ros);//prints out 20 35 | 36 | 37 | 38 | printf("%d \n", team1);//prints 20 39 | 40 | printf("%c", cow.name);//prints 'a'. 41 | 42 | 43 | 44 | 45 | 46 | return 0; 47 | } 48 | 49 | -------------------------------------------------------------------------------- /KeyWordsInC/Union.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Union.c 3 | * 4 | * Created on: Mar 22, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | #include 9 | 10 | /** 11 | * A union only allocates memory for the biggest member (variable type). 12 | * The members are stored in the same address so declaring one will overwrite the 13 | * other. Because of this we can store either i or d but NOT both. 14 | */ 15 | union Number { 16 | int i; 17 | double d; 18 | }; 19 | 20 | int main(void) { 21 | 22 | /** 23 | * Using a union type we can make arrays that can contain multiple types 24 | * like the one shown below. A problem is that we do not know which exact positions 25 | * contain integers and which contain doubles. 26 | */ 27 | union Number array[10] = { 1, 2.1, 3.14, 4, 5, 6, 7, 9.9, 9000, 100.1 }; 28 | 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /LinkedList/list.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Purpose: This is an example of a structure independent 3 | * linked list in C. This way you can have a linked list 4 | * that is independent of the structure you want to link 5 | * together. This implementation is a doubly list with 6 | * head and tail sentinel nodes for convenience. 7 | */ 8 | 9 | #include 10 | #include 11 | #include "list.h" 12 | 13 | 14 | void list_initialize(struct list * list) 15 | { 16 | assert(list != NULL); 17 | 18 | list->head.prev = NULL; 19 | list->tail.next = NULL; 20 | 21 | list->head.next = &list->tail; 22 | list->tail.prev = &list->head; 23 | } 24 | 25 | struct list_elem * list_begin(struct list * list) 26 | { 27 | return list->head.next; 28 | } 29 | 30 | void insert(struct list_elem * before, 31 | struct list_elem * element){ 32 | 33 | element->next = before; 34 | element->prev = before->prev; 35 | 36 | before->prev->next = element; 37 | before->prev = element; 38 | } 39 | 40 | void list_push_front(struct list * list, 41 | struct list_elem * elem){ 42 | 43 | insert(list_begin(list), elem); 44 | } 45 | 46 | 47 | struct list_elem * list_remove(struct list_elem * elem) 48 | { 49 | 50 | elem->prev->next = elem->next; 51 | elem->next->prev = elem->prev; 52 | 53 | elem->next = NULL; 54 | elem->prev = NULL; 55 | 56 | return elem->next; 57 | } 58 | 59 | struct list_elem * list_pop_front(struct list * list) 60 | { 61 | struct list_elem * begin = list_begin(list); 62 | remove(begin); 63 | return begin; 64 | 65 | } 66 | 67 | 68 | 69 | int main() 70 | { 71 | struct list * list = malloc(sizeof(struct list)); 72 | list_initialize(list); 73 | struct person * aj = 74 | malloc(sizeof(struct person)); 75 | 76 | aj->age = 33; 77 | aj->firstInitial = 'a'; 78 | aj->height = 170; 79 | 80 | 81 | struct person * bob = 82 | malloc(sizeof(struct person)); 83 | 84 | bob->age = 99; 85 | 86 | 87 | list_push_front(list,&aj->elem); 88 | list_push_front(list,&bob->elem); 89 | 90 | struct person * returned = 91 | list_entry(list_pop_front(list), 92 | struct person, 93 | elem); 94 | printf("%d",returned->age); 95 | 96 | 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /LinkedList/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C_tutorial.h 3 | * 4 | * Created on: May 17, 2014 5 | * Author: marknorton 6 | */ 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #ifndef C_TUTORIAL_H_ 13 | #define C_TUTORIAL_H_ 14 | 15 | struct list_elem 16 | { 17 | struct list_elem *prev; /* Previous list element. */ 18 | struct list_elem *next; /* Next list element. */ 19 | }; 20 | 21 | /* List. */ 22 | struct list 23 | { 24 | struct list_elem head; /* List head. */ 25 | struct list_elem tail; /* List tail. */ 26 | }; 27 | 28 | 29 | struct person{ 30 | int age; 31 | char firstInitial; 32 | float height; 33 | struct list_elem elem; 34 | }; 35 | 36 | 37 | #define list_entry(LIST_ELEM, STRUCT, MEMBER) \ 38 | ((STRUCT *) ((uint8_t *) &(LIST_ELEM)->next \ 39 | - offsetof (STRUCT, MEMBER.next))) 40 | 41 | 42 | 43 | #endif /* C_TUTORIAL_H_ */ 44 | -------------------------------------------------------------------------------- /MacrosInC/Macros.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Macros.c 3 | * 4 | * Created on: Mar 26, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | #define SWAP(a,b) a^=b; b^=a; a^=b; // swaps the two parameters using genius bit manipulation. 9 | #define MAX(a,b) a > b? a :b //easy one line macros 10 | #define MIN(a,b) a > b ? b: a 11 | 12 | /** 13 | * You want to define multiple line macros like the macro below with parenthesis around the macro arguments. 14 | * Notice the parenthesis around the macro parameters during the assignments. This is because 15 | * some actions take precedence over the others (*,+,-) and instead of memorizing them you can cancel 16 | * this out by using parenthesis. 17 | * 18 | * The standard is that macros are defined in capital letters. 19 | */ 20 | #define FOURTHPOWER(a) \ 21 | do{\ 22 | (a) = (a)*(a);\ 23 | (a) = (a) * (a);\ 24 | }while(0) // No semicolon like you would have on a non-macro do-while loop. 25 | int main(void) { 26 | 27 | int a = 2; 28 | FOURTHPOWER(a); 29 | 30 | printf("%d", a); //prints out 16 31 | 32 | return 0; 33 | } 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /MemoryAllocation/Malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Malloc.c 3 | * 4 | * Created on: Mar 24, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | #include 9 | #include 10 | #define STRINGSIZE 100 11 | 12 | 13 | /** 14 | * If you did not know the size of something such as a array structure, or string at compile time 15 | * you can allocate memory dynamically be using the malloc() function which will grab the amount 16 | * of memory you need. Dynamic memory will be allocated on the heap. 17 | */ 18 | 19 | int main(void) { 20 | char * string = NULL; 21 | const char *source = "this is a string"; 22 | 23 | puts("allocated memory for the pointer"); 24 | string = malloc(STRINGSIZE * sizeof(char));// allocate memory for the string 25 | //make sure to use the sizeof() command to make your code easily transferable to different computers 26 | 27 | if(string == NULL)//checks that malloc worked properly. 28 | { 29 | printf("Failed to allocate memory for the string"); 30 | 31 | exit(1);// exits the program 32 | } 33 | 34 | 35 | 36 | 37 | strncpy(string,source,STRINGSIZE); //copies the string to the variable string. 38 | 39 | 40 | printf("this is the string: %s \n", string); 41 | 42 | puts("free memory"); 43 | free(string); 44 | /** frees the dynamically allocated memory, this is very important. Not doing this can cause you 45 | to leak memory and your program to crash as you keep asking for more and more memory you need to free 46 | it to tell the computer that this memory can be used for something else instead of asking for more 47 | memory.. 48 | */ 49 | 50 | 51 | /**It is also good practice to set your your malloced pointer to NULL after freeing it 52 | so you do not have a pointer to some place in memory that you have no authority to read/write to. 53 | */ 54 | string = NULL; 55 | 56 | return 0; 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /PointersInC/FuncsWithPointers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FuncsWithPointers.c 3 | * 4 | * Created on: Mar 26, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | void cubeByPointer(int *); // takes an address as a pointer. 10 | int cubeByParameter(int); // takes an integer as a parameter. 11 | 12 | int main(void) { 13 | 14 | int i = 9; 15 | int *Ptr = &i; 16 | 17 | cubeByParameter(i); //copies value into function does not change actual value of i. 18 | //If I assigned the above value to i, ( i = cubeByParameter(i); ) that will change the value 19 | //of i as well. 20 | 21 | printf("%d \n", i); 22 | 23 | cubeByPointer(Ptr); //Changes the value at the ADDRESS of i, so this will change the value of i outside the main function. 24 | printf("%d", i); 25 | 26 | return 0; 27 | } 28 | 29 | void cubeByPointer(int *i) { 30 | *i = *i * *i * *i; // note that I am using a indirection operator and a multiplication operator, which are the same symbol (*) 31 | //in this example. 32 | } 33 | 34 | int cubeByParameter(int i) { 35 | 36 | i = i * i * i; 37 | return i; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /PointersInC/PointerArithmetic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PointerArithmetic.c 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | int main(void) { 10 | 11 | /** 12 | * I declared a multidimensional array of 2 rows and 10 columns 13 | * The way pointer arithmetic works is that is treats the locations in 14 | * memory as the same as ONE array so you can do the same operators on 15 | * 1-D arrays as 2-D or bigger arrays. All the memory of an array is stored 16 | * continuously together. 17 | */ 18 | int A[2][10] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; 19 | 20 | int *Pointer = A;//Assigns pointer address of the array of position [0][0] 21 | 22 | Pointer =Pointer + 7;// now at position 8 23 | 24 | 25 | printf("%d \n",*Pointer);// prints out 7. 26 | 27 | 28 | Pointer -= 4; //Now at position 3. 29 | 30 | 31 | printf("%d \n",*Pointer);// prints out 3. 32 | 33 | Pointer += 15;// Going to the second tow, totally valid. 34 | 35 | printf("%d",*Pointer );//Prints out 18 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | return 0; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /PointersInC/PointerMethods.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PointerMethods.c 3 | * 4 | * Created on: Apr 2, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | #include 9 | 10 | int cube(int *); //takes a pointer, either a pointer of a variable address. 11 | 12 | int* assignNinety(int *); //takes a pointer AND returns a pointer. 13 | 14 | int main(void) { 15 | 16 | int i = 60; 17 | 18 | int *iPtr = &i; 19 | 20 | cube(&i); //pass in address of i which is valid. you could also pass in iPtr. 21 | 22 | printf("%d \n", *assignNinety(&i)); 23 | /**prints out 90, not how I dereference 24 | it because the method returns a pointer. 25 | This does not change the value of i, as the i in main and the i in 26 | assignNintely are completely different. 27 | */ 28 | 29 | printf("%d", i); //prints out the cube of 60 (21600). 30 | 31 | return 0; 32 | } 33 | 34 | int cube(int *number) { 35 | *number = *number * *number * *number; //cubing the number 36 | return *number; //returns the newly cubed number. 37 | 38 | } 39 | 40 | int * assignNinety(int * integer) { //returns a pointer and takes a pointer. 41 | int i = 90; 42 | 43 | integer = &i; 44 | 45 | return integer; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /PointersInC/PointerToFunctions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PointerToFunctions.c 3 | * 4 | * Created on: Apr 8, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | int f(int i) { 10 | return i; 11 | } 12 | 13 | int main(void) { 14 | 15 | int (*funcs[])(int) = {f,f,f}; //Array of Pointers to multiple functions. 16 | 17 | int (*fFunction)(int) = f; //Pointer to function 18 | 19 | printf("%d", (*funcs)(65)); 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /PointersInC/Pointers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Pointers.c 3 | * 4 | * Created on: Mar 21, 2013 5 | * Author: Aj Norton 6 | */ 7 | #include 8 | 9 | int main(void) { 10 | int i = 90; 11 | 12 | /** 13 | * Pointers are similar to variables in that they simply store values. 14 | * The difference is that there values are ADDRESSES to non-pointer variables 15 | * or possible other pointers (in the case of a double pointer. 16 | */ 17 | 18 | /** 19 | * the "*" symbol is called the dereferencing symbol and this is getting the value 20 | * contained within the pointer 21 | */ 22 | 23 | /** 24 | * the "&" symbol is the address symbol and returns the address, also known as 25 | * where in memory the variable is stored. 26 | */ 27 | 28 | /** 29 | *The below declaration is declaring a DOUBLE pointer (**) 30 | *which is a pointer to a pointer. It is possible to have a triple pointer (***) 31 | *and beyond (infinite possibilities). 32 | */ 33 | 34 | 35 | 36 | int **q1 = NULL; // Pointers should be initialized to NULL or 0 when not used. 37 | int *q2 = &i; //pointers must be assigned addresses. 38 | 39 | /** 40 | * Since q2 contains the address of variable i. The variable i can be indirectly changed 41 | * by using the dereferencing symbol (*). This changes i to 45 since q2 is pointing to i. 42 | */ 43 | *q2 = 45; 44 | 45 | q1 = &q2; // the double pointer needs the address of a pointer. 46 | 47 | //the next 3 statements print out identical addresses 48 | //each addresses will be different when run on different computers 49 | printf("%d \n", *q1); // prints out the value stored in q1, which is the address of i 50 | 51 | printf("%d \n", q2); // prints out the value of q2, which is the address of i (same as above). 52 | 53 | printf("%d \n", &i);// prints out the address of i too. 54 | 55 | printf("%d \n", *q2); // prints out the value of q2 (45). 56 | 57 | printf("%d \n", i);// prints out 45 as well. 58 | 59 | printf("%d \n", **q1);// You can double dereference something to get a value as well 60 | //(if it is a double pointer) This will print out 45 as well. 61 | 62 | 63 | 64 | return 0; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /PointersInC/README.md: -------------------------------------------------------------------------------- 1 | This section covers the wonderful world of pointers. Pointers are very powerful and can be used in a variety of ways and are essential knowledge for any C programmar. 2 | 3 | #####Other links you can check out: 4 | 5 | *[http://pw1.netcom.com/~tjensen/ptr/ch1x.htm (indepth tutorial)](http://pw1.netcom.com/~tjensen/ptr/ch1x.htm) 6 | 7 | * [http://www.cprogramming.com/tutorial/c/lesson6.html](http://www.cprogramming.com/tutorial/c/lesson6.html) 8 | 9 | * [http://www.tutorialspoint.com/cprogramming/c_pointers.htm](http://www.tutorialspoint.com/cprogramming/c_pointers.htm) 10 | 11 | 12 | 13 | 14 | ###Questions, Concerns, flat out mistakes? Feel free to contact me as always. 15 | 16 | > [Contact me (applejuiceteaching@gmail.com)](mailto:applejuiceteaching@gmail.com) 17 | -------------------------------------------------------------------------------- /PointersInC/VoidPointer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VoidPointer.c 3 | * 4 | * Created on: Apr 17, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | 9 | 10 | #include 11 | #include 12 | 13 | typedef struct { 14 | 15 | int i; 16 | void * anything;// Void Pointer declared. 17 | 18 | } Structure; 19 | 20 | int main(void) { 21 | 22 | Structure s; 23 | 24 | /** 25 | * Since malloc returns a void pointer as well I have no problem 26 | * making i the size of anything and casting it laster if desired. 27 | */ 28 | s.anything = malloc(sizeof(int)); 29 | 30 | *((int *) s.anything) = 5; //I can assign the void target a value as long as I put 31 | //the appropriate cast. 32 | 33 | printf("%d", *((int *) s.anything)); // Prints out 5. 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /PracticeProblems/README.md: -------------------------------------------------------------------------------- 1 | Practice Problems 2 | --- 3 | 4 | These are practice problems to further your learning. I will post my solutions and problem statements in this folder. 5 | Feel free to submit your solutions and comments! 6 | 7 | --- 8 | 9 | 1. Write a program to given two rectangles find print out if they intersect or not. 10 | 11 | 12 | --- -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | C programming tutorials 3 | =========== 4 | > [You can view my videos on these examples on youtube](http://www.youtube.com/playlist?list=PLJ7II9mlYqWjIsuhVdbqhiigU2bKYtrmE) 5 | 6 | This is merely an educational means to teach myself and others C programming. I invite anyone to modify it and send me suggestions. If your new to C, I suggest reading the C_programming_readings folder and looking at the example folders 7 | to get started and then trying the practice problems when ready. 8 | 9 | ######Other helpful links: 10 | 11 | * [http://www.cprogramming.com/tutorial.html](http://www.cprogramming.com/tutorial.html) 12 | * [http://www.tutorialspoint.com/cprogramming](http://www.tutorialspoint.com/cprogramming/) 13 | * [The New Boston's C tutorials ](https://www.youtube.com/playlist?list=PL78280D6BE6F05D34) 14 | 15 |
16 | 17 | Books to check out: 18 | * [C Programming a modern approach](http://www.amazon.com/exec/obidos/ASIN/0393969452/lynnallain) 19 | * [C programming: by the creators of the language](http://www.amazon.com/exec/obidos/ASIN/0131103628/lynnallain) 20 | * [C for dummies](http://www.amazon.com/exec/obidos/ASIN/1878058789/lynnallain) 21 | 22 | 23 | --- 24 | 25 | ###Compiling In C using GCC 26 | 27 | 28 | ######Note: All of these programs have a main method to be run separately so please to make sure you compile and run the example on its own if you are using gcc you can use: 29 | 30 | ``` 31 | gcc -o BitChange BitChange.c # you want: gcc -o ... 32 | #Note you do not need <> in the terminal or put in .h files, that is linked for you. 33 | ``` 34 | 35 | #####Then you can run it from your terminal in the directory of the executable with ./{executable name} 36 | 37 | --- 38 | 39 |
40 |
41 | 42 | 43 | 44 | 45 | ####Questions, Concerns, flat out mistakes? Feel free to contact me as always. 46 | 47 | > [Contact me (applejuiceteaching@gmail.com)](mailto:applejuiceteaching@gmail.com) 48 | -------------------------------------------------------------------------------- /StringsInC/StringArray.c: -------------------------------------------------------------------------------- 1 | /* 2 | * StringArray.c 3 | * 4 | * Created on: Apr 16, 2013 5 | * Author: Aj Norton 6 | */ 7 | 8 | #include 9 | 10 | int main(void) { 11 | char *stringArray[5] = { 0 }; // create an array of char pointers which can be thought of as strings. 12 | 13 | //assigns different strings at different positions. 14 | stringArray[0] = "hello"; 15 | stringArray[1] = "my "; 16 | stringArray[2] = "name"; 17 | stringArray[3] = "is"; 18 | stringArray[4] = "A.J."; 19 | 20 | printf("%s", stringArray[0]); //prints out hello. 21 | printf("%s", stringArray[1]); //prints out my . 22 | printf("%s", stringArray[2]); //prints out name. 23 | 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /StringsInC/StringCompare.c: -------------------------------------------------------------------------------- 1 | /* 2 | * StringCompare.c 3 | * 4 | * Created on: Apr 29, 2013 5 | * Author: Aj Norton 6 | * 7 | * 8 | * This file shows an example of how to write a string compare method, 9 | * how to iterate through a string and compare them. 10 | * 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | bool compare(char * string1, char * string2); 19 | 20 | int main(void) 21 | { 22 | char * string1 = NULL; 23 | char * string2 = "ajnjjj"; 24 | 25 | printf("%d", compare(string1,string2)); 26 | 27 | return 0; 28 | } 29 | 30 | bool compare(char *string1,char *string2) 31 | { 32 | if(string1 == NULL || string2 == NULL) return false; 33 | 34 | 35 | if(strlen(string1) != strlen(string2)) return false; 36 | 37 | while( *string1 != '\0' || *string2 != '\0')//Loops through strings until null terminator is found. 38 | { 39 | if(*string1 != *string2)//if the chars are different, the strings are not the same, return false. 40 | { 41 | return false; 42 | } 43 | string1++; 44 | string2++; 45 | } 46 | 47 | return true; 48 | } 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /StringsInC/StringCounter.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int * countLetters(char * string); 4 | 5 | int main(void) { 6 | 7 | /** 8 | * Pointers are really just placers to keep track of where you are 9 | * in a list or array or which variable you are holding. If you think 10 | * of a string as an array of characters, you can use you pointer to 11 | * navigate to each character. 12 | */ 13 | 14 | char * string = "abccdefffffff"; 15 | 16 | int *Counter = countLetters(string); 17 | 18 | for (int i = 0; i < 256; i++) { 19 | printf("%d is at the position %d \n", Counter[i], i); 20 | 21 | } 22 | free(Counter); 23 | Counter = NULL; 24 | 25 | return 0; 26 | } 27 | 28 | int * countLetters(char * string) { 29 | int *Ptr = malloc(sizeof(int) * 256); 30 | 31 | /** 32 | * This While loop increments the pointer to the next position in memory which 33 | * contains the next character because all the variables are stored next to 34 | * each other in memory. 35 | */ 36 | while (*string != '\0') { 37 | Ptr[*string]++; 38 | string++; 39 | } 40 | 41 | return Ptr; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /StructuresInC/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //@author AJ Norton 5 | 6 | typedef struct { // initializes a structure 7 | //typef is used to avoid writing "struct" and just have to write the type "food" 8 | 9 | int calories;// variable contained in each struct. 10 | int fat; 11 | 12 | struct food *pointer; // a structure can contain a pointer to the same structure type or any other type. 13 | } food; 14 | 15 | 16 | int main() { 17 | 18 | food sandwich = {500,12}; //Initializes calories to 500. and fat to 12 19 | 20 | food burger = {400}; //Initializes calories to 400 and fat to 0. 21 | //the initialize format works by assigning values to the variables from top to bottom in the struct 22 | //so the order of the struct variables in the definition impacts how they are defined. 23 | //in this case calories is defined first because it is the first thing defined in the struct, fat is second and so on 24 | 25 | burger.calories = 100; //changes the number of calories in the structure by using Dot notation. 26 | //dot notation can be used to access the variable and modify it. 27 | 28 | 29 | food *pointerToFood = &sandwich; // declares a pointer of type food and assigns it the address of sandwich 30 | 31 | 32 | 33 | pointerToFood->pointer = &burger;// uses arrow notation which is how you assign values to POINTERS 34 | 35 | 36 | //This will loop through the pointer until it pointing to NUll, it keeps assigning the pointer to the pointer 37 | //of the struct is currently pointing to, this provides a way to link structure and loop through them. 38 | 39 | for(;pointerToFood != NULL; pointerToFood = pointerToFood->pointer) 40 | { 41 | printf("%d \n",pointerToFood->calories ); 42 | } 43 | 44 | 45 | /** 46 | * output: 47 | * 500 48 | * 100 49 | */ 50 | 51 | 52 | 53 | 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /StructuresInC/structExample1.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | /** 5 | * A struct which is short for structure is another type of variable 6 | * that can be used to define a list of multiple different variables. A struct 7 | * can contain structs of itself or any other variable. This is a nice way of organizing 8 | * information under one header. 9 | */ 10 | 11 | struct player { 12 | 13 | int number; 14 | char position; 15 | struct player *pointer; 16 | 17 | }; 18 | 19 | int main(void) { 20 | /** 21 | * You can initialize structs in by the below notation and specifying their start values 22 | * in the order the variables are declared in the struct form top to bottom. So the number, 23 | * position and pointer must be initialized in that order. 24 | */ 25 | struct player robin = { 33, 'r', NULL }; 26 | struct player alfred = { 12, 'c', &robin }; 27 | 28 | //You can also have pointer to structs just as you can with any other variable 29 | struct player *batman = &alfred; 30 | 31 | for (; batman != NULL ; batman = batman->pointer) { 32 | /** 33 | To get a single variable out of a struct (from a pointer to a struct, you use the 34 | arrow notation "->". 35 | */ 36 | printf("%d \n", batman->number); 37 | } 38 | 39 | //This is how you print out an attribute from a struct that is not a pointer, you use the dot notation. 40 | printf("%d \n", robin.number); 41 | 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /StructuresInC/structExample2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | //@author AJ Norton 5 | 6 | typedef struct { // initializes a structure 7 | //typef is used to avoid writing "struct" and just have to write the type "food" 8 | 9 | int calories;// variable contained in each struct. 10 | int fat; 11 | 12 | struct food *pointer; // a structure can contain a pointer to the same structure type or any other type. 13 | } food; 14 | 15 | 16 | int main() { 17 | 18 | 19 | 20 | 21 | food sandwich = {500,12}; //Initializes calories to 500. and fat to 12 22 | 23 | food burger = {400}; //Initializes calories to 400 and fat to 0. 24 | //the initialize format works by assigning values to the variables from top to bottom in the struct 25 | //so the order of the struct variables in the definition impacts how they are defined. 26 | //in this case calories is defined first because it is the first thing defined in the struct, fat is second and so on 27 | 28 | burger.calories = 100; //changes the number of calories in the structure by using Dot notation. 29 | //dot notation can be used to access the variable and modify it. 30 | 31 | 32 | food *pointerToFood = &sandwich; // declares a pointer of type food and assigns it the address of sandwich 33 | 34 | 35 | 36 | pointerToFood->pointer = &burger;// uses arrow notation "->" which is how you assign values to POINTERS 37 | 38 | 39 | //This will loop through the pointer until it pointing to NUll, it keeps assigning the pointer to the pointer 40 | //of the struct is currently pointing to, this provides a way to link structure and loop through them. 41 | 42 | for(;pointerToFood != NULL; pointerToFood = pointerToFood->pointer) 43 | { 44 | printf("%d \n",pointerToFood->calories ); 45 | } 46 | 47 | 48 | /** 49 | * output: 50 | * 500 51 | * 100 52 | */ 53 | 54 | 55 | 56 | 57 | 58 | return 0; 59 | } 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /SystemLevelInterfacing/fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | * fork.c 3 | * 4 | * Created on: Jan 23, 2014 5 | * Author: marknorton 6 | */ 7 | 8 | #include 9 | 10 | //constant 11 | 12 | int main(void) { 13 | 14 | /** 15 | * the fork() function runs the same program in a new child process that is a 16 | * duplicate of the parent. The only difference is that the fork() function returns 17 | * TWICE! once in the parent process and once in the child process since you have 18 | * duplicated the processes. 19 | * 20 | * The child process will always return 0 so you can check for that in an if statement 21 | * as shown below. 22 | * 23 | * The parent will return the process ID (pid) of the child for the parent to keep track of 24 | * in a jobs list for example. 25 | */ 26 | 27 | printf("hello \n"); 28 | int a = fork(); 29 | 30 | int x = 1; 31 | 32 | if (a == 0) {//Child check 33 | 34 | printf("x is %d \n", ++x); 35 | exit(0); 36 | } 37 | 38 | printf("other x is %d \n", --x); 39 | 40 | /** 41 | other x is 0 42 | x is 2 43 | */ 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /TestingInC/Assert.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Assert.c 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: marknorton 6 | */ 7 | 8 | #include 9 | #include 10 | int magic(int size,int *Ptr); 11 | 12 | int main(void) { 13 | int a = 4; 14 | int * Ptr = &a; 15 | magic(10,Ptr); 16 | puts("done"); 17 | return 0; 18 | } 19 | int magic(int size,int *Ptr) 20 | { 21 | /** 22 | * Assert checks if a certain condition is true, if that condition is not true, 23 | * the program terminates with the error of the assert failing. This is very helpful for 24 | * testing and a good coding practice in C to put them anywhere you could get a NULL or 25 | * number out of range. 26 | * 27 | */ 28 | assert(Ptr != (NULL)); 29 | assert(size >= 30); 30 | 31 | return 1; 32 | 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /Threading/Mutexes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mutexes.c 3 | * 4 | * Created on: Feb 22, 2014 5 | * Author: marknorton 6 | */ 7 | #include 8 | #include 9 | 10 | #define NUMTHRDS 2 11 | 12 | pthread_t t [ NUMTHRDS]; 13 | int coin_flip; 14 | 15 | pthread_mutex_t flip_done; 16 | 17 | static void *thread2(void *_){ 18 | pthread_mutex_lock(&flip_done); 19 | printf("Thread 2: flipped coin %d\n", coin_flip); 20 | } 21 | 22 | 23 | static void * thread1(void * _) 24 | { 25 | coin_flip = 23; 26 | printf("Thread 1: flipped coin %d\n", coin_flip); 27 | pthread_mutex_unlock(&flip_done); 28 | } 29 | 30 | int main() 31 | { 32 | pthread_mutex_init(&flip_done, NULL); 33 | pthread_mutex_lock(&flip_done); 34 | pthread_create(&t[1], NULL, thread2, NULL); 35 | pthread_create(&t[0], NULL, thread1, NULL); 36 | 37 | pthread_mutex_destroy(&flip_done); 38 | 39 | //must have this as main will block until all the supported threads are done 40 | pthread_exit(NULL); 41 | 42 | 43 | return 1; 44 | } 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Threading/threadIntro.c: -------------------------------------------------------------------------------- 1 | /* 2 | * threadIntro.c 3 | * 4 | * Created on: Feb 22, 2014 5 | * Author: marknorton 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | #define NUMTHRDS 2 13 | 14 | pthread_t t [ NUMTHRDS]; 15 | 16 | 17 | static void *thread2(void *_){ 18 | printf("Thread 2: flipped coin %d\n", coin_flip); 19 | } 20 | 21 | 22 | static void * thread1(void * _) 23 | { 24 | 25 | coin_flip = 23; 26 | printf("Thread 1: flipped coin %d\n", coin_flip); 27 | } 28 | 29 | int main() 30 | { 31 | /** 32 | * You have no idea what order initial threads will be done with first 33 | * 34 | */ 35 | pthread_create(&t[1], NULL, thread2, NULL); 36 | pthread_create(&t[0], NULL, thread1, NULL); 37 | 38 | 39 | //must have this as main will block until all the supported threads are done 40 | pthread_exit(NULL); 41 | 42 | 43 | return 1; 44 | } 45 | 46 | 47 | --------------------------------------------------------------------------------