Unit 2 1. Introduction of C: C is a computer programming language. That means that you can use C to create lists of instructions for a computer to follow. C is one of thousands of programming languages currently in use. C has been around for several decades and has won widespread acceptance because it gives programmers maximum control and efficiency. C is an easy language to learn.
On compiling
C is what is called a compiled language. This means that once you write your C program, you must run it through a C compiler to turn your program into an executable that the computer can run (execute). The C program is the humanreadable form, while the executable that comes out of the compiler is the
machine-readable and executable form. What this means is that to write and run a C program, you must have access to a C compiler. You can use Turbo C or Turbo C++ Compilers for this purpose.
2. History of C The milestones in C's development as a language are listed below: •
UNIX developed c. 1969 -- DEC PDP-7 Assembly Language
•
BCPL -- a user friendly OS providing powerful development tools developed from BCPL. Assembler tedious long and error prone.
•
A new language ``B'' a second attempt. c. 1970.
•
A totally new language ``C'' a successor to ``B''. c. 1971
•
By 1973 UNIX OS almost totally written in ``C''.
3. Features of C •
Small size
•
Extensive use of function calls
•
Loose typing -- unlike PASCAL
•
Structured language
•
Low level (Bitwise) programming readily available
•
Pointer implementation - extensive use of pointers for memory, array, structures and functions.
C has now become a widely used professional language for various reasons. •
It has high-level constructs.
•
It is robust language whose rich set of built-in functions and operators can be used to write any complex program.
•
It can handle low-level activities.
•
It produces efficient programs.
•
It is fast. (much faster than BASIC).
•
It can be compiled on a variety of computers.
•
It has the ability to extend itself(A C program is basically collection of functions that are supported by the C Library, We can continuously add our own functions to the C Library)
4. C Program Structure A C program basically has the following form: Documentation Section Link Section Definition Section Global Declaration Section Main() Function Section { Declaration Part Executable Part
} Subprogram Section Function 1 Function 2 ….. …….. Function n
1. Documentation Section: This section consists of a set of comments lines giving the name of the program, the author and other details which the programmer would like to use later. 2. Link Section: This section provides instruction to the complier to link functions from the system library. 3. Definition section: This section defines all symbolic constants. 4. Global Section: Here those variables are declared which are used in more than one function. 5. main() Function Section: Every program must have one main () function section It contains declaration part and executable part. 6. Subprogram Section: It contains all the user-defined functions that are called in the main function. The Simplest C Program: What's Happening? #include <stdio.h> int main() { printf("This is output from my first program!\n"); return 0;
} This C program starts with #include <stdio.h>. This line includes the "standard I/O library" into your program. The standard I/O library lets you read input from the keyboard (called "standard in"), write output to the screen (called "standard out"), process text files stored on the disk, and so on. It is an extremely useful library. C has a large number of standard libraries like stdio, including string, time and math libraries. The line int main() declares the main function. Every C program must have a function named main somewhere in the code.. At run time, program execution starts at the first line of the main function. •
In C, the { and } symbols mark the beginning and end of a block of code. In this case, the block of code making up the main function contains two lines.
•
The printf statement in C allows you to send output to standard out (for us, the screen). The portion in quotes is called the format string and describes how the data is to be formatted when printed. The format string can contain string literals such as "This is output from my first program!," symbols for carriage returns (\n), and operators as placeholders for variables.
•
The return 0; line causes the function to return an error code of 0 (no error) to the shell that started execution.
5. Variables As a programmer, you will frequently want your program to "remember" a value. For example, if your program requests a value from the user, or if it calculates a value, you will want to remember it somewhere so you can use it later. The way your program remembers things is by using variables. For example:
int b; This line says, "I want to create a space called b that is able to hold one integer value." A variable has a name (in this case, b) and a type (in this case, int, an integer). You can store a value in b by saying something like: b = 5; You can use the value in b by saying something like: printf ("%d", b); In C, there are several standard types for variables: •
int - integer (whole number) values
•
float - floating point values
•
char - single character values (such as "m" or "Z")
6. Data Types: 1. Primary data types 2. User-defined data types 3. Derived data types 4. Empty data set Primary Data type:
Other data types will discussed later………..
7. Keywords and Identifiers Every C word is classified as either a keyword or an identifier. All keywords have fixed meanings and these meaning can’t be changed. Keywords serve as basic building blocks for program statements. All keywords must be written in lowercase. ANSI C Keywords: auto
break
double
int
struct
break
else
long
switch
case
enum
register
typedef
char
extern
return
union
const
float
short
unsigned
continue
for
signed
void
default
goto
size of
volatile
do
if
static
while
Identifiers refers to the names of variables, functions and arrays. These are userdefined names and consist of a sequence of letters and digits, with a letter as a first character. Both uppercase and lowercase letters are permitted. The underscore character is also permitted.
8. Constants: ANSI C allows you to declare constants. When you declare a constant it is a bit like a variable declaration except the value cannot be changed. The const keyword is to declare a constant, as shown below: int const a = 1; const int a =2; Note: •
You can declare the const before or after the type. Choose one and stick to it.
•
It is usual to initialize a const with a value as it cannot get a value any other way.
The preprocessor #define is another more flexible method to define constants in a program. You frequently see const declaration in function parameters. This says simply that the function is not going to change the value of the parameter. Basic types of constants:
Constants
Numeric Constants
Integer Constant s
Real Constant s
Character Constants
Single char Constants
String Constant s
Integer Constants: An integer constant refers to a sequence of digits. These are of three types a. Decimal b. Octal c. Hexadecimal
Real Constants: These quantities are represented by numbers containing fractional parts like 17.548. Such numbers are called real constants.
Single Char Constants: These contains a single character enclosed within a pair of single quote marks. Example: ‘5’ ‘X’
String Constants: A string constant is a sequence of characters enclosed in double quotes. The characters may be letters, numbers, special characters and blank space. Examples: “Hello!” “1987” “WELL DONE”
Backslash Character Constants C supports some special backslash character constants that are used in output functions. For example, the symbol ‘\n’ stands for new line character. Although they contain two character but they represent a single character. Backslash Character Constants Constants ‘\a’ ‘\b’ ‘\f’ ‘\n’ ‘\r’ ‘\v’ ‘\’’ ‘\”’ ‘\?’ ‘\\’
Meaning Alert Backspace Form feed New line Carriage return Vertical tab Single quote Double quote Question mark Backslash
9. OPERATORS AND EXPRESSION
a. Arithmetic Operators:
Operator
Meaning
+
Addition or unary plus
-
Subtraction or unary minus
*
Multiplication
/
Division
%
Modulo Division
Note: C does not have an operator for exponentiation Integer arithmetic: When both the operands in a single arithmetic expression are integers, the expression is called Integer expression, and the operation is called integer arithmetic... Integer arithmetic always yields an integer value. Examples Let a = 14, b = 4 a – b = 10 a + b = 18 a * b = 56 a / b = 3 (decimal part truncated) a % b = 2 (remainder of division) Real arithmetic: An arithmetic operation involving only real operands is called real arithmetic. The result is an approximation of correct value. Examples: 6.0 / 7.0 = 0.857143
-2.0 / 3.0 = - 0.666667
Mixed Mode Arithmetic When one of the operands is real and the other is integer, the expression is called a mixed – mode arithmetic expression. If either operand is of the real type, then only real operation is performed and result is always a real number. Example 15 / 10.0 = 1.5 15 / 10 = 1 •
There are other operators available. The two arithmetic operators that are used frequently are ++ and --. You can place these in front or on the back of variables. ++ specifies increment, the -- specifies decrement. If the operator is placed in front, it is prefix if it is placed behind, it is postfix. Prefix means, increment before any operations are performed, postfix is increment afterwards. These are important considerations when using these operators.
•
C allows *= += /= -= operators. For example: a=a+1
equivalent to
a+=1
a=a-1
equivalent to
a-=1
a=a%b
equivalent to
a%=b
b. Relational Operators: You probably are familiar with < and the > relational operators from mathematics. The same principles apply in C when you are comparing two objects. •
There are six possibilities in C: <, <=, >, >=, !=, and ==. The first four a self-explanatory, the != stands for "not equals to" and == is "equivalent to".
•
Here we can point out the difference between syntax and semantics. a = b is different from a == b. Most C compilers will allow both statements to be used in conditionals like if, but they have two completely different
meanings. Make sure your assignment operators are where you want them to be and your relational where you want relational comparisons!
c. Logical Operators: •
Logical operators simulate boolean algebra in C.
•
A sampling of Logical/Boolean Operators: &&, ||, &, |, and ^. Operator
Meaning
&&
•
logical AND
||
logical OR
!
logical NOT
For example, && is used to compare two objects with AND: x != 0 && y != 0
•
Expressions
involving
logical
operators
undergo
Short-Circuit
Evaluation. Take the above example into consideration. If x! = 0 evaluates to false; the whole statement is false regardless of the outcome of y! = 0. This can be a good thing or a bad thing depending on the context.
d. Conditional Operators: A ternary operator pair “?:” is available in C to construct conditional expressions of the form exp1 ? exp2 : exp3 Working: The exp1 is evaluated first; if it is nonzero (true) then the exp2 is evaluated and becomes the value of the expression. If exp1 is false, exp3 is evaluated and its value becomes the value of the expression.
Example:
a = 10; b = 15; x = (a>b)?a:b; is equivalent to if (a > b) x = a; else b = b;
e. Bitwise Operators These operators are used for testing the bits, or shifting them right or left. Bitwise operators may not be applied to float or double. Operator
Meaning
&
Bitwise AND
|
Bitwise OR
<<
Shift left
>>
Shift right
~
1’s complement
^
Bitwise exclusive OR
10. Precedence and Associativity It is necessary to be careful of the meaning of such expressions as a + b * c
We may want the effect as either (a + b) * c
or
a + (b * c)
All operators have a priority, and high priority operators are evaluated before lower priority ones. Operators of the same priority are evaluated from left to right, so that a-b-c
is evaluated as (a-b)-c
as you would expect. From high priority to low priority the order for all C operators is: Operators Associativity ( [ - . Left to right ! - ++ -{- + * & (type-cast) sizeof Right to left (in the above line, +, - and * are the unary forms) * / % Left to right + Left to right << >> Left to right < <= > >= Left to right == != Left to right & Left to right ^ Left to right | Left to right && Left to right || Left to right ?: Left to right = += -= *= /= %= &= ^= |= <<= >>= Right to left , Left to right
Thus a < 10 && 2 * b < c
is interpreted as ( a < 10 ) && ( ( 2 * b ) < c )
12. Type Conversions in Expressions: C permits mixing of constants and variables of different types in an expression, but during evaluation it adhere to very strict rules of type conversion. If the operands are of different types, the ‘lower; types is automatically converted to the ‘higher’ type before the operation proceeds. The result is higher type. The final result of an expression is converted to the type of the variable on the left of the assignment sign before assigning the value to it. However, the following changes are introduced during final assignment. 1. float to int cause truncation of the fractional part. 2. double to float caused rounding of digits. 3. long int to int causes dropping of the excess higher order bits Casting a Value: There are instances when we want to force a type conversion in a way that is different from automatic conversion. Example ratio = female_number/male_number Since female_number and male_number are declared as integers in the program, the decimal part of the result of division would be lost and ratio would represent a wrong figure. This problem can be solved by converting locally one of the variables to the floating as shown below: ratio = (float) female_number/male_number
The process of such a local conversion is known as casting a value. The general form of cast is: (type-name) expression
13. Basic I/O Functions 1. Reading a Character:
getchar() syntax is: variable_name=getchar(); Example char name; name = getchar(); will assign the character ‘H’ to the variable name when we press the key H on the keyboard.
getch() getch() is also used to read a character from input device. getch() displays the character without accepting the carriage return.
getche() getche() reads a character from standard input device but the character is not displayed on the screen and also carriage return is not accepted.
2. Writing a Character This function writes a character to the standard output device. syntax putchar(variable_name); Where variable_name is type char variable containing a character. This statement displays character contained in the variable-name at the terminal. Example: answer=’Y’; putchar(answer); Will display the character ‘Y’ on the screen.
14. Formatted input/output Function: printf() The function is defined as follows: int printf(char *format, arg list ...) -prints to stdout the list of arguments according specified format string. Returns number of characters printed. The format string has 2 types of object: •
ordinary characters -- these are copied to output.
•
conversion specifications -- denoted by % and listed in Table
Table: Printf/scanf format characters Format Spec (%)
Type
Result
c
char
single character
i,d
int
decimal number
o
int
octal number
x,X
int
hexadecimal number lower/uppercase notation
u
int
s
char *
unsigned int print string terminated by
f
0
double/float format -m.ddd...
e,E
"
Scientific Format -1.23e002
g,G
"
e or f whichever is most compact
%
-
print % character
Between % and format char we can put: - (minus sign)
integer number m.d
-- left justify.
-- field width. -- m = field width, d = precision of number of digits after decimal point or number of chars from a string.
So:
printf("%-2.3f\n",17.23478);
The output on the screen is: 17.235 and: printf("VAT=17.5%%\n"); ...outputs: VAT=17.5% Example: #include <stdio.h> int main() { int a, b, c; a = 5; b = 7; c = a + b; printf("%d + %d = %d\n", a, b, c); return 0; }
Here is an explanation of the different lines in this program: •
The line int a, b, c; declares three integer variables named a, b and c. Integer variables hold whole numbers.
•
The next line initializes the variable named a to the value 5.
•
The next line sets b to 7.
•
The next line adds a and b and "assigns" the result to c. The computer adds the value in a (5) to the value in b (7) to form the result 12, and then places that new value (12) into the variable c. The
variable c is assigned the value 12. For this reason, the = in this line is called "the assignment operator." •
The printf statement then prints the line "5 + 7 = 12." The %d placeholders in the printf statement act as placeholders for values. There are three %d placeholders, and at the end of the printf line there are the three variable names: a, b and c. C matches up the first %d with a and substitutes 5 there. It matches the second %d with b and substitutes 7. It matches the third %d with c and substitutes 12. Then it prints the completed line to the screen: 5 + 7 = 12. The +, the = and the spacing are a part of the format line and get embedded automatically between the %d operators as specified by the programmer.
Scanf() This function is defined as follows: int scanf(char *format, args....) -- reads from stdin and puts input in address of variables specified in args list. Returns number of chars read. Format control string similar to printf Note: The ADDRESS of variable or a pointer to one is required by scanf. scanf(``%d'',&i); We can just give the name of an array or string to scanf since this corresponds to the start address of the array/string. char string[80]; scanf(``%s'',string); The simplest application of scanf looks like this:
scanf("%d", &b); The program will read in an integer value that the user enters on the keyboard (%d is for integers, as is printf, so b must be declared as an int) and place that value into b. The scanf function uses the same placeholders as printf: You MUST put & in front of the variable used in scanf. It is easy to forget the & sign, and when you forget it your program will almost always crash when you run it.
15. Library Functions: C provides a rich set of built-in functions called as library functions. It helps in making programming easy. These are already created functions. If we want to use mathematical functions like sin, cos , etc we need to include math.h Similarly we can include other library functions as required: string.h graphics.h math.h stdio.h conio.h time.h
Unit 3 1. if statements
The if statement has the same function as other languages. It has three basic forms: a). Simple if if (test expression) { statement } b). The if else statement if (test expression) { statement1 }
else { statement2 }
c). Nested if.. else statements:. if(test condition1) { if(test condition2) { statement-1 } else { statement-2 } } else { statement-3 } statement x d) The else if ladder
if (condition 1 ) statement1 else if (expression) statement2 else if statement3………. For example:- int x,y,w; main() { if (x>0) { z=w; ........ } else { z=y; ........ } } Examples:
2. The ?: operator A ternary operator pair “?:” is available in C to construct conditional expressions of the form exp1 ? exp2 : exp3 Working: The exp1 is evaluated first; if it is nonzero (true) then the exp2 is evaluated and becomes the value of the expression. If exp1 is false, exp3 is evaluated and its value becomes the value of the expression. Example: a = 10; b = 15; x = (a>b)?a:b; is equivalent to
if (a > b) x = a; else b = b;
3. goto statement goto statement can transfer the control to any place in a program, it is useful to provide branching within a loop. Another important use of goto is to exit from deeply nested loops when an error occurs. But it is good practice to avoid goto statements. When goto is used, many computers generate less efficient code, morever the logic becomes more complicated. In case any goto statement is absolutely necessary, it must be documented.
4. Switch Statement The C switch is similar to Pascal's case statement and it allows multiple choice of a selection of items at one level of a conditional where it is a far neater way of writing multiple if statements: switch (expression) { case item1: statement1; break; case item2: statement2; break;
case itemn:
statementn; break; default: statement; break; } In each case the value of itemi must be a constant, variables are not allowed. The break is needed if you want to terminate the switch after execution of one choice. Otherwise the next case would get evaluated. Note: This is unlike most other languages. We can also have null statements by just including a ; or let the switch statement fall through by omitting any statements (see e.g. below). The default case is optional and catches any other cases. For example:switch (letter) { case `A': case `E': case `I': case `O': case `U': numberofvowels++; break; case ` ': numberofspaces++;
break; default: numberofconstants++; break; } In the above example if the value of letter is `A', `E', `I', `O' or `U' then numberofvowels is incremented. If the value of letter is ` ' then numberofspaces is incremented. If none of these is true then the default condition is executed, that is numberofconstants is incremented.
5. for loop The C for statement has the following form: for (expression1; 2; expression3) statement; or {block of statements} expression1 initialises; expression2 is the terminate test; expression3 is the modifier (which may be more than just simple increment); NOTE: C basically treats for statements as while type loops For example: int x; main() { for (x=3;x>0;x-)
{ printf("x=%d\n",x); } } ...outputs: x=3 x=2 x=1 ...to the screen All the following are legal for statements in C. The practical application of such statements is not important here, we are just trying to illustrate peculiar features of C for that may be useful:for (x=0;((x>3) && (x<9)); x++) for (x=0,y=4;((x>3) && (y<9)); x++,y+=2) for (x=0,y=4,z=4000;z; z/=10) The second example shows that multiple expressions can be separated a ,. In the third example the loop will continue to iterate until z becomes 0;
6. while loop The while statement is similar to those used in other languages although more can be done with the expression statement -- a standard feature of C. The while has the form: while (expression) statement
For example: int x=3; main() { while (x>0) { printf("x=%d\n",x); x--; } } ...outputs: x=3 x=2 x=1 ...to the screen. Because the while loop can accept expressions, not just conditions, the following are all legal:while (x--); while (x=x+1); while (x+=5); Using this type of expression, only when the result of x--, x=x+1, or x+=5, evaluates to 0 will the while condition fail and the loop be exited.
We can go further still and perform complete operations within the while expression: while (i++ < 10); while ( (ch = getchar()) != `q') putchar(ch); The first example counts i up to 10. The second example uses C standard library functions getchar() - reads a character from the keyboard - and putchar() - writes a given char to screen. The while loop will proceed to read from the keyboard and echo characters to the screen until a 'q' character is read. NOTE: This type of operation is used a lot in C and not just with character reading!! .
7. do-while loop C's do-while statement has the form: do statement; while (expression); For example: int x=3; main() { do { printf("x=%d\n",x--); } while (x>0); }
..outputs:x=3 x=2 x=1 NOTE: The postfix x-- operator which uses the current value of x while printing and then decrements x.
Examples for While loop, Do –while loop and for loop while (a < b) { printf("%d\n", a); a = a + 1; } This causes the two lines within the braces to be executed repeatedly until a is greater than or equal to b. C also provides a do-while structure: do { printf("%d\n", a); a = a + 1; } while (a < b); The for loop in C is simply a shorthand way of expressing a while statement. For example, suppose you have the following code in C:
x=1; while (x<10) { blah blah blah x++; /* x++ is the same as saying x=x+1 */ } You can convert this into a for loop as follows: for(x=1; x<10; x++) { blah blah blah } Note that the while loop contains an initialization step (x=1), a test step (x<10), and an increment step (x++). The for loop lets you put all three parts onto one line, but you can put anything into those three parts. For example, suppose you have the following loop: a=1; b=6; while (a < b) { a++; printf("%d\n",a); }
You can place this into a for statement as well: for (a=1,b=6; a < b; a++,printf("%d\n",a)); It is slightly confusing, but it is possible. The comma operator lets you separate several different statements in the initialization and increment sections of the for loop (but not in the test section).
8. break & continue C provides two commands to control how we loop: •
break -- exit form loop or switch.
•
continue -- skip 1 iteration of loop.
Consider the following example where we read in integer values and process them according to the following conditions. If the value we have read is negative, we wish to print an error message and abandon the loop. If the value read is great than 100, we wish to ignore it and continue to the next value in the data. If the value is zero, we wish to terminate the loop. while (scanf( ``%d'', &value ) == 1 && value != 0) { if (value < 0) { printf(``Illegal value\n''); break; /* Abandon the loop */ } if (value > 100)
{ printf(``Invalid value\n''); continue; /* Skip to start loop again */ } /* Process the value read */ /* guaranteed between 1 and 100 */ ....; ....; } /* end while value != 0 */
9. ARRAYS single dimensional & Multidimensional arrays Let us first look at how we define arrays in C: int listofnumbers[50]; BEWARE: In C Array subscripts start at 0 and end one less than the array size. For example, in the above case valid subscripts range from 0 to 49. This is a BIG difference between C and other languages and does require a bit of practice to get in the right frame of mind. Elements can be accessed in the following ways:thirdnumber=listofnumbers[2]; listofnumbers[5]=100; Multi-dimensional arrays can be defined as follows: int tableofnumbers[50][50]; for two dimensions.
For further dimensions simply add more [ ]: int bigD[50][50][40][30]......[50]; Elements can be accessed in the following ways:
anumber=tableofnumbers[2][3]; tableofnumbers[25][16]=100; We will create a small C program that generates 10 random numbers and sorts them. To do that, we will use a variable arrangement called an array. An array lets you declare and work with a collection of values of the same type. For example, you might want to create a collection of five integers. One way to do it would be to declare five integers directly: int a, b, c, d, e; This is okay, but what if you needed a thousand integers? An easier way is to declare an array of five integers: int a[5]; The five separate integers inside this array are accessed by an index. All arrays start at index zero and go to n-1 in C. Thus, int a[5]; contains five elements. For example: int a[5]; a[0] = 12; a[1] = 9;
a[2] = 14; a[3] = 5; a[4] = 1; One of the nice things about array indexing is that you can use a loop to manipulate the index. For example, the following code initializes all of the values in the array to 0: int a[5]; int i; for (i=0; i<5; i++) a[i] = 0; The following code initializes the values in the array sequentially and then prints them out: #include <stdio.h> int main() { int a[5]; int i; for (i=0; i<5; i++) a[i] = i; for (i=0; i<5; i++) printf("a[%d] = %d\n", i, a[i]); }
More on Arrays Variable Types There are three standard variable types in C:
•
Integer: int
•
Floating point: float
•
Character: char
An int is a 4-byte integer value. A float is a 4-byte floating point value. A char is a 1-byte single character (like "a" or "3"). A string is declared as an array of characters. There are a number of derivative types: •
double (8-byte floating point value)
•
short (2-byte integer)
•
unsigned short or unsigned int (positive integers, no sign bit)
10.Strings: In C Strings are defined as arrays of characters. For example, the following defines a string of 50 characters: char name[50]; C has no string handling facilities built in and so the following are all illegal: char firstname[50],lastname[50],fullname[100]; firstname= "Arnold"; /* Illegal */ lastname= "Schwarznegger"; /* Illegal */ fullname= "Mr"+firstname +lastname; /* Illegal */ However, there is a special library of string handling routines which we will come across later. To print a string we use printf with a special %s control character:
printf(``%s'',name); NOTE: We just need to give the name of the string. In order to allow variable length strings the \0 character is used to indicate the end of a string. So we if we have a string, char NAME[50]; and we store the ``DAVE'' in it its contents will look like:
string constant , such as "I am a string" is an array of characters. It is represented internally in C by the ASCII characters in the string, i.e., ``I'', blank, ``a'', ``m'',... for the above string, and terminated by the special null character ``\0'' so programs can find the end of the string. String constants are often used in making the output of code intelligible using printf ;
printf("Hello, world\n"); printf("The value of a is: %f\n", a); String constants can be associated with variables. C provides the char type variable, which can contain one character--1 byte--at a time. A character string is stored in an array of character type, one ASCII character per location. Never forget that, since strings are conventionally terminated by the null character ``\0'', we require one extra storage location in the array! C does not provide any operator which manipulate entire strings at once. Strings are manipulated either via pointers or via special routines available from the
standard string library string.h. Using character pointers is relatively easy since the name of an array is a just a pointer to its first element. The standard ``string'' library contains many useful functions to manipulate strings; Some of the most useful functions are: char *strcpy(s,ct)
-> copy ct into s, including ``\0''; return s
char *strncpy(s,ct,n) -> copy ncharcater of ct into s, return s char *strncat(s,ct)
-> concatenate ct to end of s; return s
char *strncat(s,ct,n) -> concatenate n character of ct to end of s, terminate with ``\0''; return s int strcmp(cs,ct)
-> compare cs and ct; return 0 if cs=ct, <0 if cs0 if cs>ct
char *strchr(cs,c)
-> return pointer to first occurence of c
in cs or NULL if not encountered size_t strlen(cs)
-> return length of cs
(s and t are char*, cs and ct are const char*, c is an char converted to type int, and n is an int.) Consider the following code which uses some of these functions: #include < string.h> void main() { char line[100], *sub_text; /* initialize string */ strcpy(line,"hello, I am a string;"); printf("Line: %s\n", line);
/* add to end of string */ strcat(line," what are you?"); printf("Line: %s\n", line); /* find length of string */ /* strlen brings back
*/
/* length as type size_t */ printf("Length of line: %d\n", (int)strlen(line)); /* find occurence of substrings */ if ( (sub_text = strchr ( line, 'W' ) )!= NULL ) printf("String starting with \"W\" ->%s\n", sub_text); if ( ( sub_text = strchr ( line, 'w' ) )!= NULL ) printf("String starting with \"w\" ->%s\n", sub_text); if ( ( sub_text = strchr ( sub_text, 'u' ) )!= NULL ) printf("String starting with \"w\" ->%s\n", sub_text); }
Unit 3 1. The need and form of C functions •
Why should we make functions in our programs when we can just do it all under main? Think for a minute about high-end stereo systems. These stereo systems do not come in an all-in-one package, but rather come in separate components: pre-amplifier, amplifier, equalizer, receiver, cd player, tape deck, and speakers. The same concept applies to programming. Your programs become modularized and much more readable if they are broken down into components.
•
This type of programming is known as top-down programming, because we first analyze what needs to be broken down into components. Functions allow us to create top-down modular programs.
•
Each function consists of a name, a return type, and a possible parameter list. This abstract definition of a function is known as it's interface. Here are some sample function interfaces:
•
char *strdup(char *s)
•
int add_two_ints(int x, int y)
•
void useless(void) The first function header takes in a pointer to a string and outputs a char pointer. The second header takes in two integers and returns an int. The last header doesn't return anything nor take in parameters.
•
Some programmers like to separate returns from their function names to facilitate easier readability and searchability. This is just a matter of taste. For example:
int add_two_ints(int x, int y)
•
A function can return a single value to its caller in a statement using the
•
keyword return. The return value must be the same type as the return type specified in the function's interface. Most languages allow you to create functions of some sort. Functions let you chop up a long program into named sections so that the sections can be reused throughout the program. Functions accept parameters and return a result. C functions can accept an unlimited number of parameters. In general, C does not care in what order you put your functions in the program, so long as a the function name is known to the compiler before it is called.
2. User defined and library functions User defined functions: A function has the following layout: return-type function-name ( argument-list-if-necessary ) { ...local-declarations... ...statements... return return-value; } If return-type is omitted, C defaults to int. The return-value must be of the declared type. A function may simply perform a task without returning any value, in which case it has the following layout: void function-name ( argument-list-if-necessary ) {
...local-declarations... ...statements... }
Library functions: Libraries are very important in C because the C language supports only the most basic features that it needs. C does not even contain I/O functions to read from the keyboard and write to the screen. Anything that extends beyond the basic language must be written by a programmer. The resulting chunks of code are often placed in libraries to make them easily reusable. We have seen the standard I/O, or stdio, library already: Standard libraries exist for standard I/O, math functions, string handling, time manipulation, and so on. You can use libraries in your own programs to split up your programs into modules. This makes them easier to understand, test, and debug, and also makes it possible to reuse code from other programs that you write. Library functions are generally not available to us in source form. Argument type checking is accomplished through the use of header files (like stdio.h) which contain all the necessary information. For example, as we saw earlier, in order to use the standard mathematical library(for function like cos, sin etc) you must include math.h via the statement #include < math.h> at the top of the file containing your code. The most commonly used header files are < stdio.h> -> defining I/O routines < ctype.h> -> defining character manipulation routines < string.h> -> defining string manipulation routines < math.h> -> defining mathematical routines
< stdlib.h> -> defining number conversion, storage allocation and similar tasks < stdarg.h> -> defining libraries to handle routines with variable numbers of arguments < time.h> -> defining time-manipulation routines In addition, the following header files exist: < assert.h> -> defining diagnostic routines < setjmp.h> -> defining non-local function calls < signal.h> -> defining signal handlers < limits.h> -> defining constants of the int type < float.h> -> defining constants of the float type
3. Function Arguments C functions can accept parameters of any type. For example: int fact(int i) { int j,k; j=1; for (k=2; k<=i; k++) j=j*k; return j; } returns the factorial of i, which is passed in as an integer parameter. Separate multiple parameters with commas: int add (int i, int j) { return i+j; }
You will sometimes see functions such as add written in the "old style," as shown below: int add(i,j) int i; int j; { return i+j; } It is important to be able to read code written in the older style. There is no difference in the way it executes; it is just a different notation. You should use the "new style," (known as ANSI C) with the type declared as part of the parameter list, unless you know you will be shipping the code to someone who has access only to an "old style" (non-ANSI) compiler.
4. Return values returntype fn_name(1, parameterdef2,
)
{ localvariables functioncode } Let us look at an example to find the average of two integers: float findaverage(float a, float b) { float average; average=(a+b)/2; return(average); }
We would call the function as follows: main() { float a=5,b=15,result; result=findaverage(a,b); printf("average=%f\n",result); } Note: we can return only single value at a time. If you do not want to return a value you must use the return type void and miss out the return statement: void squares() { int loop; for (loop=1;loop<10;loop++); printf("%d\n",loop*loop); } main() { squares(); } Note: We must have () even for no parameters unlike some languages.
5. Nesting of function C permits nesting of functions freely. main can call function1, which calls function2, which calls function3, ………and so on. Example:
main() { int a,b,c; float ratio(); scanf(“%d %d %d”, &a, &b,&c); printf(“%f”\n”, ratio(a,b,c)); } float ratio(x,y,z) int x,y,z; { if(difference(y,z)) return(x/(y-z)); else return(0,0); } difference(p,q) int p,q; { if(p!=q) return 1; else return 0; }
6. Recursion When a called function in turns calls another function a process of ‘chaining’ occurs. Recursion is a special case of this process, where a function calls itself. A very example is: main()
{ printf(“This is an example of recursion\n”); main() } This execution will continue indefinitely. Another useful example is of factorial: factorial of n = n(n-1)(n-2)…….1 for example factorial of 4 = 4*3*2*1=24 factorial(int n) { int fact; if(n==1) return; else fact=n*factorial(n-1); return fact; }
7. Calling of function The call to a function in C simply entails referencing its name with the appropriate arguments. The C compiler checks for compatibility between the arguments in the calling sequence and the definition of the function. Arguments are always passed by value in C function calls. This means that local ``copies'' of the values of the arguments are passed to the routines. Any change made to the arguments internally in the function are made only to the local copies of the arguments. In order to change (or define) an argument in the argument list, this argument must be passed as an address, thereby forcing C to change the ``real'' argument in the calling routine.
As an example, consider exchanging two numbers between variables. First let's illustrate what happen if the variables are passed by value: #include < stdio.h> void exchange(int a, int b); void main() {
/* WRONG CODE */ int a, b; a = 5; b = 7; printf("From main: a = %d, b = %d\n", a, b); exchange(a, b); printf("Back in main: "); printf("a = %d, b = %d\n", a, b);
} void exchange(int a, int b) { int temp; temp = a; a = b; b = temp; printf(" From function exchange: "); printf("a = %d, b = %d\n", a, b); } Run this code and observe that a and b are NOT exchanged! Only the copies of the arguments are exchanged. The RIGHT way to do this is of course to use pointers:
#include < stdio.h> void exchange ( int *a, int *b ); void main() {
/* RIGHT CODE */ int a, b; a = 5; b = 7; printf("From main: a = %d, b = %d\n", a, b); exchange(&a, &b); printf("Back in main: "); printf("a = %d, b = %d\n", a, b);
} void exchange ( int *a, int *b ) { int temp; temp = *a; *a = *b; *b = temp; printf(" From function exchange: "); printf("a = %d, b = %d\n", *a, *b); } The rule of thumb here is that •
You use regular variables if the function does not change the values of those arguments
•
You MUST use pointers if the function changes the values of those arguments
If the function returns no value, You can call it with the following statement:
function_name(); You must include () in the call. If you do not, the function is not called, even though it will compile correctly on many systems.
8. Array as function argument Single dimensional arrays can be passed to functions as follows:float findaverage(int size,float list[]) { int i; float sum=0.0; for (i=0;i<size;i++) sum+=list[i]; return(sum/size); } Here the declaration float list[] tells C that list is an array of float. Note we do not specify the dimension of the array when it is a parameter of a function. Multi-dimensional arrays can be passed to functions as follows: void printtable(int xsize,int ysize, float table[][5]) { int x,y; for (x=0;x<xsize;x++) { for (y=0;y
Here float table[][5] tells C that table is an array of dimension N
5 of float.
Note we must specify the second (and subsequent) dimension of the array BUT not the first dimension.
9. Scope and life of variables(local and global variables) Local variables: These are the variables which are declared inside the functions. There scope is local to that function. They do not exist outside that function. Example: int sum(int a, int b) { int add; add=a+b; return add; } Here add is local variable of function sum We can’t access its value outside this function.
Global variables: These are the variables which are declared outside the functions. Scope is in all functions. Example int add; void sum(int a, int b) { add= a+b; }
Here add is global variable
10.Storage class specified-auto,extern,static,register A. int, char, float, double are the fundamental data types in C. B. Type modifiers include: short, long, unsigned, signed. Not all combinations of types and modifiers are available. C. Type qualifiers include the keywords: const and volatile. The const qualifier places the assigned variable in the constant data area of memory which makes the particular variable unmodifiable (technically it still is though). volatile
is used less frequently and tells the compiler that this value can be
modified outside the control of the program. D. Storage classes include: auto, extern, register, static. E. The auto keyword places the specified variable into the stack area of memory. This is usually implicit in most variable declarations, e.g. int i; F. The extern keyword makes the specified variable access the variable of the same name from some other file. This is very useful for sharing variables in modular programs. G. The register keyword suggests to the compiler to place the particular variable in the fast register memory located directly on the CPU. Most compilers these days (like gcc) are so smart that suggesting registers could actually make your program slower. H. The static keyword is useful for extending the lifetime of a particular variable. If you declare a static variable inside a function, the variable
remains even after the function call is long gone (the variable is placed in the alterable area of memory). The static keyword is overloaded. It is also used to declare variables to be private to a certain file only when declared with global variables. static can also be used with functions, making those functions visible only to the file itself. I. A string is NOT a type directly supported by C. You, therefore, cannot "assign" stuff into strings. A string is defined by ANSI as an array (or collection) of characters. We will go more in-depth with strings later...
Unit 5 1. Defining structure & declaration of structure variable A structure in C is a collection of items of different types. You can think of a structure as a "record" is in Pascal or a class in Java without methods. •
Structures, or structs, are very useful in creating data structures larger and more complex than the ones we have discussed so far. We will take a cursory look at some more complex ones in the next section. So how is a structure declared and initialized? Let's look at an example: struct student { char *first; char *last; char SSN[9]; float gpa; char **classes; }; struct student student_a, student_b; Another way to declare the same thing is: struct { char *first; char *last; char SSN[10]; float gpa; char **classes; } student_a, student_b;
As you can see, the tag immediately after struct is optional. But in the second case, if you wanted to declare another struct later, you couldn't. The "better" method of initializing structs is: struct student_t { char *first; char *last; char SSN[10]; float gpa; char **classes; } student, *pstudent; Now we have created a student_t student and a student_t pointer. The pointer allows us greater flexibility (e.g. Create lists of students). •
There is an easier way to define structs or you could "alias" types you create. For example:
typedef struct { char *first; char *last; char SSN[9]; float gpa; char **classes; } student; student student_a; Now we get rid of those silly struct tags. You can use typedef for nonstructs:
2. Accessing structure members But how do we access fields inside of the structure? C has a special operator for this called "member of" operator denoted by . (period). For example, to assign the SSN of student_a: strcpy(student_a.SSN, "111223333\0");
3. Nested structures Refer to unions Structures can be nested in the similar way.
4. Array of structures C also allows arrays of structures: typedef struct gun { char name[50]; int magazinesize; float calibre; } agun; agun arniesguns[1000]; This gives arniesguns a 1000 guns. This may be used in the following way: arniesguns[50].calibre=100; gives Arnie's gun number 50 a calibre of 100mm, and: itscalibre=arniesguns[0].calibre; assigns the calibre of Arnie's first gun to itscalibre.
5. Structure and Function C supports the passing of structure values as argument to functions. There are three methods by which the values of structure can be transferred from one fuction to other. Method1: To pass each member of the structure as an actual argument of the function call. The actual arguments are then treated independently like ordinary variables. Method 2: The second method involves passing copy of the entire structure to the called function. Since the function is working on a copy of the structure, any changes to structure members within the function are not reflected in the original structure. It is therefore necessary for the function to return the entire structure back to the calling function. Method 3: The third approach employs a concept called pointers to pass the structure as an argument. In this case, the address location of the structure is passed to the called function. The function can access indirectly the entire structure and work on it. Here we will discuss the second method: The general format is: function_name (structure_variable_name) The called function takes the following form data_type function_name ( st_name) struct_type st_name; { ---------------------------------------------
return expression; }
Note: a. The called function must be declared for its type, appropriate to the data type it is expected to return. For example, if it is returning a copy of entire structure, then it must be declared as struct with an appropriate tag name. b. The structure variable used as the actual argument and the corresponding formal argument in the called function must be of the same struct type. c. The return statement is necessary only when the function is returning some data. The expression many be any simple variable or structure variable or an expression using simple variable. d. When a function returns a structure, it must be assigned to a structure of identical type in the calling function. e. The called function must be declared in the calling function for its type, if it is placed after the calling function.
6. Union A union is a variable which may hold (at different times) objects of different sizes and types. C uses the union statement to create unions, for example: union number { short shortnumber; long longnumber; double floatnumber; } anumber
defines a union called number and an instance of it called anumber. number is a union tag and acts in the same way as a tag for a structure. Members can be accessed in the following way: printf("%ld\ n",anumber.longnumber); This clearly displays the value of longnumber. When the C compiler is allocating memory for unions it will always reserve enough room for the largest member (in the above example this is 8 bytes for the double). In order that the program can keep track of the type of union variable being used at a given time it is common to have a structure (with union embedded in it) and a variable which flags the union type: An example is: typedef struct { int maxpassengers; } jet; typedef struct { int liftcapacity; } helicopter; typedef struct { int maxpayload; } cargoplane; typedef union { jet jetu; helicopter helicopteru;
cargoplane cargoplaneu; } aircraft; typedef struct { aircrafttype kind; int speed; aircraft description; } an_aircraft; This example defines a base union aircraft which may either be jet, helicopter, or cargoplane. In the an_aircraft structure there is a kind member which indicates which structure is being held at the time. •
Unions are declared in the same fashion as structs, but have a fundamental difference. Only one item within the union can be used at any time, because the memory allocated for each item inside the union is in a shared memory location. Why you ask? An example first: struct conditions { float temp; union feels_like { float wind_chill; float heat_index; } } today;
As you know, wind_chill is only calculated when it is "cold" and heat_index when it is "hot". There is no need for both. So when you specify the temp in today, feels_like only has one value, either a float for wind_chill or a float for heat_index. •
Types inside of unions are unrestricted, you can even use structs within unions.