commit ce99fa761271fab5615d3b91bd0b17aa13c93c53 Author: androiddrew Date: Mon May 6 21:21:21 2019 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7388b9 --- /dev/null +++ b/.gitignore @@ -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/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e344037 --- /dev/null +++ b/README.md @@ -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 diff --git a/functions/cube.c b/functions/cube.c new file mode 100644 index 0000000..0d535e3 --- /dev/null +++ b/functions/cube.c @@ -0,0 +1,24 @@ +//Demonstrates a simple function in C code +#include + +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; +} \ No newline at end of file diff --git a/headers/temp.c b/headers/temp.c new file mode 100644 index 0000000..e19bdae --- /dev/null +++ b/headers/temp.c @@ -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; +} diff --git a/headers/temp.h b/headers/temp.h new file mode 100644 index 0000000..ffe769d --- /dev/null +++ b/headers/temp.h @@ -0,0 +1,3 @@ +float celcius_to_fahrenhiet(float celcius); + +float celcius_to_kelvin(float celcius); \ No newline at end of file diff --git a/headers/temp_count.c b/headers/temp_count.c new file mode 100644 index 0000000..9ed591c --- /dev/null +++ b/headers/temp_count.c @@ -0,0 +1,34 @@ +#include +#include +#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; +} \ No newline at end of file diff --git a/hello/hello.c b/hello/hello.c new file mode 100644 index 0000000..115f6ec --- /dev/null +++ b/hello/hello.c @@ -0,0 +1,9 @@ +# import + +int main(){ + + char name[10] = "Laura"; + + printf("Hello %s!\n", name); + return 0; +} \ No newline at end of file diff --git a/static/eggs.c b/static/eggs.c new file mode 100644 index 0000000..ca83e39 --- /dev/null +++ b/static/eggs.c @@ -0,0 +1,32 @@ +#include + +//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; +} \ No newline at end of file diff --git a/structs/pixel.c b/structs/pixel.c new file mode 100644 index 0000000..3160b99 --- /dev/null +++ b/structs/pixel.c @@ -0,0 +1,60 @@ +/* +Structures allow us to construct a collection or sequence of variables, which can be of any type +*/ +#include + +//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; +} diff --git a/structs/struct2.c b/structs/struct2.c new file mode 100644 index 0000000..3795f80 --- /dev/null +++ b/structs/struct2.c @@ -0,0 +1,42 @@ +#include + +//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; +} \ No newline at end of file diff --git a/types/types.c b/types/types.c new file mode 100644 index 0000000..f6bf39e --- /dev/null +++ b/types/types.c @@ -0,0 +1,37 @@ +#include + +//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; +} \ No newline at end of file