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