/*
 ============================================================================
 Name        : PointerSandbox.c
 Author      : Matt Boutell, modified by David Mutchler and YOU
 Description : An exercise to help you to understand pointers and arrays.
 ============================================================================
 */

#include <stdio.h>	/* for printf, scanf */
#include <stdlib.h>	/* for malloc, free, EXIT_SUCCESS */

void incrementMe(int* x);
void swap(int x, int y);
void getArrayValues(float* ar, int size);
void printArrayValues(float* ar, int size);

int main(void) {

/* Q1. Run this first block of code once, then again in the debugger.
 * Then sketch the results of executing this block of code
 * (showing pointers as arrows, like we did in class).
 */
 	int num;
	int* pNum;
	pNum = &num;

	num = 4;

	printf("num = %d and is stored at %p\n", num, &num);
	printf("pNum = %p and is stored at %p\n", pNum, &pNum);

/* Q1a. In the above code, would it be any different if you wrote:
 *     int *pNum;
 * instead of:
 *     int* pNum;
 * How about:
 *     int * pNum;
 * Try them out!
 */

/* Q2. Predict the output of this commented block of code and write it down
 * (Hint, drawing some more pictures might help). Then uncomment and run to
 * confirm your guess.
 */

/*
	*pNum = 5;
	printf("num = %d and is stored at %p\n", num, &num);
	printf("pNum = %p and is stored at %p\n", pNum, &pNum);
	int num2 = 10;
	int* pNum2 = &num2;
	pNum2 = pNum;
	*pNum2 = 15;
	printf("num = %d and is stored at %p\n", num, &num);
	printf("pNum = %p and is stored at %p\n", pNum, &pNum);
	printf("num2 = %d\n", num2);
	printf("pNum2 = %p and is stored at %p\n", pNum2, &pNum2);
*/


/* Q3. Study how we use pointers here to modify a primitive argument passed
 * to a function. Look both at the call to incrementMe and at the code
 * for incrementMe (below main). You should see one use of & and both uses of *:
 * 	& means pass the address of anotherNum to the function. The * in the
 * parameter list, means that the function is expecting a pointer to be passed,
 * and the * in the function body means to change the contents of the variable
 * stored at that address.
 */
	int anotherNum = 20;
	printf("another num starts as %d, ", anotherNum);
	incrementMe(&anotherNum);
	printf("and ends as %d\n", anotherNum);

/* Q3 (continued). The following code calls the swap() function below.
 * Run it first to confirm that it doesn't actually swap the variables.
 * Then rewrite the function call and function body in the same way as the
 * incrementMe function, passing the references to the two
 * variables instead. Make use of the debugger to help you if needed.
 * If you get stuck or don't understand what to do, ask someone for help.
 */
 	int a = 10;
 	int b = 20;
 	printf("a=%d and b=%d\n", a, b);
 	swap(a, b);
 	printf("a=%d and b=%d\n", a, b);

/* Q4. By now, you should know why scanf() needs the addresses of the
  * variables it wants to change.
  * a. What would happen if scanf expected and received regular variables instead of addresses?
  * b. What would happen with the real scanf (which expects addresses) if we just
  * passed the variables themselves? (in other words, we forgot the &)
  * Devise and implement a short experiment in the space below
  * and run it to confirm your understanding.
  */



/* Q5. What's wrong with this code? Uncomment and run it.*/
/*	float* ptr = 0;
	printf("%4.2f\n", *ptr);
*/

/* Q6. An array in C is just a pointer. That means we can modify its contents
 * from within a function. Declare an array of 5 floats called ar.
 * Then write the function getArrayValues below to fill the array
 * with values entered by the user. Then write the function printArrayValues
 * below to print the contents.  Uncomment the calls below and test.
 *
 * Note that I have to pass the size to each function.
 * Note that I don't pass &ar to the function. Arrays are pointers, so passing ar
 * is passing a pointer already! However, what ar is pointing to cannot be changed.
 /*
 /*
 	getArrayValues(ar, 5);
 	printArrayValues(ar, 5);
 */

/* Q7. Dynamic arrays. Ask the user to enter the size of the array, and declare
 * an array of that size using malloc(). Then get that many inputs from the
 * user to fill the array, then print the contents of the array to
 * show that it works. Once you are done, what must you do to release the memory?
 */


/* Q8. (Optional) Say I declare an array of size 5,
 * then loop through the array from i = 0 to 100,
 * printing the contents at each location. Guess, then write some code to
 * check your hypothesis.
 */

 /* If you finish early, you can work on the homework. */
 	return EXIT_SUCCESS;;
}

/* An example of using pointers to change arguments */
void incrementMe(int* x) {
	++ (*x);
}

void swap(int x, int y) {
	// TODO: fix this function and its call to actually swap.
	int temp = x;
	x = y;
	y = temp;
}

void getArrayValues(float* ar, int size) {
	/* TODO: implement this, first using array subscripts like have done
	 * in class, then using pointer arithmetic
	 */
}

 void printArrayValues(float* ar, int size) {
	/* TODO: implement this, first using array subscripts like we have done
	 * in class, then comment that out and rewrite using pointer arithmetic.
	 */
 }