0% found this document useful (0 votes)
14 views41 pages

C Programming: Arrays and Functions

This unit covers derived data types in C, focusing on arrays, strings, user-defined functions, recursion, and storage classes. It explains one-dimensional and two-dimensional arrays, their declaration, initialization, and operations such as searching and sorting. Additionally, it discusses handling strings, including reading and writing characters and strings, and the limitations of certain input functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views41 pages

C Programming: Arrays and Functions

This unit covers derived data types in C, focusing on arrays, strings, user-defined functions, recursion, and storage classes. It explains one-dimensional and two-dimensional arrays, their declaration, initialization, and operations such as searching and sorting. Additionally, it discusses handling strings, including reading and writing characters and strings, and the limitations of certain input functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

UNIT III

UNIT III
After studying this unit, you will be able to understand:
 Derived Data Types in C- Arrays
 Handling of Strings
 User-Defined functions
 Recursion
 Storage Classes

Arrays
An array is a group of related data items of same data type that share a
common name. For instance, we can define an array name salary to represent a set of
salaries of a group of employees. A particular value is indicated by writing a number
called index number or subscript in brackets after the array name. For example,
salary [10] represents the salary of the 10th employee. While the complete set of
values is referred to as an array, the individual values are called elements. Arrays can
be of any variable type.
The ability to use a single name to represent a collection of items and to refer to
an item by specifying the item number enables us to develop concise and efficient
programs. For example, a loop with the subscript as the control variable can be used to
read the entire array, perform calculations and, print out the results.

One-dimensional arrays
A list of items can be given one variable name using only one subscript and
such a variable is called a single-subscripted variable or a one-dimensional array.
The subscript can begin with number 0.
For example, if we want to represent a set of five numbers, say (35,40,20,57,19), by an
array variable number, then we may declare the variable number as follows
int number[5];
and the computer reserves five storage locations as shown below:

The values to the array elements can be assigned as follows:

1
UNIT III

number[0] = 35;
number[1] = 40;
number[2]=20;
number[3]=57; number[4] = 19;
This would cause the array number to store the values as shown below:

These elements may be used in programs just like any other C variable. For
example, the following are valid statements:
a = number[0] + 10;
number[4] = number[0] + number [2];
number[2] = x[5] + y[10];
value[6] = number[i] * 3;
The subscript of an array can be integer constants, integer variables like i, or
expressions that yield integers. C performs no bounds checking and, therefore, care
should be exercised to ensure that the array indices are within the declared limits.

Declaration of One Dimensional Arrays


Like any other variable, arrays must be declared before they are used. The general
form of array declaration is
datatype variable-name[size];
The type specifies the type of element that will be contained in the array, such
as int, float, or char and the size indicates the maximum number of elements that can
be stored inside the array.
For example,
 float height[50]; declares the height to be an array containing 50 real
elements. Any subscripts 0 to 49 are valid.
 Similarly, int group[10]; declares the group as an array to contain a
maximum of 10 integer constants.
 Remember, any reference to the arrays outside the declared limits would not
necessarily cause an error. Rather, it might result in unpredictable program

2
UNIT III

results.
 The C language treats character strings simply as arrays of characters.
 The size in a character string represents the maximum number of characters
that the string can hold.
 For instance, char name[10]; declares the name as a character array (string)
variable that can hold a maximum of 10 characters.
 Suppose we read the following string constant into the string variable name.
say "WELL DONE"
Each character of the string is treated as an element of the array name and is stored in
the memory as follows:
„W‟ „E‟ „L‟ „L‟ „ „ „D‟ „O‟ „N‟ „E‟ „\0‟

then the compiler sees a character string, it terminates it with an additional null
character. Thus, the element name[9] holds the null character '\0' at the end. When
declaring character arrays, we must always allow one extra element space for the null
terminator.
 Initialization of Arrays
We can initialize the elements of arrays in the same way as the ordinary
variables when they are declared. An array can be initialized at either of the following
stages:
 At Compile time
 At run time

Compile Time Initialization


The general form of initialization of arrays is:
static datatype array-name[size] = { list of values };
The values in the list are separated by commas. For example, the statement
static int number[3] = { 0,0,0 };
will declare the variable number as an array of size 3 and will assign zero to each
element. If the number of values in the list is less than the size specified, then only
that many elements will be initialized. The remaining elements will be set to zero
automatically. For instance,
static float total[5] = {0.0,15.75,-10};
will initialize the first three elements to 0.0,15.75, and -10.0 and the remaining two
elements to zero.
The word 'static' before type declaration declares the variable as a static variable.
The size may be omitted. In such cases, the compiler allocates enough space for all
initialized elements. For example, the statement

3
UNIT III

static int counter[ ] = {1,1,1,1};


will declare the counter array to contain four elements with initial values 1. This
approach works fine as long as we initialize every element in the array.
Character arrays may be initialized in a similar manner. Thus, the statement
static char name[ ] = {'J'.'o', 'h', 'n'}; declares the name to be an array of four
characters, initialized with the string "John".

Initialization of arrays in C suffers two drawbacks.


1. There is no convenient way to initialize only selected items.
2. There is no shortcut method for initializing a large number of array elements
Run time Initialization
An array can be explicitly initialized at run time. This approach is usually applied for
initializing large arrays.
Consider an array of size, say 100. All the 100 elements have to be explicitly
initialized. In such situations, it would be better to use a for loop to initialize the
elements. Consider the following segment of a C program:
for (i = 0;i < 100; i = i+1)
{
if i < 50
sum[i] = 0.0;
else
sum[i] = 1.0;
}
The first 50 elements of the array sum are initialized to zero while the remaining 50
elements are initialized to 1.0.

Searching and Sorting


Searching and Sorting are the two most frequent operations performed on arrays. Computer
scientists have devised several data structures and searching and sorting techniques that
facilitate rapid access to data stored in lists.
Sorting is the process of arranging elements in the list according to their values in ascending
order or descending order. A sorted list is called an ordered list. Sorted lists are especially
important in list searching because they facilitate rapid search operations. Many sorting
techniques are available. The three simple and most important among them are:
 Bubble Sort
 Selection Sort
 Insertion Sort
