CCPROG1_functions_libraries
Functions in C
When you're writing a program, sometimes the problem requires a bunch of code with similar function. To avoid copy pasting forever, we have functions.
- Functions are a group of statements called to perform a task. They are also called subprograms.
- They're used to modularize our program by breaking it down into several modules that can be subdivided into different processes that the program will take.
- It also makes reading and tracing the code easier.
Syntax:
<return_type> <name_of_function>(<parameters>) {
return <value>;
}
- The
return_type
is the datatype of the value that the function will return. We "return" something when we want to get something out of (calling) the function. - The return type can only be one of the primitive data types (
int
,float
,double
,char
,long
, orvoid
) name_of_function
is the identifier name. It should not be a keyword, reserved word, or any identifier name that has been used for any variables, etc.- The
parameters
and variables are only within the function's scope. This means they cannot be accessed outside the function.- If a variable is declared inside a function it can only be accessed and declared within that function.
int function(int param1, int param2)
int noParameters()
double oneParameter(char oneParam)
When you define a function yourself, that is a user-defined function.
- concept of divide-and-conquer strategy. Each problem is decomposed into smaller problems until it's trivial.
- Reduces complexity: Using functions hides some implementation details so the programmer can view the task at a high level. It reduces the complexity of a problem by breaking it into smaller problems.
- Avoid duplicate code: Redundant code can be placed in function and then called or reused multiple times. Modifications will be easier because you will need to modify the code from only one location. Moreover, generic code placed in separate functions promotes code reuse. Code put into a function can be reused more easily than the same code embedded in a large subprogram.
- Improve performance: Having code in one place means optimizing the code benefits all the functions that use that subprogram, whether they use it directly or indirectly.
- Makes code readable: Putting code into a well-named function is one of the best ways to document and describe its purpose.
- Isolate complex operations: Complex operations are prone to errors. Finding and debugging errors is easier if they are isolated in a routine.
Return statement and Void
The return statement is a statement signifying what the function will return. In the syntax: return <value>;
, the "value" being returned needs to have the same datatype as the return_type
.
When something is the void
datatype, that means the function does not return a value. This is commonly used when you have a function that's just full of print statements OR it uses pointers to do operations on variables.
void sayHello() {
printf("Hello!\n");
printf("Hello!\n");
printf("Hello!\n");
printf("Hello!\n");
printf("Hello!\n");
printf("Hello!\n");
}
int main() {
sayHello();
return 0;
}
main()
is also a function. It signifies where the program starts. The reason why it has a return_type
of int
is because you have return 0
at the end. The return 0 closes the program.
- If your program runs, crashes, or hangs, the return value would be a different number.
- This is one sign that you should look back at your code and remove bugs.
You have called functions before. printf()
and scanf()
are functions that were defined/declared within the <stdio.h>
header file. Notice how the order of the parameters matter.
Calling Functions
When you declare a function, you can now call it by writing the identifier name of the function (including the parentheses).
- Function calls (except those with a return type of void) can be used as operands in arithmetic/logical expressions
- or can be used as parameters for function calls.
Basic function usage
#include <stdio.h>
int myFunc(int a, int b, char c) {
//do something here
}
int main() {
int a = function(4, 5, 'd');
// 4 would go to myFunc's variable a, 5 to variable b, and 'd' goes to c
}
In the example above, the int a
within main
is not the same as the int a
within myFunc
.
Another example
#include <stdio.h>
int dQuotient(double a, double b) {
return a/b; //return value is an expression
}
int main() {
double a, b;
a = 100 + dQuotient(50, 2);
printf("%lf\n", a);
printf("%lf\n", 100+dQuotient(50,2)); //should print the same value as a
printf("%lf\n", dQuotient(250, 25.0)); //function as a parameter
b = dQuotient(dQuotient(100,2), dQuotient(625,25)); //functions as parameters to a function
return 0;
}
Remember: void
functions cannot be placed as parameters to other functions or be operands in expressions. This is because void
means you're not returning anything, so there's nothing to print.
You can also call functions within a function.
#include <stdio.h>
void printMyOtherInt(int d){
printf("%d is my other int.\n", d);
}
int printMyIntAndGetTheSum(int c, int d){
printf("%d is my int\n", c);
printMyOtherInt(d); // function call within a function
return c + d;
}
int main(){
int firstOne, secondOne;
printf("Give me two numbers: ");
scanf("%d%d", &firstOne, &secondOne);
fflush(stdin);
printMyIntAndGetTheSum(firstOne, secondOne); // function call within a function
}
Note: If you're calling a function (ex. printMyOtherInt()
within another function printMyIntAndGetTheSum
), it (printMyOtherInt()
) has to exist or be defined before it's called. Just put it before the function you're gonna call it in. Else, your compiler or maybe the IDE will warn you with an error. Adam and Eve had to exist before you did so it's kind of the same thing. (I am not religious)
No you can't define functions within functions, that's not in standard C. (StackOverflow: Nested Functions)
Pre-defined Functions
When you pre-define a function, like so:
int abs(int n); //pre defined function, notice the immediate semi-colon
<data_type> <function_name>(<datatype of param1> <param_name>, <datatype of param2> <param_name>, <continue until you have all ur needed parameters>)
This means that this is a prototype. This prototype function has to be defined later on in your code.
return_type
: the datatype of the value that the function will returnfunction_name
: a valid identifier in C that is associated with the functionparameters
: zero or more input variables that are used to pass information to and/or from the function. Parameters are the values that the function needs in order to perform a particular task.
Standard Input/Output Library (stdio.h)
The functions scanf()
and printf()
are used for input and output, respectively. The f
part means formatted. These functions exist in the standard input/output library (.h) and are available whenever a C system is present.
printf()
function is used to print strings and the values of variables on the standard output device of the computer, which is usually your computer monitor's screen.
The function prototype of printf()
is: int printf( _const char *format, ..._ );
const char
denotes that it's a string. The three dots (...) mean that it is followed by a list of other parameters. This list is optional forprintf()
Additional Formatting Stuff
(you can skip most of this, i barely used them in CCPROG1, read if you want)
printf()
can have explicit formatting information included in the conversion specification. If it's not included, then defaults are used. For example, the format %f
alone will print 3.55
as 3.550000
if you don't specify that it will print 2 decimal places. (%.2f
)
Between the % symbol that starts the conversion specification and conversion character that ends it (see format specifier), there may appear (in order):
-
zero or more flag characters.
-
n optional positive integer that specifies the minimum field width of the converted argument. If the converted argument has fewer characters than the specified field width, then it will be padded with spaces on the left or right, depending on whether the converted argument is left- or right-justified. Numbers are right-justified, therefore the spaces are padded at the left. Similarly, spaces for characters and strings are padded at the leftmost end. If the converted argument has more characters than the specified field width, then the field width will be extended to whatever is required. By default, it is right-justified. If you want to make it left-justified, you put a negative sign beside the integer. (i can't simplify this i just got this from Canvas)
-
If the integer defining the field width begins with a zero and the argument being printed is right-justified in its field, then zeroes rather than spaces will be used for padding.
-
an optional precision, which is specified by a period followed by a nonnegative integer. For d and i conversions, it specifies the minimum number of digits to be printed.
-
for f conversions, the optional precision specifies the number of digits to the right of the decimal point
-
for an s conversion, the period followed by a nonnegative integer specifies the maximum number of characters to be printed from a string
-
a plus sign means that a nonnegative number that comes from a signed conversion is to have a + symbol appended. All negative numbers automatically start with a minus sign.
other
The Math Library (math.h)
You can start reading again, you will need this
#include <math.h>
Another library that's included when you have C installed in your system is <math.h>
. This header file contains common math functions but it will not solve all your problems. I will be copypasting notes below lol:
squareroot function (sqrt())
The sqrt()
function returns the result as a double-precision floating-point number (remember that double is a floating-point that can store a bigger range of values). It has one input parameter that also has a data type of double. These math functions can be assigned directly to a variable, used in a C expression, or printed directly on the screen. Storing the value in a float variable is possible as long as the value is not too large.
double x;
x = sqrt(25.0) // x is assigned the value 5.0, which is the square root of 25
// ------------------------
double x = 25.0;
float y;
y = sqrt(x)/2+10; //y is assigned the value of 12.5 (double is typecast implicitly to float)
// ------------------------
printf("%f", sqrt(25.0)); //5.000000 is printed on the screen (double is typecast implicitly to float)
Typecasting
Typecasting is the conversion from one datatype to another.
- an explicit type cast is done by enclosing a datatype in parenthesis and placing it before a value or variable.
- an implicit type cast is done when the compiler will convert compatible datatypes automatically without explicitly indicating it in the code
// explicit: y will be converted to int before being assigned to x
x = (int)y;
// implicit: 1.5 will be converted to 1 (int) then assigned to x
int x = 1.5;
power function (pow())
double pow(double x, double y);
The pow()
function computes the power of a number. It raises the value of the base to a particular exponent. It returns a double-precision floating-point. It has two input arguments, the x (the base) and y (the exponent), and both have the data type, double. It will return the value of xy.
double x;
x = pow(2.0, 4.0); // x is assigned the value 16.000000
float y;
y = pow(2.0, -4.0); // y is assigned the value 0.062500 (the double is typecast* implicitly to float)
float z;
z = pow(25.0, 0.5); // z is assigned the value 5.000000 (double is typecast* implicitly to float)
M_PI
, which is the pi or the circumference of a circle with a diameter of 1; and M_E
, which is the base of natural logarithms, e
.
The Standard Library (stdlib.h)
#include <stdlib.h>
absolute function (abs())
int abs(int x);
The abs()
function returns the absolute value of an integer. It has one input argument, which is an integer.
#include <stdlib.h>
x = abs(-5); // x is assigned value of 5
y = abs(5); // y is assigned value of 5
random function (rand())
int rand(void); The
rand()function returns a pseudo-random integer in the range of 0 to
RAND_MAX.
RAND_MAX` is a macro that specifies the largest integer value that will be returned by rand(). They are called pseudo-random numbers (pseudo means resembling or imitating) because the sequence of numbers generated will eventually repeat, but they are certainly random enough for most applications (Hanly, J. & Koffman, E., 2012).
- Returns an integer, has no input parameters.
#include <stdlib.h>
x = rand(); //x is assigned a random value from 0 to RAND_MAX
y = rand() 5 10 + 1; // y is assigned a random value from 1 to 10
seedrand function (srand())
void srand(unassigned int seed);
The srand()
function uses the input parameter as a seed to get a new sequence of pseudo-random numbers. Note that if you use rand()
without using srand()
it will always give the same sequence of numbers.
The srand()
function does not return any value. It has one integer parameter (unsigned means that it is nonnegative) that serves as the seed of the pseudo-random sequence. Note that we use the term pseudo-random because the C cannot actually generate an entirely random number. We usually use the time of the system as a basis for the seed. Note that usually only need to call this function once in a program before using rand()
.
#include <stdlib.h>
srand(7); // the system will use 7 as the seed to generate the sequence of pseudo-random numbers for rand()
srand(time(NULL)); // the system will use your computer's time as a basis as the seed to generate the sequence of pseudo-random numbers for rand()
Example
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* This program asks the user for two integers a lower bound and an upper bound for a range of numbers. It then generates a random number between the lower bound and the upper bound, inclusive */
int main () {
int nLower, nUpper;
int nRange, nRandom;
printf("Enter the lower and upper bound: ");
scanf("%d%d", &nLower, &nUpper);
nRange = nUpper - nLower + 1;
srand(time(NULL));
nRandom = rand() % nRange + nLower;
printf("A random number: %d\n", nRandom);
return 0;
}