====Welcome====
====Reason for independent study instead of traditional lecture====
It is my firm belief that success correlates with strong internal motivation. What does that mean in this instance? My reason in opting for this independent study was to see if I'm capable of grasping these fundamental concepts with my own devices. I've been extremely pleased with the results.
====Scope of experience====
Over the last three months, I've explored various concepts of C programming. In my studies I explored syntactical structures, various logical operations, and principals that make up a C program. The following projects demonstrate what I've explored.
====Fun and general projects====
I've developed two projects that solve simplex problems in a very fun way. The first is a drinking game called "Power Hour" that works with loop incrementing that adds up to one hour. The loop wait 60 seconds using the sleep function via time.h:
#include
#include
int main()
{
printf("Begin power hour!\n\a");
int minute;
for(minute = 0; minute <= 60; ++minute)
{
printf("Minute Number: %d\n",minute);
sleep(60);
printf("Drink!\n\a");
}
printf("Congratulations, you've survived power hour!");
return 0;
}
The second fun project involves using a raspberry pi's General Purpose I/O to connect to solid state relay switch that powers a coffee machine. I call it "Lair Brew." The program makes heavy use of a library that gives the Pi Arduinio like I/O functions:
/*
Lair_Brew ~ Caffeine ~
Version 0.2
*/
#include
#include
void loopback(void)
{
char ch;
ch = getchar();
while( ch != '\n' ) ch = getchar();
}
int main (void)
{
int pin = 7;
char ch;
int exit_flag = 0;
printf("welcome to Lair Brew\n");
if (wiringPiSetup() == -1) return(1);
pinMode(pin, OUTPUT);
printf("Brew on\n");
digitalWrite(pin, 1);
while( exit_flag == 0 ) {
printf("Wish to exit? (Y)\n");
scanf(" %c", &ch );
ch = toupper( ch );
if((ch == 'Y')){
printf("\nBrew Off\n");
digitalWrite(pin, 0);
delay(250);
printf("\nEnjoy Your Coffee, Sir!\n");
}
else {
printf("\nType (y) to exit.\n");
loopback();
}
if( ch == 'Y' ) exit_flag = 1;
}
return 0;
}
Playing with simple structs:
#include
#include
typedef struct {
int a;
int b;
int c;
char abc[];
}node;
int main()
{
node n;
n.a = 1;
n.b = 2;
n.c = 3;
strcpy(n.abc, "abc");
printf("Now I know my %s's, they are easy as %d, %d, %d\n", n.abc, n.a, n.b, n.c);
return 0;
}
====Projects assigned by Matt====
The following projects were assigned by Matt in chronological order.
====Data type project====
This project went over different data types and the storage capabilities of those types.
The following code demonstrates the storage range of a signed and unsigned char:
/*
* range.c - A program to display information for signed and unsigned data types
*
*
* Compile with: gcc -o range range.c -lm
* Execute with: ./range
*/
#include
#include
int main()
{
// Variables
unsigned long long int quantity = 0;
unsigned char uc = 0;
signed char sc = 0;
// Display information for unsigned char data type
printf("An unsigned char is %d bytes\n", sizeof(uc));
printf("The range of an unsigned char is %hhu to %hhu\n", uc, (uc-1));
quantity = (unsigned char)(uc-1) + 1; // What does this line do?
printf("An unsigned char can store %llu unique values\n\n", quantity);
// Display information for signed char data type
printf("A signed char is %d bytes\n", sizeof(sc));
quantity = (unsigned long long int)pow(2, (sizeof(sc)*8)); // What is happening?
printf("The range of a signed char is %hhd to %hhd\n", (sc-(quantity/2)), (sc+(quantity/2)-1));
printf("A signed char can store %llu unique values\n\n", quantity);
return(0);
}
====Cipher project====
The cipher project entails taking a string value that is either entered or within a file and shifting it to another value. the shift uses ascii as its base.
encipher.c
/*
* encipher.c - program that encodes a message according to a key
*
*
* Compile with: gcc -o encipher encipher.c
*
* Place key value in: key.txt
* Place message to encipher in: plain.txt
* Enciphered message placed in: cipher.txt
*
* Execute with: ./encipher KEYVAL
*
*/
#include
#include
#include
int main(int argc, char **argv)
{
printf("Greetings Agent\n");
FILE *in, *out;
int cipher;
int key;
in = fopen("plain.txt", "r");
out = fopen("enciphered.txt", "w");
if(argv[1] == NULL) //if program called without argument
{
printf("\nNo argument provided, execute with key argument.\nexample: ./encipher 1\n");
exit(1);
}
char *plain;
plain = (char*) malloc (sizeof(char) * 127); //memory allocate for ascii
int count = 0;
//when text file is empty
if(in == NULL)
{
printf("\nFile empty, enter some text to encipher\n");
fgets(plain, 127, stdin);
while(plain[count] != '\0') //loop stdin characters
{
count = count+1;
}
int cipher = atoi(argv[1]); //ascii to integer; cipher key
count = 0; //begining
while(plain[count] != '\0') //loop until end of characters
{
key = 1;
if(plain[count] >= 65 && plain[count] <= 90) //upper case letters
{
key = plain[count] + cipher;
while(key > 90)
{
key = key - 26; //cipher shift
}
}
if(plain[count] >= 97 && plain[count] <= 122) //lower case letters
{
key = plain[count] + cipher;
while(key > 122)
{
key = key - 26; //cipher shift
}
}
if(key == 1)
{
key = 32;
}
fprintf(out, "%c", key);
count = count+1;
}
printf("\nEnciphered text is loated in enciphered.txt\n");
}
else //if file is present
{
fgets(plain, 127, in); //get file
printf("\nText before cipherication: ");
while(plain[count] != '\0') //loop to print file
{
printf("%c", plain[count]);
count = count+1;
}
int cipher = atoi(argv[1]); //get cipher key value from initial argument
count = 0; //begining
printf("\nCiphered text output: ");
while(plain[count] != '\0') //loop
{
key = 1;
if(plain[count] >= 65 && plain[count] <= 90) //uppercase characters
{
key = plain[count] + cipher;
while(key > 90)
{
key = key - 26; //cipher shift
}
}
if(plain[count] >= 97 && plain[count] <= 122) //lowercase characters
{
key = plain[count] + cipher;
while(key > 122)
{
key = key - 26; //cipher shift
}
}
if(key == 1)
{
key = 32;
}
printf("%c", key);
fprintf(out, "%c", key); //write to file
count = count+1;
}
printf("\nEnciphered text is located in enciphered.txt\n\n");
fclose(in);
fclose(out);
}
return 0;
}
decipher.c
/*
* decipher.c - program that encodes a message according to a key
*
*
* Compile with: gcc -o encipher encipher.c
*
* Place key value in: key.txt
* Place message to encipher in: plain.txt
* Enciphered message placed in: cipher.txt
*
* Execute with: ./decipher KEYVAL
*
*/
#include
#include
#include
int main(int argc, char **argv)
{
FILE *in, *out;
int key;
in = fopen("enciphered.txt", "r"); //read enciphered text file
out = fopen("plain.txt", "w"); //write deciphered text file
if(argv[1] == NULL) //if program called without arguments
{
printf("Execute with key argument.\nExample: ./decipher 1\n");
exit(1);
}
char *enciphered;
enciphered = (char*)malloc(sizeof(char) * 127); //memory allocate for ascii
int count = 0;
fgets(enciphered, 127, in); //get characters to decipher from enciphered.txt
printf("\nEnciphered text being deciphered: "); //display text before decipher
while(enciphered[count] != '\0')
{
printf("%c", enciphered[count]);
count = count+1;
}
int cipher = atoi(argv[1]); //argument from ascii to integer
count = 0;
printf("\nDeciphered text: ");
while(enciphered[count] != '\0') //while loop deciphers text
{
key = 1;
if(enciphered[count] >= 65 && enciphered[count] <= 90) //for upper case letters
{
key = enciphered[count] - cipher;
while(key < 65)
{
key = key + 26; //cipher shift
}
}
if(enciphered[count] >= 97 && enciphered[count] <= 122) //for lower case letters
{
key = enciphered[count] - cipher;
while(key < 97)
{
key = key + 26; //cipher shift
}
}
if(key == 1)
{
key = 32;
}
printf("%c", key);
fprintf(out, "%c", key); //print to file
count = count+1;
}
printf("\nDeciphered text written to plain.txt\n\n");
fclose(in); //
fclose(out); //close files
return (0);
}
====Array calculator project====
Bignum is an array based calculator program. The the two values are stored as character strings and compared against an integer length array. Each aggregate function is placed within a header file and called in an if/else if loop that's nested in a while loop. The struct really serves no purpose and was an experiment at the end.
bignum.c
#include
#include
#include
#include "add.h" //
#include "multiply.h" //
#include "sub.h" //
#include "divide.h" //each aggregate function placed in header file
struct {
char *first; //
char *second; //
int length; //
int count; //
int div; //experimental struct for datatypes (not necessary for logic)
}n;
int main()
{
int select=1;
printf("Welcome to BigNum!\n");
printf("select a length for your array size: ");
scanf("%u", &n.length); //
n.length = n.length-1; //get length
n.first = (char*)malloc(sizeof(char)*n.length); //first number size of length
printf("\nFirst number: ");
fgetc(stdin);
for(n.count = n.length; n.count >= 0; -- n.count) //get first number, compare it to length
{
n.first[n.count] = fgetc(stdin);
n.first[n.count] = n.first[n.count] - 48;
}
n.second = (char*)malloc(sizeof(char)*n.length); //second is the size of length
printf("\nSecond number: ");
fgetc(stdin);
for(n.count = n.length; n.count >= 0; -- n.count) //get second number, compare it to length
{
n.second[n.count] = fgetc(stdin);
n.second[n.count] = n.second[n.count] - 48;
}
while(select != 0 ){ //aggregate function selection menu
printf("_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_\n");
printf("|Please choose an Option(1-5): |\n");
printf("|Option 1: Add |\n");
printf("|Option 2: Subtract |\n");
printf("|Option 3: Multiply |\n");
printf("|Option 4: Divide |\n");
printf("|Option 5: Exit |\n");
printf("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-\n");
scanf("%d", &select);
if (select == 1){
printf("\nYou selected addition.\nThe answer is: ");
n.first = add(n.first, n.second, n.length);
for (n.length; n.length>=0; --n.length)
{
printf("%hhu", n.first[n.length]);
}
printf("\n");
break;}
else if (select == 2){
printf("\nYou selected subtraction.\nThe answer is: ");
n.first = sub(n.first, n.second, n.length);
for (n.length; n.length>=0; --n.length)
{
printf("%hhu", n.first[n.length]);
}
printf("\n");
break;}
else if (select == 3){
printf("\nYou selected multiplication.\nThe answer is: ");
multiply(n.first, n.second, n.length);
for (n.length; n.length>=0; --n.length)
{
printf("%hhu", n.first[n.length]);
}
printf("\n");
break;}
else if (select == 4){
printf("\nYou selected division.\nThe answer is: ");
divide(n.first, n.second, n.length, &n.div);
printf("%hhu", n.div);
printf("\n");
break;}
else if (select == 5){
printf("\nYou selected to exit.\nThe answer is: Tom's mom"); //inside joke
break;}
else{
printf("Incorrect in.\n"); //account for undesired input
}
}
printf("\nGoodbye!\n");
return(0);
}
add.h
#ifndef _ADDITION_H //
#define _ADDITION_H //define header file for use in main
char * add(char * first, char * second, int length) //function prototype
{
int count = 0;
char carry = 0;
for(count; count <= length; ++count) //loop until no more remaining numbers, end of length
{
int holder = (first[count] + second[count])+carry; // addition of numbers
if (holder > 9) //
{ //
first[count] = holder-10; //
carry=1; // account for carry
} //
else //
{ //
first[count] = holder; //
carry=0; // discount for carry
}
}
return first; //return to main for printing
}
#endif
sub.h
#ifndef _SUB_H
#define _SUB_H
char * sub(char *first, char *second, int length) //function prototype
{
char count = 0;
for(count; count <= length; ++count) //loop until no more remaining numbers, end of length
{
if (first[count] < second[count]) //if the second number is greater than the first
{
first[count+1] = first[count+1] - 1; //
first[count] = first[count] + 10; //carry for subtraction
}
first[count] = first[count] - second[count]; //simple subtraction
}
return first; //return to main for printing
}
#endif
multiply.h
#ifndef _MULTIPLY_H
#define _MULTIPLY_H
#include
#include "sub.h"
void multiply(char * first, char * second, int length) //function prototype
{
int count = 0;
int holder = 0;
char *third;
third = (char*)malloc(sizeof(char)*length); //memory allocate for length
for (count; count <= length; ++count) //loop until no more numbers
{
third[count] = first[count]; //copy first into third
}
for(count=0; count <= length; ++count) //account for leading zero
{
holder = (second[count]*pow(10, count)); //second (10^count)
for(holder; holder > 0; --holder) //loop until no more in holder
{
first = add(first, third, length); //add function
}
}
first = sub(first, third, length); //return to main for printing
}
#endif
divide.h
#ifndef _DIVIDE_H
#define _DIVIDE_H
void divide(char * first, char * second, int length, int *div) //function prototype
{
int count = 0;
char *fourth;
fourth = (char*)malloc(sizeof(char)*length); //allocate memory for fourth, size of length
for (count; count <= length; ++count) //loop until count matches length
{
fourth[count] = first[count]; //copy first into fourth
}
for(count=length; count>=0; --count) //count equals length, run each number until all the way through.
{
while(first[count] > 0)
{
++*div;
first = sub(first, second, length); //return to main for printing
}
}
}
#endif
====Thoughts and impressions====
Overall I've been pleased with what I've explored over this semester. I'm excited to further explore concepts of C and C++ in systems programming next semester.