Other sorting techniques include Shell Sort, Merge Sort and Quick Sort.

4
UNIT III

Searching is the process of finding the location of the specified element in a list. The
specified element is often called search key. If the process of searching finds a match of the
search key with a list element value, the search is said to be successful; other wise it is
unsuccessful. The two most commonly used search techniques are :
 Sequential Search
 Binary Search

TWO-DIMENSIONAL ARRAYS
There will be situations where a table of values will have to be stored. Consider
the following data table, which shows the value of sales of three items by four
salesgirls:
Item1 item2 item3
Salesgirl 1 310 275 365
Salesgirl 2 210 190 325
Salesgirl 3 405 235 240
Salesgirl 4 260 300 380

We can think of this table as a matrix consisting of four rows and three columns.
In mathematics, we represent a particular value in a matrix by using two
subscripts such as vij. Here v denotes the entire matrix and vij refers to the value in
the i'th row and jth column. For example, in the above table v23 refers to the value 325.
C allows us to define such tables of items by using two-dimensional arrays. The
table discussed above can be defined in C as v[4][3]
Two-dimensional arrays are declared as follows:
datatype array-name [row_size][column_size];
C places each size in its own set of brackets.
. As with the single-dimensional arrays, each dimension of the two dimensional
array is indexed from zero to its maximum size minus one where the first index selects
the row and the second index selects the column within that row.

5
UNIT III

INITIALIZING TWO-DIMENSIONAL ARRAYS


Like the one-dimensional arrays, two-dimensional arrays may be initialized by
following their declaration with a list of initial values enclosed in braces. For example,
static int table[2][3] = {0,0,0,1,1,1};
initializes the elements of the first row to zero and the second row to one. The
initialization is done row by row. The above statement can be equivalently written as
static int table[2][3] = {{0,0,0}, {1,1,1}};
by surrounding the elements of each row by braces. We can also initialize a two-
dimensional array in the form of a matrix as shown below:
static int table[2][3] = {
{0,0,0},
{1,1,1}
};
Note the syntax of the above statements. Commas are required after each brace that
closes off a row, except in the case of the last row.
If the values are missing in an initializer, they are automatically set to zero. For
instance, the statement
static int table[2][3]={ {1,1},{2}};
will initialize the first two elements of the first row to one, the first element of
the second row to two and all other elements to zero.
C allows arrays of three or more dimensions. The exact limit is controlled by
the compiler.

6
UNIT III

