Notes of C Language
Notes of C Language
Notes of C Language
Generally there are two major types of languages are available are as follows:
The set of commands available in high level language is very simple and
easy to understandable.
High level languages are further divided into two major categories.
C language
Pascal language
C LanguageHistory
IDE
<function declaration>
< Global Variable (on your demand)>
main () (Necessary)
{ statements }
{}
Suppose if you want to use a function clrscr() ; in the main function so must be
declared on top # include <conio.h> other wise you could have an prototype error.
Stdio.h
Conio.h
Dos.h
String.h
Stdlib.h
void main(void)
functions there are in a C program , main is the one to which control is passed
from the operating system when the program is run ; it is the first function
executed. The word "void" preceding "main" specifies that the function main()
will not return a value. The second "void," in parenthesis , specifies that the
printf()
printf() is built-in function we can display with printf() any message, variable
value on screen/file/printer.
Escape sequences are special notations through which we can display our data
Variety of ways:
Example Program #1
#include <stdio.h>
#include <conio.h>
void main(void)
getch();
--------------------------------------------
------------------------------------------
\\ \
\’ ‘
\" \"
Example Program #2
#include <stdio.h>
#include <conio.h>
void main(void)
clrscr();
getch();
"Pakistan ZindaBad"
Description : in the above we use a escape sequence \" this will produce " on
screen after that a message Pakistan ZindaBad is appear after the message another
" ( double quotation) appear on screen because of \"
Variable : variables are named peace of memory in which we can store our data
and manipulate our data. Variables are used so that same space in memory can
hold different values at different times.
In C language following are the list of data type available through which we can
define our variables:
Variables
In C, a variable must be declared before it can be used. Variables can be declared at the
start of any block of code, but most are found at the start of each function. Most local
variables are created when the function is called, and are destroyed on return from that
function.
A declaration begins with the type, followed by the name of one or more variables. For
example,
Variable Names
Every variable has a name and a value. The name identifies the variable, the value stores
data. There is a limitation on what these names can be. Every variable name in C must
start with a letter, the rest of the name can consist of letters, numbers and underscore
characters. C recognises upper and lower case characters as being different. Finally, you
cannot use any of C's keywords like main, while, switch etc as variable names.
variable name. Most modern ones don't apply this limit though.
The rules governing variable names also apply to the names of functions. We shall meet
functions later on in the course.
Global Variables
Local variables are declared within the body of a function, and can only be used within
that function. This is usually no problem, since when another function is called, all
required data is passed to it as arguments. Alternatively, a variable can be declared
globally so it is available to all functions. Modern programming practice recommends
against the excessive use of global variables. They can lead to poor program structure,
and tend to clog up the available name space.
A global variable declaration looks normal, but is located outside any of the program's
functions. This is usually done at the beginning of the program file, but after preprocessor
directives. The variable is not declared again in the body of the functions which access it.
Static Variables
Another class of local variable is the static type. A static can only be accessed from the
function in which it was declared, like a local variable. The static variable is not
destroyed on exit from the function, instead its value is preserved, and becomes available
again when the function is next called. Static variables are declared as local variables, but
the declaration is preceeded by the word static.
Constants
A C constant is usually just the written version of a number. For example 1, 0, 5.73,
12.5e9. We can specify our constants in octal or hexadecimal, or force them to be treated
as long integers.
Character constants are usually just the character enclosed in single quotes; 'a', 'b', 'c'.
Some characters can't be represented in this way, so we use a 2 character sequence.
In addition, a required bit pattern can be specified using its octal equivalent.
Character constants are rarely used, since string constants are more convenient. A string
constant is surrounded by double quotes eg "Brian and Dennis". The string is actually
stored as an array of characters. The null character '\0' is automatically placed at the end
of such a string to act as a string terminator.
We will meet strings and characters again when we deal with the input / output functions
in more detail.
Arithmetic operators are the most common. Other operators are used for comparison of
values, combination of logical states, and manipulation of individual binary digits. The
binary operators are rather low level for so are not covered here.
Operators and values are combined to form expressions. The values produced by these
expressions can be stored in variables, or used as a part of even larger expressions.
• Assignment Statement
• Arithmetic operators
• Type conversion
• Comparison
• Logical Connectors
Assignment Statement
The easiest example of an expression is in the assignment statement. An expression is
evaluated, and the result is saved in a variable. A simple example might look like
y = (m * x) + c
count = count + 1;
C has some operators which allow abbreviation of certain types of arithmetic assignment
statements.
These operations are usually very efficient. They can be combined with another
expression.
Versions where the operator occurs before the variable name change the value of the
variable before evaluating the expression, so
These can cause confusion if you try to do too many things on one command line. You
are recommended to restrict your use of ++ and - to ensure that your programs stay
readable.
Comparison
C has no special type to represent logical or boolean values. It improvises by using any of
the integral types char, int, short, long, unsigned, with a value of 0 representing false and
any other value representing true. It is rare for logical values to be stored in variables.
They are usually generated as required by comparing two numeric values. This is where
the comparison operators are used, they compare two numeric values and produce a
logical result.
x == y
i > 10
a + b != c
In the last example, all arithmetic is done before any comparison is made.
These comparisons are most frequently used to control an if statement or a for or a while
loop. These will be introduced in a later chapter.
Logical Connectors
These are the usual And, Or and Not operators.
Not operates on a single logical value, its effect is to reverse its state. Here is an example
of its use.
if ( ! acceptable )
printf("Not Acceptable !!\n");
Control Statements
A program consists of a number of statements which are usually executed in sequence.
Programs can be much more powerful if we can control the order in which statements are
run.
This section will discuss the use of control statements in C. We will show how they can
be used to write powerful programs by;
The following test decides whether a student has passed an exam with a pass mark of 45
If we wish to have more than one statement following the if or the else, they should be
grouped together between curly brackets. Such a grouping is called a compound
statement or a block.
• Only one variable is tested, all branches must depend on the value of that variable.
The variable must be an integral type. (int, long, short or char).
• Each possible value of the variable can control a single branch. A final, catch all,
default branch may optionally be used to trap all unspecified cases.
Hopefully an example will clarify things. This is a function which converts an integer
into a vague description. It is useful where we are only concerned in measuring a quantity
when it is quite small.
estimate(number)
int number;
/* Estimate a number as none, one, two, several, many */
{ switch(number) {
case 0 :
printf("None\n");
break;
case 1 :
printf("One\n");
break;
case 2 :
printf("Two\n");
break;
case 3 :
case 4 :
case 5 :
printf("Several\n");
break;
default :
printf("Many\n");
break;
}
}
Each interesting case is listed with a corresponding action. The break statement prevents
any further statements from being executed by leaving the switch. Since case 3 and case 4
have no following break, they continue on allowing the same action for several values of
number.
Both if and switch constructs allow the programmer to make a selection from a number
of possible actions.
The other main type of control statement is the loop. Loops allow a statement, or block of
statements, to be repeated. Computers are very good at repeating simple tasks many
times, the loop is C's way of achieving this.
Loops
C gives you a choice of three types of loop, while, do while and for.
• The while loop keeps repeating an action until an associated test returns false.
This is useful where the programmer does not know in advance how many times
the loop will be traversed.
• The do while loops is similar, but the test occurs after the loop body is executed.
This ensures that the loop body is run at least once.
• The for loop is frequently used, usually where the loop will be traversed a fixed
number of times. It is very flexible, and novice programmers should take care not
to abuse the power it offers.
As an example, here is a function to return the length of a string. Remember that the
string is represented as an array of characters terminated by a null character '\0'.
return(i);
}
The string is passed to the function as an argument. The size of the array is not specified,
the function will work for a string of any size.
The while loop is used to look at the characters in the string one at a time until the null
character is found. Then the loop is exited and the index of the null is returned. While the
character isn't null, the index is incremented and the test is repeated.
do
{ printf("Enter 1 for yes, 0 for no :");
scanf("%d", &input_value);
} while (input_value != 1 && input_value != 0)
The for Loop
The for loop works well where the number of iterations of the loop is known before the
loop is entered. The head of the loop consists of three parts separated by semicolons.
• The first is run before the loop is entered. This is usually the initialisation of the
loop variable.
• The second is a test, the loop is exited when this returns false.
• The third is a statement to be run every time the loop body is completed. This is
usually an increment of the loop counter.
The example is a function which calculates the average of the numbers stored in an array.
The function takes the array and the number of elements as arguments.
float average(float array[], int count)
{ float total = 0.0;
int i;
return(total / count);
}
The for loop ensures that the correct number of array elements are added up before
calculating the average.
The three statements at the head of a for loop usually do just one thing each, however any
of them can be left blank. A blank first or last statement will mean no initialisation or
running increment. A blank comparison statement will always be treated as true. This will
cause the loop to run indefinitely unless interrupted by some other means. This might be
a return or a break statement.
It is also possible to squeeze several statements into the first or third position, separating
them with commas. This allows a loop with more than one controlling variable. The
example below illustrates the definition of such a loop, with variables hi and lo starting at
100 and 0 respectively and converging.
Like a break, continue should be protected by an if statement. You are unlikely to use it
very often.
Pointers in C
Pointers are not exclusive to functions, but this seems a good place to introduce the
pointer type.
Imagine that we have an int called i. Its address could be represented by the symbol &i. If
the pointer is to be stored as a variable, it should be stored like this.
The opposite operator, which gives the value at the end of the pointer is *. An example of
use, known as de-referencing pi, would be
i = *pi;
Take care not to confuse the many uses of the * sign; Multiplication, pointer declaration
and pointer de-referencing.
This is a very confusing subject, so let us illustrate it with an example. The following
function fiddle takes two arguments, x is an int while y is a pointer to int. It changes both
values.
main()
{ int i = 0;
int j = 0;
Starting main : i = 0 ,j = 0
Calling fiddle now
Starting fiddle: x = 0, y = 0
Finishing fiddle: x = 1, y = 1
Returned from fiddle
Finishing main : i = 0, j = 1
After the return from fiddle the value of i is unchanged while j, which was passed as a
pointer, has changed.
To summarise, if you wish to use arguments to modify the value of variables from a
function, these arguments must be passed as pointers, and de-referenced within the
function.
Where the value of an argument isn't modified, the value can be passed without any
worries about pointers.
The Standard Input Output File
UNIX supplies a standard package for performing input and output to files or the
terminal. This contains most of the functions which will be introduced in this section,
along with definitions of the datatypes required to use them. To use these facilities, your
program must include these definitions by adding the line This is done by adding the line
#include <stdio.h>
near the start of the program file.
If you do not do this, the compiler may complain about undefined functions or datatypes.
• printf
• scanf
printf
This offers more structured output than putchar. Its arguments are, in order; a control
string, which controls what gets printed, followed by a list of values to be substituted for
entries in the control string.
There are several more types available. For full details type
man printf
on your UNIX system.
It is also possible to insert numbers into the control string to control field widths for
values to be displayed. For example %6d would print a decimal value in a field 6 spaces
wide, %8.2f would print a real value in a field 8 spaces wide with room to show 2
decimal places. Display is left justified by default, but can be right justified by putting a -
before the format information, for example %-6d, a decimal integer right justified in a 6
space field.
scanf
scanf allows formatted reading of data from the keyboard. Like printf it has a control
string, followed by the list of items to be read. However scanf wants to know the address
of the items to be read, since it is a function which will change that value. Therefore the
names of variables are preceeded by the & sign. Character strings are an exception to
this. Since a string is already a character pointer, we give the names of string variables
unmodified by a leading &.
Control string entries which match values to be read are preceeded by the percentage sign
in a similar way to their printf equivalents.
• gets
• puts
gets
gets reads a whole line of input into a string until a newline or EOF is encountered. It is
critical to ensure that the string is large enough to hold any expected input lines.
puts
puts writes a string to the output, and follows it with a newline character.
Example: Program which uses gets and puts to double space typed input.
#include <stdio.h>
main()
{ char line[256]; /* Define string sufficiently large to
store a line of input */
Note that putchar, printf and puts can be freely used together. So can getchar, scanf and
gets.
Arrays
In C, as in Fortran or PL/I, it is possible to make arrays whose elements are basic types.
Thus we can make an array of 10 integers with the declaration
int x[10];
The square brackets mean subscripting; parentheses are used only for function
references. Array indexes begin at zero, so the elements of x are
x[0], x[1], x[2], ..., x[9]
If an array has n elements, the largest subscript is n-1.
Multiple-dimension arrays are provided, though not much used above two dimensions.
The declaration and use look like
Here is a program which reads a line, stores it in a buffer, and prints its length (excluding
the newline at the end).
main( ) {
int n, c;
char line[100];
n = 0;
while( (c=getchar( )) != '\n' ) {
if( n < 100 )
line[n] = c;
n++;
}
printf("length = %d\n", n);
}
As a more complicated problem, suppose we want to print the count for each line in the
input, still storing the first 100 characters of each line. Try it as an exercise before
looking at the solution:
main( ) {
int n, c; char line[100];
n = 0;
while( (c=getchar( )) != '\0' )
if( c == '\n' ) {
printf("%d0, n);
n = 0;
}
else {
if( n < 100 ) line[n] = c;
n++;
}
}
Strings
Text is usually kept as an array of characters, as we did with line[ ] in the example
above. By convention in C, the last character in a character array should be a `\0'
because most programs that manipulate character arrays expect it. For example, printf
uses the `\0' to detect the end of a character array when printing it out with a `%s'.
i = 0;
while( (t[i]=s[i]) != '\0' )
i++;
Most of the time we have to put in our own `\0' at the end of a string; if we want to print
the line with printf, it's necessary. This code prints the character count before the line:
main( ) {
int n;
char line[100];
n = 0;
while( (line[n++]=getchar( )) != '\n' );
line[n] = '\0';
printf("%d:\t%s", n, line);
}
Here we increment n in the subscript itself, but only after the previous value has been
used. The character is read, placed in line[n], and only then n is incremented.
There is one place and one place only where C puts in the `\0' at the end of a character
array for you, and that is in the construction
Functions
Suppose we want, as part of a larger program, to count the occurrences of the ascii
characters in some input text. Let us also map illegal characters (those with value>127
or <0) into one pile. Since this is presumably an isolated part of the program, good
practice dictates making it a separate function. Here is one way:
main( ) {
int hist[129]; /* 128 legal chars + 1 illegal
group*/
...
count(hist, 128); /* count the letters into hist */
printf( ... ); /* comments look like this; use them
*/
... /* anywhere blanks, tabs or newlines could
appear */
}
count(buf, size)
int size, buf[ ]; {
int i, c;
for( i=0; i<=size; i++ )
buf[i] = 0; /* set buf to
zero */
while( (c=getchar( )) != '\0' ) { /* read til
eof */
if( c > size || c < 0 )
c = size; /* fix illegal
input */
buf[c]++;
}
return;
}
We have already seen many examples of calling a function, so let us concentrate on how
to define one. Since count has two arguments, we need to declare them, as shown,
giving their types, and in the case of buf, the fact that it is an array. The declarations of
arguments go between the argument list and the opening `{'. There is no need to specify
the size of the array buf, for it is defined outside of count.
The return statement simply says to go back to the calling routine. In fact, we could
have omitted it, since a return is implied at the end of a function.
What if we wanted count to return a value, say the number of characters read? The
return statement allows for this too:
int i, c, nchar;
nchar = 0;
...
while( (c=getchar( )) != '\0' ) {
if( c > size || c < 0 )
c = size;
buf[c]++;
nchar++;
}
return(nchar);
Any expression can appear within the parentheses. Here is a function to compute the
minimum of two integers:
min(a, b)
int a, b; {
return( a < b ? a : b );
}
There is a subtlety in function usage which can trap the unsuspecting Fortran
programmer. Simple variables (not arrays) are passed in C by ``call by value'', which
means that the called function is given a copy of its arguments, and doesn't know their
addresses. This makes it impossible to change the value of one of the actual input
arguments.
There are two ways out of this dilemma. One is to make special arrangements to pass to
the function the address of a variable instead of its value. The other is to make the
variable a global or external variable, which is known to each function by its name