/* demo.c * A demo C program to explore machine level code including * a recursive function and a binary data structure on the heap. * See ./_readme_demo.txt for all the details. * Jim Mahoney | Oct 2020 | cs.bennington.college | MIT License */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned char *byte_pointer; typedef struct _node *node; // a "node" is a pointer to "struct _node" struct _node { // a "struct _node" contains a value and a node. char name; node right; node left; }; node new_node(char name, node left, node right){ // Create and return a new node. node result = malloc(sizeof(struct _node)); result->name = name; // same as (*result).value = value result->left = left; result->right = right; return result; } node make_tree(){ // Create and return the root of a binary tree that looks like this: // a // / \ // b c // / \ // d e node e = new_node('e', NULL, NULL); node d = new_node('d', NULL, NULL); node c = new_node('c', d, e); node b = new_node('b', NULL, NULL); node a = new_node('a', b, c); return a; } void print_tree(node root){ // print a tree as (name node node), e.g. (a (b) (c (e) (f)))" if (root){ printf(" (%c", root->name); print_tree(root->left); print_tree(root->right); printf(")"); } } void print_map_node(node n){ // display memory map - address and bytes - for a node // sizeof(struct node) is 3*8 bytes byte_pointer ptr = (byte_pointer) n; int i, j; printf(" node %c at %p : \n", n->name, n); for (i=0; i<3; i++){ printf(" %p : ", ptr); for (j=0; j<8; j++) printf("%.2x ", *(ptr+j)); printf(" "); for (j=0; j<8; j++) printf("%c ", *(ptr+j)); printf("\n"); ptr += 8; } } int fibbo(int n){ if (n < 2) return 1; return fibbo(n-1) + fibbo(n-2); } void swap(int *xp, int *yp){ int t0, t1; t0 = *xp; t1 = *yp; *xp = t1; *yp = t0; } int swap_and_stuff(int* a_ptr, int* b_ptr, int c, int d, int e, int f, int g){ int result; swap(a_ptr, b_ptr); result = c * (*a_ptr) + (*b_ptr) + (3 * d + 4 * e + 5 * f + 6 * g); printf(" address of g in swap_and_stuff is %p \n", &g); return result; } void part0(){ char input[100]; int n_inputs; char input_format[] = "%s"; printf("-- part 0 --\n"); printf(" inputs[] is at %p \n", (void*) input); printf(" What is your favorite color? "); if (0){ n_inputs = scanf(input_format, input); if (n_inputs == 1){ printf(" You said '%s'. \n", input); } else { printf(" Oops: scanf error \n"); } } else { printf(" ... never mind. ;) \n"); } } void part1(){ int n1 = 12, n2 = 34, n3 = 5, n4; printf("-- part1 --\n"); printf(" before: n1 = %d, n2 = %d, n3 = %d, n4 = %d \n", n1, n2, n3, n4); n4 = swap_and_stuff(&n1, &n2, n3, 1+n1, 2+n2, 3+n3, 13); printf(" after: n1 = %d, n2 = %d, n3 = %d, n4 = %d \n", n1, n2, n3, n4); } void part2(){ int f5 = fibbo(5); printf("-- part2 --\n"); printf(" fibbo(5) is %d \n", f5); } void part3(){ printf("-- part3 --\n"); node tree = make_tree(); print_tree(tree); printf("\n"); print_map_node(tree); print_map_node(tree->left); print_map_node(tree->right); } // declared before "main" so we can call it from within main ... void part4(); int main(){ printf("It's another demo.c !!!\n"); part0(); part1(); part2(); part3(); part4(); printf("(Are we having fun yet?)\n"); return 0; } // ... implemented after "main" so we can refer to main's location. void part4(){ printf("-- part4 --\n"); printf(" some function locations : \n"); printf(" main is at %p \n", (void*) main); printf(" part0 is at %p \n", (void*) part0); printf(" part1 is at %p \n", (void*) part1); printf(" part2 is at %p \n", (void*) part2); printf(" part3 is at %p \n", (void*) part3); printf(" part4 is at %p \n", (void*) part4); printf(" new_node is at %p \n", (void*) new_node); printf(" fibbo is at %p \n", (void*) fibbo); printf(" swap is at %p \n", (void*) swap); printf(" printf is at %p \n", (void*) printf); }