HANDLING OF STRINGS
DECLARING AND INITIALIZING STRING VARIABLES
A string variable is any valid C variable name and is always declared as an
array. The general form of declaration of a string variable is
char string_name[ size ];
The size determines the number of characters in the string-name.
Some examples are:
char city[10];
char name[30];
When the compiler assigns a character string to a character array, it automatically
supplies a null character ('\0 ') at the end of the string. Therefore, the size should be
equal to the maximum number of characters in the string plus one.
Character arrays may be initialized when they are declared. C permits a character
array to be initialized in either of the following two forms:
static char city[9] = "NEW YORK";
static char city[9] = {'N’,’E’,’W’,’ ‘,’Y’,’O’,’R’,’K’'};
The reason that city had to be 9 elements long is that the string NEW YORK
contains 8 characters and one element space is provided for the null terminator. Note
that when we initialize a character array by listing its elements, we must supply
explicitly the null terminator.
C also permits us to initialize a character array without specifying the number of
elements. In such cases, the size of the array will be determined automatically, based
on the number of elements initialized. For example, the statement
static char string [] = {'G','O’,’O’,’D’,’\0’};
defines the array string as a five element array. Note that the word static may be
omitted when using ANSI compilers.
READING A CHARACTER
Reading a single character can be done by using the function getchar. The
syntax of getchar is as follows
Variablename = getchar();
variable_name is a valid C name that has been declared as char type. When this
statement is encountered, the computer waits until a key is pressed and then assigns
this character as a value to getchar function. Since getchar is used on the right-hand
side of an assignment statement, the character value of getchar is in turn assigned to
the variable name on the left. For example
char name;
name = getchar();

7
UNIT III

will assign the character 'H' to the variable name when we press the key H on the
keyboard. Since getchar is a function, it requires a set of parentheses as shown.
The getchar function may be called successively to read the characters contained in
a line of text.

WRITING A CHARACTER
Like getchar, there is an analogous function putchar for writing characters one
at a time to the terminal. It takes the following form
putchar(variable_name);
where variable-name is a type char variable containing a character. This statement
displays the character contained in the variable-name at the terminal. For example, the
statements
answer = ‘Y';
putchar(answer);
will display the character Y on the screen. The statement putchar(„\n'); would cause
the cursor on the screen to move to the beginning of the next line.

STRING HANDLING:
A string is an array of characters. Any group of characters (except double
quote sign) defined between double quotation marks is a constant string.
Example: "Man is obviously made to think."
If we want to include a double quote in the string, then we may use it with a back
slash as shown below.
"\” Man is obviously made to think,\” " said Pascal."
For example, printf ("\” Well Done !\" ");
will output the string “Well Done!”
while the statement printf(" Well Done !"); will output the string
Well Done !
Character strings are often used to build meaningful and readable programs. The
common operations performed on character strings are:
• Reading and Writing strings.
• Combining strings together.
• Copying one string to another.
• Comparing strings for equality.
• Extracting a portion of a string.

8
UNIT III

READING STRINGS FROM TERMINAL (Reading Words)


The input function scanf can be used with %s format specification to read in a string
of characters. Example:
char address[15];
scanf("%s", address);
The problem with the scanf function is that it terminates its input on the first
white space it finds. (A white space includes blanks, tabs, carriage returns, form feeds,
and new lines.) Therefore, if the following line of text is (typed in at the terminal),
NEW YORK, then only the string "NEW" will be read into the array address, since
the blank space after the word 'NEW' will terminate the string.
Note that, the ampersand (&) is not required before the variable name. The scanf
function automatically terminates the string that is read with a null character and
therefore the character array should be large enough to hold the input string plus the
null character.
If we want to read the entire line "NEW YORK", then we may use two character
arrays of appropriate sizes. That is,
scanf(u%s %s", adr1, adr2);
with the line of text
NEW YORK
will assign the string "NEW" to adr1 and "YORK" to adr2.

READING A LINE OF TEXT


In many text processing applications, we need to read in an entire line of text from
the terminal. It is not possible to use scanf function to read a line containing more than
one word. This is because the scanf terminates reading as soon as a space is
encountered in input.
In such situation we can use getchar function repeatedly to read successive single
characters from the input and place them into a character array. Thus, an entire line of
text can be read and stored in an array. The reading is terminated when the newline
character ('\n') is entered and the null character is then inserted at the end of the string.
C does not provide operators that work on strings directly. For instance, we cannot
assign one string to another directly. For example, the assignment statements (in
which string, string1, string2 are of string data types)
string = "ABC";
string1 = string2;
are not valid. If we really want to copy the characters in string2 into string1, we may
do so on a character-by-character basis.

9
UNIT III

WRITING STRINGS TO SCREEN


The format %s in a printf function can be used to display an array of characters
that is terminated by the null character. For example, the statement printf(''%s",
name); can be used to display the entire contents of the array name.
We can also specify the precision with which the array is displayed. For instance, the
specification %10.4 indicates that the first four characters are to be printed in a field
width of 10 columns.
However, if we include the minus sign in the specification (e.g., % -10.4s), the string
will be printed left justified. Some of the features of %s specification are,
1. When the field width is less than the length of the string, the entire string is
printed.
2. The integer value on the right side of the decimal point specifies the number of
characters to be printed.
3. When the number of characters to be printed is specified as zero, nothing is
printed.
4. The minus sign in the specification causes the string to be printed left-justified.

ARITHMETIC OPERATIONS ON CHARACTERS


C allows us to manipulate characters the same way we do with numbers.
Whenever a character constant or character variable is used in an expression, it is
automatically converted into an integer value by the system. The integer value
depends on the local character set of the system. To write a character in its integer
representation, we may write it as an integer. For example, if the machine uses the
ASCII representation, then,
x = 'a';
printf("%d\n”,x); will display the number 97 on the screen.
It is also possible to perform arithmetic operations on the character constants
and variables. For example, x = 'z'-1; is a valid statement. In ASCII, the value of 'z' is
122 and therefore, the statement will assign the value 121 to the variable x.
We may also use character constants in relational expressions. For example, the
expression ch >= 'A' && ch <= 'Z' would test whether the character contained in the
variable ch is an upper-case letter. We can convert a character digit to its equivalent
integer value using the following relationship:
x = character - '0';
where x is defined as an integer variable and character contains the character
digit. For example, let us assume that the character contains the digit '7',
Then, x = ASCII value of „7' - ASCII value of '0' = 55-48 = 7
The C library supports a function that converts a string of digits into their

10
UNIT III

integer values. The function takes the form x = atoi(string) x is an integer variable
and string is a character array containing a string of digits. Consider the following
segment of a program:
number = "2011";
year = atoi(number);
number is a string variable which is assigned the string constant "2011". The
function atoi converts the siring "2011" (contained in number) to its numeric
equivalent 2011 and assigns it to the integer variable year.

PUTTING STRINGS TOGETHER


Just as we cannot assign one string to another directly, we cannot join two
strings together by the simple arithmetic addition. That is, the statements such as
string3 = string1 + string2;
string2 = string1 + "hello";
are not valid. The characters from string1 and string2 should be copied into the string3
one after the other. The size of the array string3 should be large enough to hold the
total characters. The process of combining two strings together is called
concatenation.

COMPARISON OF TWO STRINGS


Once again, C does not permit the comparison of two strings directly. That is,
the statements such as if(name1 == name2) and if (name == "ABC")
are not permitted. It is therefore necessary to compare the two strings to be tested,
character by character. The comparison is done until there is a mismatch or one of the
strings terminates into a null character, whichever occurs first. The following segment
of a program illustrate this.
i=0;
while(str1[i] == str2[i] && str1[i] !='\0' &&str2[i] !='\0')
{
i = i+1;
if (str1[i] == '\0' && str2[i] == '\0‟)
printf("strings are equal \n"):
else
printf("strings are not equal \n"),
}

11
UNIT III

STRING-HANDLING FUNCTIONS
Fortunately, the C library supports a large number of string-handling functions
that can be used to carry out many of the string manipulations discussed so far.
Following are the most commonly used string-handling functions.
Function Action
strcat() concatenates two strings
strcpy() copies one string over another
strlen() finds the length of a string
strcmp() compares two strings
strstr() locate a sub string in a string
strrev() reverse the specified string

 strcat() Function
The strcat function joins two strings together. It takes the following form:
strcat(string 1, string2);
stringl and string2 are character arrays. When the function strcat is executed, string2 is
appended to stringl. It does so by removing the null character at the end of stringl and
placing string2 from there. The string at string2 remains unchanged.
For example, consider the following three strings:

12
UNIT III

 strcmp() Function
The strcmp function compares two strings identified by the arguments and has
a value 0 if they are equal. If they are not, it has the numeric difference between the
first non matching characters in the strings. It takes the form:
strcmp(string1, string2);
stringl and string2 may be string Variables or string constants.

Examples are:
strcmp(name1, name2); strcmp(name1, "John"); strcmp("Rom", "Ram");

We have to determine whether the strings are equal; if not, which is


alphabetically above. The value of the mismatch is rarely important. For example, the
statement strcmp("their", "there");
will return a value of -9 which is the numeric difference between ASCII "i" and
ASCII "r". That is, "i" minus "r" in ASCII code is -9. If the value is negative, string1
is alphabetically above string2.

13
UNIT III

 strcpy() Function
The strcpy function works almost like a string-assignment operator.
It takes the form
strcpy(string1, string2);
and assigns the contents of string2 to stringl. string2 may be a character array variable
or a string constant.
For example, the statement
strcpy(clty, "DELHI");
will assign the string "DELHI" to the string variable city. Similarly, the statement
strcpy(city1, city2);
will assign the contents of the string variable city2 to the string variable cityl.
The size of the array cityl should be large enough to receive the contents of city2
 strlen() Function
This function counts and returns the number of characters in a string. It takes the form
n = strlen(string);
Where n is an integer variable which receives the value of the length of the string. The
argument may be a string constant. The counting ends at the first null character.
Example: int l;
l=strlen(“New York”); the value of l is 8.
 strstr() function
This function has two parameters, that can be used to locate a substring in a
string. This takes the form:
strstr(s1, s2);
strstr(s1,”ABC”);
The function strstr searches the string s1 to see whether the string s2 is contained in
s1. If yes, the function returns the position of the first occurrence of the sub string.
Otherwise, it returns a NULL pointer.
Example
if(strstr(s1,s2)==NULL)
printf(“substring is not found”);
else
printf(“s2 is a substring of s1”);

14
UNIT III

 strrev() Function
This function is used to reverse the entire string.
It takes the form strrev(string);:
Eg:
void main()
{
printf(“%s”, strrev(“Canara”));
}
Will returns the value aranaC.
Warning:
1. When allocating space for a string during declaration, remember to count the
terminating null character.
2. When creating an array to hold a copy of a string variable of unknown size, we
can computer the size required using the expression strlen(stringname)+1.
3. When copying or concatenating one string to another, we must ensure that the
target string has enough space to hold the incoming characters. No error
message will be available even if this condition is not satisfied. The copying
may overwrite the memory and the program may fail in an unpredictable way.

CHARACTER HANDLING FUNCTIONS


 A function is a single comprehensive unit (self-contained block) containing a
block of code that performs a specific task.
 This means function performs the same task when called which avoids the need of
rewriting the same code again and again.
 As we know that characters are the fundamental building blocks of every program.
 A character constant is represented as a character in a single quote. The value of
character constant is an integer.
 For example, a is represented as 'a' which is actually the integer value equal to 97
in ASCII.
 Similarly, '\n' represents the integer value of newline equal to 10 in ASCII.
 C provides standard character handling library <ctype.h>.
 We should include character handling library i.e. <ctype.h> for using different
character handling function.
 This header include various useful functions for performing tests and
manipulations of character data in C programming.
 The function in <ctype.h> recieves an unsigned char represented as int or EOF as
argument.
 In C programming, character is a one byte integer.

15
UNIT III

C Character handling library <ctype.h> functions


 islower( ch );
o It returns a true if ch is a lowercase letter and 0 otherwise.
 isupper(ch );
o It returns a true value if ch is a uppercase and 0 otherwise.
 isblank(ch );
o This function checks whether ch is a blank character or not.
 isdigit(ch);
o This function checks whether ch is a digit or not.
 isnumeric(ch);
o Returns a Boolean value indicating whether an expression can be evaluated
as a number i.e checks whether ch is a number or not.
 isalpha(ch):
o This function checks if the argument passed to it is in the alphabet. If the
argument is not in the alphabet, then the function will return a zero, else it
returns a non-zero value.
 toascii(ch);
o Converts the value of ch to the 7-bit ASCII range and returns the result.
 tolower(ch);
o This function converts uppercase letter into lowercase letter.
 toupper(ch);
o This function converts lowercase letter into uppercase letter.

16
UNIT III

USER-DEFINED FUNCTIONS
One of the strengths of C language is that C functions are easy to define and
use. C functions can be classified into two categories, namely, library functions and
user-defined functions. main is an example of user-defined functions where as printf
and scanf belong to the category of library functions. We are also having other library
functions such as sqrt, cos, strcat, etc. The main distinction between these two
categories is that library functions are not required to be written by us whereas a
user-defined function has to be developed by the user at the time of writing a program.
However, a user-defined function can later become a part of the C program library.

NEED FOR USER-DEFINED FUNCTIONS


Every program must have a main() function to indicate where the program has
to begin its execution. While it is possible to code any program utilizing only main
function, it leads to a number of problems. The program may become too large and
complex and as a result the task of debugging, testing, and maintaining becomes
difficult. If a program is divided into functional parts, then each part may be
independently coded and later combined into a single unit. These subprograms called
'functions' are much easier to understand, debug, and test.
There are times when some type of operation or calculation is repeated at many
points throughout a program. For instance, we might use the factorial of a number at
several points in the program. In such situations, we may repeat the program
statements wherever they are needed. Another approach is to design a function that
can be called and used whenever required. This saves both time and space.
This sub-sectioning approach clearly results in a number of advantages.
1. It facilitates top-down modular programming as shown below.

In Top-down modular programming, it divides main function into many sub


functions. In this programming style, the high level logic of the overall problem is
solved first while the details of each lower-level function are addressed later.
2. The length of a source program can be reduced by using functions at
appropriate places.
3. It is easy to locate and isolate a faulty function for further debugging.
4. A function may be used by many other programs. This means that a C
programmer can build their program on what others have already done, instead
of starting from the beginning.

17
UNIT III

MULTI-FUNCTION PROGRAM
A function is a self-contained block of code that performs a particular task.
Once a function has been designed and packed, it can be used to take some data from
the main program and return a value. The inner details of operation are invisible to the
rest of the program. Every C program can be designed using a collection of functions.
Consider a set of statements as shown below:
printline( )
{
int i;
for (i=1; i<=40; i ++)
printf("-");
printf("\n");
}

The above set of statements defines a function called printline, which could print a
line of 40-character length. This function can be used in a program as follows:
main( )
{
printline();
printf ("This illustrats the use of C functions\n");
printline();
}
The above program contains two user-defined functions:- main() and printline().
As we know, the program execution always begins with the main function. During
execution of the main, the first statement encountered is printline(); which indicates
that the function printline is to be executed. At this point, the program control is
transferred to the function printline. After executing the printline function which
outputs a line of 40 character length, the control is transferred back to the main. Now,
the execution continues at the point where the function call was executed. After
executing the printf statement, the control is again transferred to the printline function
for printing the line once more.
The main function calls the user-defined printline function two times and the library
function printf once. We may notice that the printline function itself calls the library
function printf repeatedly.
Any function can call any other function. In fact, it can call itself. A 'called function'
can also call another function. A function can be called more than once. In fact, this is
one of the main features of using functions. The following figure illustrates the flow
of control in a multi-function program.

18
UNIT III

Except the starting point, there are no other predetermined relationships, rules of
precedence, or hierarchies among the functions that make up a complete program. The
functions can be placed in any order. A called function can be placed either before or
after the calling function. However, it is the usual practice to put all the called
functions at the end.

ELEMENTS OF USER DEFINED FUNCTIONS


 Both function names and variable names are considered identifiers and
therefore they must adhere to the rules for identifiers.
 Like variables, functions have types associated with them.
 Like variables, function names and their types must be declared and defined
before they are used in a program.

In order to make use of a user defined function, we need to establish three elements
that are related to functions.
 Function Definition
 Function Call
 Function Declaration

19
UNIT III

The Function Definition is an independent program module that is specially written to


implement the requirements of the function. In order to use this function we need to
invoke it at a required place in the program. This is known as the function call. The
program that calls the function is referred to as the calling program or calling function.
The calling program should declare any function that is to be used later in the
program. This is known as the function declaration or function prototype.

DEFINITION OF FUNCTIONS
A function definition is an independent implementation shall include the following
elements:
1. Function Name
2. Function Type
3. List of Parameters
4. Local variable declarations
5. Function statements
6. A return statement

All the six elements are grouped into two parts, namely,
 Function Header
 Function Body

The general form of a function declaration to implement these two parts is :


function_type function_name(parameter list)
{
local variable declarations;
executable statements1;
executable statements2;
return(statement);
}
The function_type function_name(parameter list) is known as function
header and the statements within the opening and closing braces constitute the
function body, which is a compound statement.
In the above function format, all parts are not essential
 The parameter list and its associated declaration parts are Optional.
 The declaration of local variables is required only when any local variables are
used in the function. These local variables doesn‟t have any meaning outside

20
UNIT III

the function. Therefore their values are local to the function and cannot be
accessed by any other function.
 A function can have any number of executable statements. A function that does
nothing, may not include any executable statements at all.
 The return statement is the mechanism for returning a value to the calling
function. This is also an optional statement. Its absence indicates that no value
is being returned to the calling function.

Function Header
The function header consists of three parts: the function type (return type), the
function name and the formal parameter list. Note that the semicolon is not used at the
end of the function header.

Function Name and Type


The function type specifies the type of value that the function is expected to
return to the program calling the function. If the return type is not explicitly specified,
C will assume that it is an integer type. If the function is not returning anything , the
we need to specify the return type as void. Void is one of the fundamental data types
in C.
The function name is any valid C identifier and therefore must follow the same
rules of formation as other variable names in C. The name should be appropriate to the
task performed by the function.

Formal Parameter List


The parameter list declares the variables that will receive the data sent by the
calling program. They serve as input data to the function to carry out the specified
task. Since they represent actual input values, they are often referred as formal
parameters. These parameters can also be used to send vales to the calling programs.
The parameter are also known as Arguments. The parameter list contains declaration
of variables separated by commas and surrounded by parenthesis.

Examples:
float quadratic( int a, int b, int c) {……..}
double power(double x, int n) {……}
float mul(float x, float y){………}
int sum(int a, int b) {………..}
The parameter variables receive values from the calling function, thus providing a
means for data communication from the calling function to the called function.

21
UNIT III

Function Body
The function body contains the declarations and statements necessary for
performing the required task. The body enclosed in braces, contains three parts, in the
given order below:
1. Local declaration that specify the variables needed by the function.
2. Function statements that perform the task of the function.
3. A return statement that returns the value evaluated by the function.
The function does not any value, we can omit the return statement.
Examples:
a) float mul( float x, float y) b) void sum( int a, int b)
{ {
float result; printf(“sum is =d”, a+b);
return;
result=x*y;
}
return result;
}
c)
void display()
{
printf (“No type and parameter”);
}

RETURN VALUES AND THEIR TYPES


All functions by default return int type data.
A function may or may not send back any value to the calling function. If it
does, it is done through the return statement. While it is possible to pass to the called
function any number of values, the called function can only return one value per
call, at the most.
The return statement can take one of the following forms
return; or return(expression);
The first, the 'plain' return does not return any value; it acts much as the closing brace
of the function. When a return is encountered, the control is immediately passed back
to the calling function. The second form of return with an expression returns the value
of the expresion. For example, the function
mul(int x, int y)
{

22
UNIT III

int p;
p = x*y;
return(p);
}
returns the value of p which is the product of the values of x and y. The last two
statements can be combined into one statement as follows: return (x*y);
A function may have more than one return statements. This situation arises when
the value returned is based on certain conditions. For example:
if( x <= 0 )
return(0);
else
return(1);
We can force a function to return a particular type of data by using a type specifier in
the function header.
Example:
double product(x,y)
float sqr_root(p)
When a value is returned, it is automatically cast to the function's type.

FUNCTION CALLS
A function can be called by simply using the function name in a statement.
Example:
main( )
{ int p;
p = mul(10,5);
printf("%d\n", p);
}
When the compiler encounters a function call, the control is transferred to the function
mul(x,y). This function is then executed line by line as described and a value is
returned when a return statement is encountered. This value is assigned to p.
main( )
{ int p;
p = mul(10,5);
printf("%d\n", p);
}
Int mul(int x, int y)
{

23
UNIT III

int p; /*local variable*/


p=x*y; ?8 x=10. Y=5;*/
return p;
}
A function which returns a value can be used in expressions like any other variable.
Each of the following statements is valid:
prinrf("%d\n", mul(p,q));
y = mul(p,q) / (p+q);
if (mul(m,n)>total)
printf("large");
However, a function cannot be used on the right side of an assignment statement.
For instance,
mul(a.b) = 15; is invalid.
A function that does not return any value may not be used in expressions; but can be
called to perform certain tasks specified in the function. Such functions may be called
in by simply stating their names as independent statements.
Example:
main( )
{
printline( );
}
Note the presence of a semicolon at the end.
FUCTION DECLARATION
Like variables, all function in C program must be declared, before they are
invoked. A function declaration (is also called function prototype) consists of four
parts:
1. Function Type(return type)
2. Function Name
3. List of Parameters
4. Terminating semicolon
They are coded in the following format:
function_type function_name(parameter list);
This is very similar to the function header line except the Terminating semicolon.

24
UNIT III

CATEGORY OF FUNCTIONS
A function, depending on whether the arguments are present or not and
whether a value is returned or not, may belong to one of the following categories.
Category 1: Functions with no arguments and no return values.
Category 2: Functions with arguments and no return values.
Category 3: Functions with arguments and one return values.
Category 4: Functions with no arguments but return a value.
Category 5: Functions that return multiple values.

1. NO ARGUMENTS AND NO RETURN VALUES


When a function has no arguments, it does not receive any data from the
calling function. Similarly, when it does not return a value, the calling function does
not receive any data from the called function. In effect, there is no data transfer
between the calling function and the called function.

No data communication

As pointed out earlier, a function that does not return any value cannot be used in an
expression. It can only be used as an independent statement.
Example:
void printline();
void main()
{
printline();
printf(“\n Welcome to the world of C”);
printline();
getch();
}
void printline()
{
int i;

25
UNIT III

for(i=1;i<=35;i++)
printf(“-“);
printf(“\n”);
}
Above program is with two user defined functions i.e main() and printline(). Main is
calling function that calls printline(), which has no arguments and no return values.
When the printline function encountered, prints a line with a length of 35 characters.
There is no return statement in printline function. When there is nothing to be
returned, the return statement is optional. The closing braces signals the end of
execution of the function, thus returning the control, back to the calling function.

2. ARGUMENTS BUT NO RETURN VALUES


We could make the calling function to read data from the terminal and pass it
on to the called function. Here the calling function can check for the validity of data, if
necessary, before it is handed over to the called function.
The nature of data communication between the calling function and the called
function with arguments but no return value can be shown as follows.

One-way data communication

Here the value of actual argument „a‟ is copied to the formal parameter „f‟. The
actual and formal arguments should match in number, type, and order. The values of
actual arguments are assigned to the formal arguments on a one to one basis, starting
with the first argument.

26
UNIT III

While the formal arguments must be valid variable names, the actual arguments
may be variable names, expressions, or constants. The variables used in actual
arguments must be assigned values before the function call is made.
When a function call is made, only a copy of the values of actual arguments is
passed into the called function. What occurs inside the function will have no effect on
the variables used in the actual argument list.
Example:
void printline();
void value(float, float, int);
void main()
{
int period;
float rate, principal;
printf(“Enter the principal amount, rate and period”);
scanf(“%f%f%d”,&principal, &rate, &period);
printline();
value(principal, rate, period);
printline();
getch();
}
void printline()
{
int i;
for(i=1;i<=35;i++)
printf(“-“);
printf(“\n”);
}
value(float p, float r, int t)
{
float i=p*t*r/100;

27
UNIT III

printf(“Interest values = %f”, i);


}
The variables declared inside a function are known as local variables and therefore
their values are local to the function and cannot be accessed by any other function.

3. ARGUMENTS WITH RETURN VALUES


Sometimes we may need to use the result of a function in the calling function
for further processing. Moreover, to assure a high degree of portability between
programs, a function should generally be coded without involving any I/O operations.
A self-contained and independent function should behave like a 'black box' that
receives a predefined form of input and outputs a desired value. Such functions will
have two-way data communication as shown below.

Two-way data communication between functions

The following events occur, in order, when the above function call is executed:
1. The function call transfers the control along with copies of the values of the
actual argument to function2 where the formal argument „f‟ is assigned the
value of „a‟.
2. The called function value is executed line by line in a normal fashion until the
return(e); statement is encountered. At this point, the value of „e‟ is passed back
to the function- call in the main.
3. The calling statement is executed normally and the returned value is thus can be
assigned to another variable.
Example:-
Example:
void printline();
float value(float, float, int);
void main()
{ int period;

28
UNIT III

float rate, principal, x


printf(“Enter the principal amount, rate and period”);
scanf(“%f%f%d”,&principal, &rate, &period);
printline();
x=value(principal, rate, period);
printf(“The interest =%f”, x);
printline();
getch();
}
void printline()
{
int i;
for(i=1;i<=35;i++)
printf(“-“);
printf(“\n”);
}
value(float p, float r, int t)
{
return(p*t*r/100);
}

4: FUNCTIONS WITH NO ARGUMENTS BUT RETURN A VALUE.


There could be occasions where we may need to design functions that may not
take any arguments but returns value to the calling function.
Example:
int get_number();
void main()
{
int m =get_number();
printf(“%d”, m);
}
int get_number()
{
int number;
scanf(“%d”, &number);
return (number);
}

29
UNIT III

5: FUNCTIONS THAT RETURN MULTIPLE VALUES.


Till now we have illustrated functions that return just one value using return
statement, because a return statement can return only one value. Suppose we want to
get more information from a function. We can achieve this in C using the arguments
not only to receive information but also to send back information to the calling
function. The arguments that are used to “send out” information are called output
parameters.
The mechanism of seding back information through arguments is achieved
using what are known as the addess operator(&) and indirection operator(*).
Example:
void mathoperation(int x, int y , int *s, int *d);
void main()
{
int x=20, y=10, s,d;
mathoperation(x,y,&s,&d);
printf(“s=%d d=%d”, s,d);
}
void mathoperation(int a, int b, int *sum, int *diff)
{
*sum=a+b;
*diff=a-b;
}
The actual arguments x and y are input arguments, s and d are output arguments. In
the function call, while we pass the actual values of x and y to the function, we pass
the addresses of locations where the values of s and d are stored in the memory. When
the function is called the following assignments occur:
Value of x to a
Value of y to b
Address of s to sum
Address of d to diff
The indirection operator * in the declaration of sum and diff in the header indicates
these variables are to store addresses, not actual values of variables. The variables sum
and diff point to the memory locations of s and d respectively.
The statements *sum=a+b and *diff=a-b; adds and subtracts the values a and b and
the result is stored in the memory location pointed to by sum and diff. This memory

30
UNIT III

location is the same as the memory location of s and d. Therefore, the value stored in
the location pointed to by sum and diff is the value of s and d.
The variables *sum and *diff are known as pointers and sum and diff as pointer
variables. The use of pointer variables as actual parameters by communicating data
between functions is called “pass by pointers” or “call by address or reference”.

NESTING OF FUNCTIONS
C permits nesting of functions freely. Main can call function1, which calls
function2, which calls function3,….and so on. There is in principle no limit as to how
deeply functions can be nested.
Example:
float ration(int x, int y, int z);
int difference(int x, int y);
void main()
{
int a,b,c;
scanf(“%d%d%d”,&a,&b,&c);
printf(“%f”,ration(a,b,c));
}
float ratio(int x, int y, int z)
{ if (difference(y,z))
return(x/(y-z));
else
return(0.0);
}
int difference(int p, int q)
{ if (p!=q)
return(1);
else
return(0);
}
The above program calculates the ratio a/(b-c);

31
UNIT III

RECURSION
When a called function in turn calls another function a process of 'chaining' occurs.
Recursion a special case of this process, where a function calls itself. A very simple
example of recursion is presented below.
main()
{
printf("This is an example of recursion\n");
main();
}
When executed, this program will produce an output for the continuous indefinite
execution. This is an example of recursion.
Another useful example of recursion is the evaluation of factorials of a given
number. The factorial of a number n is expressed as a series of repetitive
multiplications as shown below:
A function to evaluate factorial of n is as follows:
factorial(int n)
{
int fact;
if(n==1)
return(1);
else
fact = n*factorlal(n-1);
return(fact);
}
Recursive functions can be effectively used to solve problems where the solution is
expressed in terms of successively applying the same solution to subsets of the
problem. When we write recursive functions, we must have an if statement
somewhere to force the function to return without the recursive call being executed.
Otherwise, the function will never return.

32
UNIT III

STORAGE CLASSES
THE SCOPE AND LIFETIME OF VARIABLES IN FUNCTIONS
Variables in C differ in behavior from those in most other languages. It depends on
the 'storage' class a variable may assume. The storage class decides the scope and
longevity of the variable.
The scope of variable determines over what part(s) of the program a variable
is actually available for use (active). Longevity refers to the period during which a
variable retains a given value during execution of a program (alive). So longevity
has a direct effect on the utility of a given variable.
A variable in C can have any one of the four storage classes:
1. Automatic variables
2. External variables
3. Static variables
4. Register variables
The variables may also be broadly categorized, depending on the place of their
declaration, as internal (local) or external (global). Internal variables are those which
are declared within a particular function, while external variables are declared outside
of any function.
 Automatic Variables
Automatic variables are declared inside a function in which they are to be utilized.
They are created when the function is called and destroyed automatically when the
function is exited, hence the name automatic. Automatic variables are therefore
private (or local) to the function in which they are declared. Because of this property,
automatic variables are also referred to as local or internal variables.
A variable declared inside a function without storage class specification is, by
default, an automatic variable. For instance, the storage class of the variable number in
the example below is automatic.
main()
{ int number; }
We may also use the keyword auto to declare automatic variables explicitly.

33
UNIT III

main()
{ auto int number; }
One important feature of automatic variables is that their value cannot be changed
accidentally by what happens in some other function in the program. This assures that
we may declare and use the same variable name in different functions in the same
program without causing any confusion to the compiler.
A program with 2 subprograms function1 and function2 is shown below.

m is an automatic variable and it is declared at the beginning of each function, m is


initialized to 10, 1100, and 1000 in functionl, function2, and main respectively.
When executed, main calls function2 which in turn calls functionl. When main is
active, m = 1000; but when function2 is called, the main's m is temporarily put on the
shelf and the new local m = 100 becomes active. Similarly, when functionl is called,
both the previous values of m are put on the shelf and the latest value of m (=10)
becomes active. As soon as functionl (m=10) is finished, functionl (m=100) takes over
again. As soon it is done, main (m=1000) takes over. The output clearly shows that
the value assigned to m in one function does not affect its value in the other functions;

34
UNIT III

and the local value of m is destroyed when it leaves a function.


There are two consequences of the scope and longevity of auto variables worth
remembering .
 Firstly, any variable local to main will normally live throughout the whole
program, although it is active only in main.
 Secondly, during recursion, the nested variables are unique auto variables
which is a situation similar to function-nested auto variables-with identical
names. Automatic variables can also be defined within a set of braces known as
"blocks". They are meaningful only inside the blocks where they are defined.
Consider the example below:
main()
{

The variables n, a and b defined in main have scope from the beginning to the end
of main . However, the variable n defined in the main cannot enter into the block of
scope level 2 because the scope level 2 contains another variable named n. The
second n (which takes precedence over the first n) is available only inside the scope
level 2 and no longer available the moment control leaves the if block. Of course, if
no variable named n is defined inside the block, then n defined in the main would be
available inside scope level 2 as well. The variable sum defined in the if block is not
available outside that block.
 External Variables
Variables that are both alive and active throughout the entire program are

35
UNIT III

known as external variables. They are also known as global variables. Unlike local
variables, global variables can be accessed by any function in the program. External
variables are declared outside a function.
For example, the external declaration of integer number and float length might
appear as:
int number;
float length = 7.5;
main()
{-------
}
function1()
{ --------
}
function2()
{ ----------
}
The variables number and length are available for use in all the three functions. In
case a local variable and a global variable have the same name, the local variable will
have precedence over the global one in the function where it is declared.
Consider the following example:
int count;
main()
{
count = 10;
………
}

function ( )
{
int count=0;
-------------
count=count+1;
}

When the function references the variable count, it will be referencing only its local
variable, not the global one. The value of count in main will not be affected.
A program to illustrate the properties of global variables is presented below. Note

36
UNIT III

that variable x is used in all functions has a definition for x except funl,. Because x has
been declared 'above' all the functions, it is available to each function without having
to pass x as a function argument.
int x;
main()
{
x= 10;
printf("x = %d\n", x);
printf("x = %d\n",fun1());
printf("x = %d\n", fun2( );
printf("x = %d\n", fun3();
}
fun1()
{
x = x + 10 ; return(x);
}
fun2( )
{
int x ;
x=1;
return(x);
}
fun3()
{
x=x+10;
return(x);
}
Output
x=10
x = 20
x=1
x = 30
Once a variable has been declared as global, any function can use it and change its
value. Then, subsequent functions can reference only that new value.
External Declaration
In any program segment , the main cannot access the variable if it has been
declared after the main function. This problem can be solved by declaring the variable
with the storage class extern.
For example:
main()

37
UNIT III

{
extern int y; /* external declaration */
………………
}
func1()
{
extern int y; /* external declaration */
……………
}
int y; /* definition */

Although the variable y has been defined after both the functions, the external
declaration of y inside the functions informs the compiler that y is an integer type
defined somewhere else in the program. Note that the extern declaration does not
allocate storage space for variables. In case of arrays, the definition should include
their size as well.
Example: main()
{
int i;
void print_out();
extern float height [ ];
…………
print_out(); }
void print_out()
{
extern float height [ ];
int i;
………
}
float height[SIZE];
An extern within a function provides the type information to just that one function.
We can provide type information to all functions within a file by placing external
declarations before any of them, as shown below:
extern float height [ ];
main()
{
int i;

38
UNIT III

void print_out();
………….
print_out();
}
void print_out()
{
int i;
……..
}
float height[SIZE];

The distinction between definition and declaration also applies to functions. A


function is defined when its parameters and function body are specified. This tells the
compiler to allocate space for the function code and provides type information for the
parameters. Since functions are external by default, we daclare them (in the calling
functions) without the qualifier extern. Therefore, the declaration
void print_out(); is equivalent to extern void print_out(); Function declarations outside
of any function behave the same way as variable declarations.
 static Variables
As the name suggests, the value of static variables persists until the end of the
program. A variable can be declared static using the keyword static like
static int x; static float y;
A static variable may be either an internal type or an external type, depending
on the place of declaration.
Internal static variables are those which are declared inside a function. The
scope of intenal static variables extend upto the end of the function in which they are
defined. Therefore, internal static variables are similar to auto variables, except that
they remain in existence (alive) through out the remainder of the program. Therefore,
internal static variables can be used to retain values between function calls.
For example, it can be used to count the number of calls made to a function.

39
UNIT III

A static variable is initialized only once, when the program is compiled. It is never
initialized again. During the first call to stat, x is incremented to 1. Because x is static,
this value persists and therefore, the next call adds another 1 to x giving it a value of 2.
The value of x becomes three when the third call is made.
If x is declared as auto then output will be
x=1
x=1
x=1
This is because each time stat is called, the auto variable x is initialized to zero.
When the function terminates, its value of 1 is lost.
 Register Variables
We can tell the compiler that a variable should be kept in one of the machine's
registers, instead of keeping in the memory (where normal variables are stored). Since
a register access is much faster than a memory access, keeping the frequently accessed
variables (e.g., loop control variables) in the register will lead to faster execution of
programs. This is done as follows:
register int count;
Since only a few variables can be placed in the register, it is important to carefully
select the variables for this purpose. However, C will automatically convert register
variables into non register variables once the limit is reached.
Table summarizes the information on the visibility and lifetime of variables in
functions and files.

40
UNIT III

Storage Where to be declared Visibility (Active) Lifetime (Alive)


class
None Before all functions in a Entire file plus other files where Entire program
file (may be initialized) variable is declared with extern. (Global)
extern Before all functions in a Entire file plus other files where Global
file variable is declared extern and the
(can not be initialized) file where originally declared as
global

static Before all functions in a Only in that file Global


file
None or auto Inside a function (or a Only in that function or block Until end of
block) function or block
register Inside a function or Only in that function or block Until end of
block function or block

static Inside a function Only in that function Global

SCOPE RULES
Scope
The region of a program in which a variable is available for use.
Visibility
The program‟s ability to access a variable from the memory.
Lifetime
The lifetime of a variable is the duration of time in which a variable exists
in the memory during execution.
Rules of use
1. The scope of a global variable is the entire program file.
2. The scope of a local variable begins at point of declaration and ends at the
end of the block or function in which it is declared.
3. The scope of a formal function argument is its own function.
4. The lifetime (longevity) of an auto variable declared in main is the entire
program execution time, although its scope is only the main function.
5. The life of an auto variable declared in a function ends when the function is
exited.
6. A static local variable, although its scope is limited to its function, its
lifetime extends till the end of the program execution.
7. All variables have visibility in their scope, provided they are not declared
again.
8. If a variable, is redeclared within its scope again, it loses its visibility in the
scope of the redeclared variable.

41

You might also like