User Tools

Site Tools


user:mtaft4:portfolio:howto:functions

Function Tutorial

Author: Matthew Taft

Objectives

  1. Learn the creation and use of functions in C
  2. Create functions to calculate the square root of a number, to generate random numbers, and to print the current date/time

Requirements

  • General knowledge of the C programming language
  • The ability to read the Unix Manual Pages
  • Knowledge of how to compile C programs using GCC

Background

Functions are an important part of programming in the C language as they help break your code up into logical sections. This makes your program easier to read and understand from the point of view of someone that may have no familiarity with your programming style or even your project.

It also serves as a great lesson for anyone looking to move into more Object Oriented Programming in languages like C++, Java, Ruby, etc. since everything in those languages can be in some way wrapped up into a class. Classes in this case being groupings of the functions of the class (or methods as some refer to them) and the data or parameters that the class handles. In essence because these languages aren't for the most part meant to be procedural, functions or methods are an essential part to programming in them.

Project

Square Root Function

Square Root, the mathematical operation for finding the number which when multiplied by itself or squared will yield the number that the operation was originally performed on. Now the C math.h library contains a handy little function for computing the square root called sqrt(), you can look at its specs by issuing “man 3 sqrt” from your lab46 prompt (Without the quotes of course) to see what it does. But we're going to be writing our own.

You might say that this is crazy because most of the people reading this have probably never had their teachers do the proof of how to do the square root function, but there is a way to do it without using that handy little shortcut function. Newton's Method, a mathematical algorithm developed by Sir Issac Newton is a procedure for finding successively better approximations for the roots (zeros) of real-valued functions. Now the long explanation involves a slight understanding of calculus but the short version is that if you put the number you want to find the square root of into this function:

Y = X - ((X2 - N) / 2X)

Where X is some initial guess and thereafter the results of each iteration of the algorithm, and N is the number you wish to find the square root of, eventually the values of each iteration will converge to a better and better approximation of the zero of the function. This will be the square root of that number N to a level of precision that you decide on in the form of how many iterations you go through.

Random Number Generation

Random Number Generators are an invaluable tool to many computer applications. Many cryptography programs use them to ensure that data is sufficiently protected by introducing an element of randomness to their encryption algorithms, making them that much harder to discern the pattern from and thereby break the encryption. Gaming programs use them for everything from simulating die rolls and card draws, to even certain random chances associated with computer games such as whether or not one entity will hit another one with an attack or whether some desired condition will be met.

Whatever the case, generating truly random numbers in a computer is quite difficult. A computer doesn't have a concept of “randomness”, and therefore what it can generate is really pseudorandom numbers. This can be accomplished using the srand() and rand() functions available in the stdlib.h library. srand() being the function to seed the generator that rand() calls. The seed value is the value that's going to be put into the mathematical operations in order to generate the random number. The problem comes if the seed value used in srand() is the same between two times that rand() is called. In this case rand() will end up outputting the same number. To help mitigate this the general wisdom is to seed srand with the value of time(NULL) from the time.h library. This way unless the routine is run twice in the same second, the numbers will always be different.

There are much better ways as part of the reading in the References section will show but for now this is the easiest way to get a grasp of random number generation.

Display Time/Date

Finally the last function that needs to be worked out is displaying time and date in a string format. In the time.h library there is a struct defined which has the capacity for storing hours, minutes, seconds, the day of the week, the current day of the year (0-365) and whether or not daylight savings time is in effect. Then there's the time() function which gives the current time in the number of seconds since January 1, 1970 at 12:00am.

Instructions and Guidelines

  1. Create a properly written program (Or series of programs) that can do the following.
    1. Calculate the square root of a number greater than 0 input by the user.
    2. Generate a pseudorandom number and display it.
    3. Display the current time and date.
  2. The Square Root function must not use the sqrt function found in math.h.
  3. The Time and Date program must output the time in a string that contains at least the month, day, year, and the current time in either 12 or 24 hour format.

References

Example Code

functions.c
#include <stdio.h>// used by all 3
#include <math.h>   // Used by square root only function used from it is pow() in square root
//and doesn't really need to be here
#include <stdlib.h> // used by Random numbers
#include <time.h>   // used by time
 
int main() {
	menu();
}
 
int menu() {
	int select;
	double num;
	char flag;
	printf("1: Square Root\n");
	printf("2: Random Numbers\n");
	printf("3: Display Time/Date\n");
	printf("4: Quit\n");
	printf("What function would you like to use?: ");
	scanf("%d", &select);
	switch (select) {
		case 1:
			printf("Enter a number greater than 0: ");
			scanf("%lf", &num);
			sqroot(num);
			break;
		case 2:
			randn();
			break;
		case 3:
			distime();
			break;
//any additional menu entries can be placed here and their numbers changed accordingly
//conforming to the format already specified here.
		case 4:
			return(0);
		default:
			printf("Invalid Selection. Try again?(y/n): ");
			scanf("%c", &flag);
			if (flag == 'y')	
				menu();
			else
				return(0);
//Test here to keep from infinitely looping when an input of the wrong type is used
//on the menu.
	}
}
 
int sqroot(double num) {
	double lastNum = 0;
	double errorMargin = 0.000001, test = 1;
//errorMargin: The precision to which the approximation of the square root
//is to be held to
	int i = 0;
	while (num <= 0) {
		printf("Please enter a number greater than 0.\n");
		printf("Enter: ");
		scanf("%lf", &num);
	}
	lastNum = num;
	while ((test * 2) < num) {
		test += test;
//using the 2^n closest to the test number as the initial guess for Newton's method
	}
	while ((lastNum-test) > errorMargin) {
		lastNum = test;
		test = (test - ((pow(test, 2) - num)/(2 * test)));
//Apply Newton's method until the difference between the previous approximation
//and the current one is less than or equal to the errorMargin
	}
	printf("The square root of %f is: %f\n", num, test);
	menu();
}
 
int randn() {
	int num;
	srand(time(NULL)); //Seed rand() with the current epoch time
//better seeding strategies can be used here to make the number more random.
	num = rand();      
//Should be a perfectly random number so long as it is not run twice in the same second.
	printf("Your random number is: %d\n", num);
	menu();
//To make this number random between 1 and some max value for say a dice roller,
//use the modulus operator (%) on the num variable for the max number you want and 
//then add 1 to the number to make it 1-max rather than 0-(max-1)
}
 
int distime() {
	time_t now;
	time(&now);
	printf("%s", ctime(&now));
//give ctime the struct filled by time(&now) to output the time and date 
//in a nicely formatted string
	menu();
}
 
//Place the definitions of any additional functions here.
//should include their name, return type and all other things needed
//to run them.
user/mtaft4/portfolio/howto/functions.txt · Last modified: 2011/05/17 19:51 by mtaft4