Jim's
Tutorials

Spring 2013
course
navigation

C programming

Jim's evaluation & grade
Jim on March 8 - please read and acknowledge

Noah

I don't know. I'd like to be able to do object-oriented stuff with C. I'll keep pushing forward in K&R C and try to have something by then.
Today we covered pointers again and wrote a function to remove the trailing newline from fgets() input. I've worked on the wordcount code to try to make it take a filename as an argument and read it in as input, but that's still broken.
I've copied numdigits.c from KN King chapter 6. I googled some of the parts I didn't understand and have commented about them: /* Calculates the number of digits in an base-10 integer by dividing by 10 n times and returning n. */ #include <stdio.h> int main(void){ // void is the standard C99 way of saying that // main takes no arguments. () would be an unknown // number of them int digits = 0, n; printf("Enter a nonnegative integer: "); scanf("%d", &n); do { n /= 10; // I like these handy shortcuts. This is n = n/10 digits++; } while (n > 0); // Do loops are a little weird, the while goes // on the end for the special case where n = 0. // I would have just put an if statement in, but // that shows what I know, I guess. // I put a conditional here because screw digit(s) if (digits == 1){ printf("The number has 1 digit\n"); } else{ printf("The number has %d digits.\n", digits); } return 0; }
Jim: Here's another way to do that last if statement, using the ternary 'if' operator : printf("The number has %d digit%c\n", digits, (digits==1 ? '' : 's'))
also, here's the version of grades.c I did in class:
#include <stdio.h> // Checks how bad your grade is, grade inputs 4 to 1, anything else qualifies you for expulsion. int main(void){ int n; scanf("%d", &n); switch(n){ case (4): printf("Definitely an a"); break; case (3): printf("More like a b"); break; case (2): printf("I'd say it's a c"); break; case (1): printf("INCOMPETENCE"); break; default: printf("Immediate expulsion"); break; } return 0; }

Friday, April 5th

I copied the next switch-case example from KN C into the computer and fixed it so it takes a reasonable date format as input (although it's obviously a silly program and outputs an even worse date format than that):
/* legaldate.c */ #include <stdio.h> int main(void){ int month, day, year; printf("Enter date (yyyy-mm-dd): "); scanf("%d -%d -%d", &year, &month, &day); printf("Dated this %d", day); switch (day) { case 1: case 21: case 31: printf("st"); break; case 2: case 22: printf("nd"); break; case 3: case 23: printf("rd"); break; default: printf("th"); break; } printf(" day of "); switch (month) { case 1: printf("January"); break; case 2: printf("February"); break; case 3: printf("March"); break; case 4: printf("April"); break; case 5: printf("May"); break; case 6: printf("June"); break; case 7: printf("July"); break; case 8: printf("August"); break; case 9: printf("September"); break; case 10: printf("October"); break; case 11: printf("November"); break; case 12: printf("December"); break; } printf(", %d\n", year); return 0; }
Emacs was being a little weird and indenting the 'case's all on the same line as the switch, I fixed that manually.
Here's a thing for checking the exercises from the end of 5.1:
#include <stdio.h> int main(void){ int i = 2, j = 3, k; k = i * j == 6; printf("Exercise a: \n"); printf("i = %d, j = %d\n", i,j); printf("k = i * j == 6\n"); printf("Should output 1, because i * j = 6. Actual output:\n"); printf("%d\n", k); i = 5, j = 10, k = 1; printf("Exercise b: \n"); printf("i = %d, j = %d, k = %d\n", i,j,k); printf("k > i < j\n"); printf("Should output 1 (because k > i is 0, which is < 10.) Actual output:\n"); printf("%d\n", k > i < j); i = 3, j = 2, k = 1; printf("Exercise c: \n"); printf("i = %d, j = %d, k = %d\n", i,j,k); printf("i < j == j < k\n"); printf("Should output 1, because i < j = 0, j < k = 0, and 0 == 0 = 1.\n"); printf("Actual output:\n"); printf("%d\n", i < j == j < k); i = 3, j = 4, k = 5; printf("Exercise d: \n"); printf("i = %d, j = %d, k = %d\n", i,j,k); printf("i %% j + i < k\n"); printf("Should output 0, because 3 %% 4 = 3, 3 + 3 = 6, and 6 is > 5\n"); printf("Actual output: \n"); printf("%d\n", i % j + i < k); return 0; }
I've written a factorial program in c, I had to look at my python one to remember what the recursive definition is.
#include <stdio.h> int main(void){ int input, output; scanf("%d", &input); int factorial(input){ if (input == 1){ return 1; } else { return input * factorial(input - 1); } } output = factorial(input); printf("%d\n", output); return 0; }
Messed around with GMP a little bit, it looks useful for fun numerical functions like pi/phi/e approximation.
/* Learning how to use gmp * Variable initialisation has to happen within main() * The manual is pretty useless * There's little else out there * http://www.thinkdigit.com/forum/programming/82996-need-help-using-gmp-bignum-library.html had a great * example * this is even simpler * I still don't know how to do even bigger numbers, such as the sort project euler problems tend to generate. */ #include <stdio.h> #include <gmp.h> int main(){ mpz_t pie; mpz_init_set_ui(pie, 314159265); // initalise and set an unsigned int gmp_printf("%Zd\n", pie); return 0; }
More GMP funtimes:
#include <stdio.h> #include <gmp.h> int main(){ mpf_t pie; mpf_t sqrtpie; mpf_set_default_prec(1000); // set default precision to 1000 bits mpf_init(pie); mpf_init(sqrtpie); mpf_set_str(pie, "3.14159265358979323846264338327950288419716939937510582097494459230", 10); // set a signed int in base 10 to a str gmp_printf ("%.40Ff\n", pie); //mpf_out_str(NULL, 10, 40, pie); // give me 40 digits of a base 10 string of a number mpf_sqrt (sqrtpie, pie); gmp_printf ("%.40Ff\n", sqrtpie); // Turns out gmp_printf is way easier return 0; }

Mutual recursion re-done using a library

Yay, saved a line of code using three files! This makes more sense than declaring just one function empty to start-- let's
declare them all that way.

attempt at approximating e

/* I tried to approximate e. * Sam helped. */ #include <stdio.h> #include <stdlib.h> #include <gmp.h> typedef struct _bignumber_{ mpf_t value; }* bignumber; bignumber myadd(mpf_t a, mpf_t b){ // getting around the awkwardness of mpf_add bignumber output = malloc(sizeof(struct _bignumber_)); mpf_init(output->value); mpf_add (output->value, a, b); return output; } bignumber mypow(mpf_t base, mpf_t exponent){ bignumber output = malloc(sizeof(struct _bignumber_)); mpf_init(output->value); mpf_pow_ui(output->value, base, exponent); return output; } bignumber e(unsigned long int n){ return mypow(myadd(1,1/n), n); } int main(){ unsigned long int n = 1000; bignumber thing = e(n); gmp_printf ("%.40Ff\n", thing->value); // printf("%f\n",e(n)); return 0; }

May 5th

Attached my adventures in C writeup.
http://cs.marlboro.edu/ courses/ spring2013/jims_tutorials/ noah/ home
last modified Tuesday May 14 2013 4:06 pm EDT

attachments [paper clip]

     name last modified size
[DOC]adventuresinc.pdf May 5 2013 4:33 am 184kB [COD]mutualrecursion2.c Apr 19 2013 12:05 pm 254B [COD]mutualrecursionlib.c Apr 19 2013 12:06 pm 314B    mutualrecursionlib.h Apr 19 2013 12:06 pm 67B [COD]wc.c Mar 1 2013 1:14 pm 891B