C programming
Noah
- So far I've just copied the word count program from K&R C. I'm going to try to make it take files as input.
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.