Initial commit
						commit
						ce99fa7612
					
				| @ -0,0 +1,34 @@ | ||||
| # ---> C | ||||
| # Object files | ||||
| *.o | ||||
| *.ko | ||||
| *.obj | ||||
| *.elf | ||||
| 
 | ||||
| # Precompiled Headers | ||||
| *.gch | ||||
| *.pch | ||||
| 
 | ||||
| # Libraries | ||||
| *.lib | ||||
| *.a | ||||
| *.la | ||||
| *.lo | ||||
| 
 | ||||
| # Shared objects (inc. Windows DLLs) | ||||
| *.dll | ||||
| *.so | ||||
| *.so.* | ||||
| *.dylib | ||||
| 
 | ||||
| # Executables | ||||
| *.exe | ||||
| *.out | ||||
| *.app | ||||
| *.i*86 | ||||
| *.x86_64 | ||||
| *.hex | ||||
| 
 | ||||
| # Debug files | ||||
| *.dSYM/ | ||||
| 
 | ||||
| @ -0,0 +1,7 @@ | ||||
| # Learn C | ||||
| 
 | ||||
| This repository is an experimental playground for learning C programming. The inspiration for learning C is three fold: | ||||
| 
 | ||||
| 1. Embedded programming | ||||
| 2. Operating systems | ||||
| 3. Python integration | ||||
| @ -0,0 +1,24 @@ | ||||
| //Demonstrates a simple function in C code
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| long cube(long x); | ||||
| 
 | ||||
| long input, answer; | ||||
| 
 | ||||
| int main(void){ | ||||
| 	printf("Enter an integer value: "); | ||||
| 	scanf("%ld", &input); | ||||
| 	answer = cube(input); | ||||
| 	 | ||||
| 	printf("\nThe cube of %ld is %ld.\n", input, answer); | ||||
| 	 | ||||
| 	return 0; | ||||
| 	 | ||||
| 	} | ||||
| 	 | ||||
| long cube(long x){ | ||||
| 	long x_cubed; | ||||
| 	 | ||||
| 	x_cubed = x * x * x; | ||||
| 	return x_cubed; | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| float celcius_to_fahrenhiet(float celcius) | ||||
| { | ||||
| 	return celcius * 9/5 + 32; | ||||
| } | ||||
| 
 | ||||
| float celcius_to_kelvin(float celcius) | ||||
| { | ||||
| 	return celcius + 273.15f; | ||||
| } | ||||
| @ -0,0 +1,3 @@ | ||||
| float celcius_to_fahrenhiet(float celcius); | ||||
| 
 | ||||
| float celcius_to_kelvin(float celcius); | ||||
| @ -0,0 +1,34 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include "temp.h" | ||||
| 
 | ||||
| float celcius = 0; | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 
 | ||||
| 	if(argc != 2) | ||||
| 	{ | ||||
|         /* We print argv[0] assuming it is the program name */ | ||||
|         printf( "usage: %s requires an integer argument\name", argv[0] ); | ||||
|         return 1; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     	printf("Argument: %s\n\n", argv[1]); | ||||
|     	//cast char type to float
 | ||||
|     	celcius = (float)atof(argv[1]); | ||||
| 
 | ||||
|     	while (celcius < 110) | ||||
| 		{ | ||||
| 			printf("%.2f C = %.2f F = %.2f K\n", celcius, | ||||
| 			celcius_to_fahrenhiet(celcius), | ||||
| 			celcius_to_kelvin(celcius) | ||||
| 		 	); | ||||
| 
 | ||||
| 			celcius = celcius + 10; | ||||
| 		} | ||||
|     } | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| # import <stdio.h> | ||||
| 
 | ||||
| int main(){ | ||||
| 
 | ||||
| 	char name[10] = "Laura"; | ||||
| 
 | ||||
| 	printf("Hello %s!\n", name); | ||||
| 	return 0; | ||||
| } | ||||
| @ -0,0 +1,32 @@ | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| //In order to share state between functions want to use static variables in file scope
 | ||||
| //At file scope like this static variables are only available within the same source file
 | ||||
| //removing static it's possible that other files could cause name collision
 | ||||
| 
 | ||||
| static int eggs;  //defaults to zero unless you provide your own initializer
 | ||||
| 
 | ||||
| 
 | ||||
| void up() | ||||
| { | ||||
| 	eggs += 10; | ||||
| } | ||||
| 
 | ||||
| void down() | ||||
| { | ||||
| 	eggs -= 5; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
| 	up(); | ||||
| 	up(); | ||||
| 	down(); | ||||
| 
 | ||||
| 	//Here we are sharing state across functions and at the end of this should have 15 eggs
 | ||||
| 
 | ||||
| 	printf("You have %d eggs\n", eggs); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -0,0 +1,60 @@ | ||||
| /*
 | ||||
| Structures allow us to construct a collection or sequence of variables, which can be of any type | ||||
| */ | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| //ask dan
 | ||||
| typedef unsigned char byte; | ||||
| 
 | ||||
| //alternative method is wrapping struct in a typedef
 | ||||
| //The compiler doesn't care
 | ||||
| typedef struct Color | ||||
| { | ||||
| 	/* data */ | ||||
| 	byte Red; | ||||
| 	byte Green; | ||||
| 	byte Blue; | ||||
| } Color; | ||||
| 
 | ||||
| struct Pixel | ||||
| { | ||||
| 	/* data */ | ||||
| 	float X; | ||||
| 	float Y; | ||||
| 	Color color; | ||||
| }; | ||||
| 
 | ||||
| typedef struct Pixel Pixel; | ||||
| 
 | ||||
| void print_pixel(Pixel p){ | ||||
| 	puts("Pixel Location"); | ||||
| 	printf("X:%2f, Y:%2f\n", p.X, p.Y); | ||||
| 	puts("Pixel color"); | ||||
| 	printf("rgb(%d, %d, %d)\n", p.color.Red, p.color.Green, p.color.Blue); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
| 	//In C the compiler places structs in a different namespace
 | ||||
| 	//This requires us to use the struct keyword to have the compiler look up struct definitions
 | ||||
| 	//like so
 | ||||
| 	//struct Pixel p;
 | ||||
| 	//struct Color c;
 | ||||
| 	// but we can instead introduce the structs via typedefs and leave off the struct keyword
 | ||||
| 	//Also we can initialize structs with the following
 | ||||
| 	Color c = { 255, 128, 0 }; | ||||
| 	Pixel p = { 10.0f, 20.0f, c}; | ||||
| 	// Color c = { 255, 128 }; //Trailing members are zero initialized
 | ||||
| 
 | ||||
| 	//We can access members of structs via dot notation like so
 | ||||
| 	float x = p.X; | ||||
| 	//We can use assignment to update a member directly
 | ||||
| 	c.Blue = 255; | ||||
| 	Pixel o = { 12.0f, 22.0f, c}; | ||||
| 
 | ||||
| 	print_pixel(p); | ||||
| 	print_pixel(p); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -0,0 +1,42 @@ | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| //There are two factors at play for why our struct is taking up 12 bytes of memory
 | ||||
| //1. C and C++ require that the members of a structure are allocated in declaration order
 | ||||
| // This means that the address in memory for first must be less than second and second less than third
 | ||||
| 
 | ||||
| //2. Processors either require or prefer that types are alligned in memory such that they begin on an
 | ||||
| //address boundry that is some multiple of it's size so if second was placed after first it would be 
 | ||||
| //misaligned 
 | ||||
| 
 | ||||
| //So what we are seeing here is that the second member is padded so that it is ensured to falls on a 
 | ||||
| //on a 4 byte boundry relative to the start of the structure
 | ||||
| 
 | ||||
| //typedef struct
 | ||||
| //{
 | ||||
| //	
 | ||||
| //	short first; //xx__
 | ||||
| //	int second; //xxxx
 | ||||
| //	short third; //xx__ //this end is padded to ensure that if multiple structures were in an array that they would also be aligned
 | ||||
| //} Layout;
 | ||||
| 
 | ||||
| //reordering can help align memory and reduce memory usage
 | ||||
| // This results in an 8 byte struct
 | ||||
| typedef struct | ||||
| {	 | ||||
| 	short first; //xx
 | ||||
| 	short third; //xx
 | ||||
| 	int second; //xxxx
 | ||||
| } Layout; | ||||
| 
 | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
| 	printf("short: (%d) bytes\n", (int) sizeof(short)); | ||||
| 
 | ||||
| 	printf("int: (%d) bytes\n", (int) sizeof(int)); | ||||
| 
 | ||||
| 	//What is interesting is that the struct as a whole occupies 12 bytes not 8 like we thought
 | ||||
| 	printf("struct: (%d) bytes\n", (int) sizeof(Layout)); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -0,0 +1,37 @@ | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| //Type definition
 | ||||
| typedef unsigned char byte; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
| 	int i = 123; | ||||
| 	float f = 1.23f; | ||||
| 	double d = 2.34; | ||||
| 	char c = 'c'; | ||||
| 
 | ||||
| 	//variations
 | ||||
| 	unsigned int ui = 123u; | ||||
| 	 | ||||
| 	//short and long provide different storage depending on the compiler and platform
 | ||||
| 	//Regular int usually maps to the natural size of a word on a particular machine
 | ||||
| 	// Ex: on a 32 bit machine int == 32 bits  short == 16 bits and long == 64 bits ...or 32
 | ||||
| 	short int si = 123;  | ||||
| 	long int li = 123; | ||||
| 
 | ||||
| 	//short hand declaration of short and long
 | ||||
| 	short sh_si = 123; | ||||
| 	long sh_li = 123; | ||||
| 
 | ||||
| 	//typedef example
 | ||||
| 	byte b = 0x12; | ||||
| 
 | ||||
| 	//we have to cast the result of sizeof because it returns a value whose size is large enough
 | ||||
| 	//to hold a pointer value, but the fundamental types will never be that big so we cast
 | ||||
| 	printf("The value of i: %d (%d) bytes\n", i, (int) sizeof(int)); | ||||
| 	//this will tell us that int is 4 bytes and running in a 32 bit address space
 | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
					Loading…
					
					
				
		Reference in New Issue