Академический Документы
Профессиональный Документы
Культура Документы
By:
Preface
The question you always might think before learning C language is that why should I learn this language? At present in the market, there are so many languages, using which you can meet most of the industry needs. For the past many years, the solution for the most of the raw needs of the industry has been C language? C is the heart of programming, one who learns this language can command over any language very easily. This book covers more than average discussions of C, It covers the features and functionality of the language in depth. Starting chapter helps the reader to grasp the basic and structure of the language, later chapter deals with the advance features of the language like pointers and file handling. In order to asses your learning the quiz section is appended at the end of each chapter. This assessment system is designed to evaluate the level of knowledge and skills as defined by learning objectives We have tried my best to make the book very useful for the students. Constructive, criticism, and suggestions for the improvement of book are most welcome It is pleasure to acknowledge my sincere gratitude to Prof. Dinesh Khurana (Amity International Business School), Amity University Uttar Pradesh for giving us an opportunity and motivation to write this book. Thanks to our parents who gave us shower of love and believed our ability. we would like to dedicate this work to our lovely daughters baby Verda and baby Vindhya. Finally, we thanks to the Almighty who helped us in disguise in each and every step
Index
Chapter No. Title Introduction to C Operators and Expressions Data Input/Output Functions Control Statements Functions Arrays Pointers Structures and Unions Data Files Key to End Chapter Quizzes Bibliography Page No. 1 15 37 48 64 88 106 126 138 150 152
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Chapter 1 Introduction to C
Contents: 1.1 Introduction 1.2 Data and Variables 1.2.1 Reserve words 1.2.2 Identifiers\ 1.3 Data Types 1.3.1 Integer Number Variables 1.3.2 Decimal Number Variables 1.3.3 Character Variables 1.4 Form of C Program
1.1 Introduction
C is considered as High Level Languages. It uses English type statements that are converted to machine statements which are executed by computers. C programs are simple text files containing program statements. As such, it is created using a text editor. This is called the source program. Once you have written the program, it must be compiled. The source program is compiled by a special program called a compiler, whose task is to convert the statements in the source code to either an intermediate format (called an object file), or an executable format which can be run on the computer. There are a number of free compilers available on the Internet. we briefly described the following stages in the development of a computer program:
(1) Define the problem. (2) Analyze the problem. (3) Develop an algorithm (a method) for solving the problem. (4) Write the computer program which implements the algorithm. (5) Test and debug (find the errors in) the program. (6) Document the program. (Explain how the program works and how to use it). (7) Maintain the program.
the data for an accounting program would include, among other things, expenses and income; the data for a program that teaches Spanish could be an English word that you type in response to a question. For a program to be run, it must be stored in the computers memory. When data is supplied to a program, that data is also stored in memory. Thus we think of memory as a place for holding programs and data. One of the nice things about programming in a high-level language (like C or Java) is that you dont have to worry about which memory locations are used to store your data. But how do we refer to an item of data, given that there may be many data items in memory? Think of memory as a set of boxes (or storage locations). Each box can hold one item of data, for example, one number. We can give a name to a box, and we will be able to refer to that box by the given name. In our example, we will need two boxes, one to hold the side of the square and one to hold the area. We will call these boxes s and a, respectively. If we wish, we can change the value in a box at any time; since the values can vary, s and a are called variable names, or simply variables. Thus a variable is a name associated with a particular memory location or, if you wish, it is a label for the memory location. We can speak of giving a variable a value, or setting a variable to a specific value, such as 1, for instance. Important points to remember are: a box can hold only one value at a time; if we put in a new value, the old one is lost; we must not assume that a box contains any value unless we specifically store a value in the box. In particular, we must not assume that the box contains 0. Variables are a common feature of computer programs. It is very difficult to imagine what programming would be like without them. In everyday life, we often use variables. For example, we speak of an address. Here, address is a variable whose value depends on the person under consideration. Other common variables are telephone number, name of school, subject, size of population, type of car, television model, etc. (What are some possible values of these variables?) A variable is a data name that may be used to store a data value. Variable may take different values at different times during execution.
1.2.2 Identifiers
The C programmer needs to make up names for things such as variables, function names and symbolic constants (see next section). A name that he makes up is called a user identifier. There are a few simple rules to follow in naming an identifier:
6
Ranges of data types: int -------- -32,768 to 32767 char ------ -128 to 127 float ------ 3.4e-38 to 3.4e+38 Size: int ----- 2 byte=16bit char --- 1 byte=8bit float --- 4 byte=32bit One of the confusing things about the C language is that the range of values and the amount of storage that each of these types takes is not defined. This is because in each case the 'natural' choice is made for each type of machine. You can call variables what you like, although it helps if you give them sensible names that give you a hint of what they're being used for - names like sum, total, average and so on. If you are translating a formula then use variable names that reflect the elements used in the formula. For example, 2 r (that should read as "2 pi r" but that depends upon how your browser has been set-up) would give local variables names of pi and r. Remember, C programmers tend to prefer short names! Note: all C's variables must begin with a letter or a "_" (underscore) character. 1.3.1 Integer Number Variables The first type of variable we need to know about is of class type int - short for integer. An int variable can store a value in the range -32768 to +32767. You can think of it as a largish positive or negative whole number: no fractional part is allowed. To declare an int you use the instruction: int variable name; For example: int a; declares that you want to create an int variable called a. To assign a value to our integer variable we would use the following C statement:
a=10;
The C programming language uses the "=" character for assignment. A statement of the form a=10; should be interpreted as take the numerical value 10 and store it in a memory location
8
will get mathematicians blowing fuses! This statement should be interpreted as take the current value stored in a memory location associated with the integer variable a; add the numerical value 10 to it and then replace this value in the memory location associated with a. 1.3.2 Decimal Number Variables As described above, an integer variable has no fractional part. Integer variables tend to be used for counting, whereas real numbers are used in arithmetic. C uses one of two keywords to declare a variable that is to be associated with a decimal number: float and double. They are each offer a different level of precision as outlined below. float A float, or floating point, number has about seven digits of precision and a range of about 1.E-36 to 1.E+36. A float takes four bytes to store. double A double, or double precision, number has about 13 digits of precision and a range of about 1.E303 to 1.E+303. A double takes eight bytes to store. For example: float total; double sum; To assign a numerical value to our floating point and double precision variables we would use the following C statement: total=0.0; sum=12.50; 1.3.3 Character Variables C only has a concept of numbers and characters. It very often comes as a surprise to some programmers who learnt a beginner's language such as BASIC that C has no understanding of strings but a string is only an array of characters and C does have a concept of arrays which we shall be meeting later in this course. To declare a variable of type character we use the keyword char. - A single character stored in one byte.For example: char c;
declares three integers: a, b and c. You have to declare all the variables that you want to use at the start of the program. Later you will discover that exactly where you declare a variable makes a difference, but for now you should put variable declarations after the opening curly bracket of the main program. Here is an example program that includes some of the concepts outlined above.
/* Program#int.c Another simple program using int and printf */ #include <stdio.h> main() { int a,b,average; a=10; b=6; average = ( a+b ) / 2 ; printf("Here "); printf("is "); printf("the "); printf("answer... "); printf("\n");
10
More On Initialising Variables You can assign an initial value to a variable when you declare it. For example:
int i=1;
sets the int variable to one as soon as it's created. This is just the same as:
int i; i=l;
but the compiler may be able to speed up the operation if you initialise the variable as part of its declaration. Don't assume that an uninitialised variable has a sensible value stored in it. Some C compilers store 0 in newly created numeric variables but nothing in the C language compels them to do so. The form of a C Program All C programs will consist of at least one function, but it is usual (when your experience grows) to write a C program that comprises several functions. The only function that has to be present is the function called main. For more advanced programs the main function will act as a controlling function calling other functions in their turn to do the dirty work! The main function is the first function that is called when your program executes. C makes use of only 32 keywords which combine with the formal syntax to the form the C programming language. Note that all keywords are written in lower case - C, like UNIX, uses upper and lowercase text to mean different things. If you are not sure what to use then always use lowercase text in writing your C programs. A keyword may not be used for any other purposes. For example, you cannot have a variable called auto. The layout of C Programs The general form of a C program is as follows (don't worry about what everything means at the moment - things will be explained later): pre-processor directives global declarations main() { local variables to function main ; statements associated with function main ; } f1()
11
Note the use of the bracket set () and {}. () are used in conjunction with function names whereas {} are used as to delimit the C statements that are associated with that function. Also note the semicolon - yes it is there, but you might have missed it! a semicolon (;) is used to terminate C statements. C is a free format language and long statements can be continued, without truncation, onto the next line. The semicolon informs the C compiler that the end of the statement has been reached. Free format also means that you can add as many spaces as you like to improve the look of your programs. A very common mistake made by everyone, who is new to the C programming language, is to miss off the semicolon. The C compiler will concatenate the various lines of the program together and then tries to understand them - which it will not be able to do. The error message produced by the compiler will relate to a line of you program which could be some distance from the initial mistake.
12
2.1 Introduction
Operators form expressions by joining individual constants, variables, and array. C includes a large number of operators which fall into different categories. In this lesson we will see how arithmetic operators, unary operators, relational and logical operators, assignment operators and the conditional operators are used to form expressions. The data items on which operators act upon are called operands. Some operators require two operands while others require only one operand. Most operators allow the individual operands to be expressions. A few operators permit only single variable as operand. Variables and constants can be used in conjunction with C operators to create more complex expressions. Table 2-1 presents the set of C operators.
13
Structure and union member selection Structure and union member selection Value of a Negative of a Reference to object at address a Address of a One's complement of a The value of a after increment The value of a before increment The value of a after decrement The value of a before decrement Size in bytes of object with type t1 Size in bytes of object having the type of expression e a plus b
a a a a a
+ * / %
b b b b b
>> <<
a >> b a << b
a a a a a a
1 if a > b; 0 otherwise 1 if a <= b; 0 otherwise 1 if a >= b; 0 otherwise 1 if a equal to b; 0 otherwise 1 if a not equal to b; 0 otherwise
14
Bitwise AND of a and b Bitwise OR of a and b Bitwise XOR (exclusive OR) of a and b Logical AND of a and b (yields 0 or 1) Logical OR of a and b (yields 0 or 1) Logical NOT of a (yields 0 or 1) Expression e1 if a is nonzero;
a && b a || b !a
?:
a ? e1 : e2
a minus b (assigned to a)
a = b a += b a -= b a *= b a /= b a %= b a >>= b a <<= b a &= b a |= b a ^= b e1,e2
a times b (assigned to a) a divided by b (assigned to a) Remainder of a/b (assigned to a) a, right-shifted b bits (assigned to a) a, left-shifted b bits (assigned to a) a AND b (assigned to a) a OR b (assigned to a) a XOR b (assigned to a) e2 (e1 evaluated first)
The C operators fall into the following categories: Postfix operators, which follow a single operand. Unary prefix operators, which precede a single operand. Binary operators, which take two operands and perform a variety of arithmetic and logical operations. The conditional operator (a ternary operator), which takes three operands and evaluates either the second or third expression, depending on the evaluation of the first expression. Assignment operators, which assign a value to a variable. The comma operator, which guarantees left-to-right evaluation of comma-separated expressions.
15
In an unparenthesized expression, operators of higher precedence are evaluated before those of lower precedence. Consider the following expression:
A+B*C
The identifiers B and C are multiplied first because the multiplication operator (*) has higher precedence than the addition operator (+). Category Postfix Unary Additive Shift Relational Equality Bitwise AND Bitwise XOR Bitwise OR Logical AND Logical OR Conditional Assignment Comma Operator () [] -> . ++ - + - ! ~ ++ - - (type) * & sizeof +<< >> < <= > >= == != & ^ | && || ?: , Associativity Left to right Right to left 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
16
Multiplicative * / %
In a more complicated example, associativity rules specify that b ? c : d is evaluated first in the following example:
a ? b ? c : d : e;
The associativity of the conditional operator is right-to-left on the line. The assignment operator also associates right-to-left; for example:
int x = 0 , y = 5, z = 3; x = y = z; /* x has the value 3, not 5 */
Other operators associate left-to-right; for example, the binary addition, subtraction, multiplication, and division operators all have left-to-right associativity. Associativity applies to each row of operators in Table 2-2 and is right-to-left for some rows and left-to-right for others. The kind of associativity determines the order in which operators from the same row are evaluated in an unparenthesized expression. Consider the following expression:
A*B%C
This expression is evaluated as follows because the multiplicative operators (*, /, %) are evaluated from left to right:
(A*B)%C
Parentheses can always be used to control precedence and associativity within an expression
17
Meaning
Greater than Greater than or equal to Less than Less than or equal to Equal Not equal logical AND logical OR logical NOT
|| !
The idea of true and false underlies the concepts of relational and logical operators. In C, true is any value other than zero and false is zero. All relational and logical operations produce a result of either 1 or 0.
18
19
will display the text "a=3 a+1=4." If the increment operator comes after the named variable, then the value of the statement is calculated after the increment occurs. So the statement example 1,
a= 3; printf("a=%d a+1=%d\n", a, a++);
would display "a=3 a+1=3" but would finish with a set to 4. The decrement operator "--" is used in the same fashion as the increment operator. example 2,
if (c == '\n') ++nl;
20
sets x to 5, but
x = ++n;
sets x to 6. In both cases, n becomes 6. The increment and decrement operators can only be applied to variables; an expression like (i+j)++ is illegal. In a context where no value is wanted, just the incrementing effect, as in
if (c == '\n') nl++;
prefix and postfix are the same. But there are situations where one or the other is specifically called for. For instance, consider the function squeeze(s,c), which removes all occurrences of the character c from the string s.
/* squeeze: delete all c from s */ void squeeze(char s[], int c) { int i, j; for (i = j = 0; s[i] != '\0'; i++) if (s[i] != c) s[j++] = s[i]; s[j] = '\0'; }
Each time a non-c occurs, it is copied into the current j position, and only then is j incremented to be ready for the next character. This is exactly equivalent to
if (s[i] != c) { s[j] = s[i]; j++; }
As another example, consider the standard function strcat(s,t), which concatenates the string t to the end of string s. strcat assumes that there is enough space in s to hold the combination. As we have written it, strcat returns no value; the standard library version returns a pointer to the resulting string. /* strcat: concatenate t to end of s; s must be big enough */
void strcat(char s[], char t[]) { int i, j; i = j = 0; while (s[i] != '\0') /* find end of s */ i++; while ((s[i++] = t[j++]) != '\0') /* copy t */
21
As each member is copied from t to s, the postfix ++ is applied to both i and j to make sure that they are in position for the next pass through the loop. Exercise. Write an alternative version of squeeze(s1,s2) that deletes each character in s1 that matches any character in the string s2. Exercise. Write the function any(s1,s2), which returns the first location in a string s1 where any character from the string s2 occurs, or -1 if s1 contains no characters from s2. (The standard library function strpbrk does the same job but returns a pointer to the location.)
22
Declaring the argument x to be an unsigned ensures that when it is right-shifted, vacated bits will be filled with zeros, not sign bits, regardless of the machine the program is run on. Quite apart from conciseness, assignment operators have the advantage that they correspond better to the way people think. We say ``add 2 to i'' or ``increment i by 2'', not ``take i, add 2, then put the result back in i''. Thus the expression i += 2 is preferable to i = i+2. In addition, for a complicated expression like yyval[yypv[p3+p4] + yypv[p1]] += 2 the assignment operator makes the code easier to understand, since the reader doesn't have to check painstakingly that two long expressions are indeed the same, or to wonder why they're not. And an assignment operator may even help a compiler to produce efficient code. We have already seen that the assignment statement has a value and can occur in expressions; the most common example is while ((c = getchar()) != EOF) ... The other assignment operators (+=, -=, etc.) can also occur in expressions, although this is less frequent. In all such expressions, the type of an assignment expression is the type of its left operand, and the value is the value after the assignment. Exercise In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x. Explain why. Use this observation to write a faster version of bitcount.
Since C was designed to take the place of assembly language for most programming tasks, it needed to be able to support assembler-like operations. Bitwise operations refer to testing, setting or shifting the actual bits in a byte or word (byte and word corresponding to the types char and int and their variants). C provides six operators for bit manipulation; these may only be applied to integral operands, that is, char, short, int, and long, whether signed or unsigned. & bitwise AND
24
The bitwise AND operator & is often used to mask off some set of bits, for example n = n & 0177; sets to zero all but the low-order 7 bits of n. The bitwise OR operator | is used to turn bits on: x = x | SET_ON; sets to one in x the bits that are set to one in SET_ON. The bitwise exclusive OR operator ^ sets a one in each bit position where its operands have different bits, and zero where they are the same. One must distinguish the bitwise operators & and | from the logical operators && and ||, which imply left-to-right evaluation of a truth value. For example, if x is 1 and y is 2, then x & y is zero while x && y is one. The shift operators << and >> perform left and right shifts of their left operand by the number of bit positions given by the right operand, which must be non-negative. Thus x << 2 shifts the value of x by two positions, filling vacated bits with zero; this is equivalent to multiplication by 4. Right shifting an unsigned quantity always fits the vacated bits with zero. Right shifting a signed quantity will fill with bit signs (``arithmetic shift'') on some machines and with 0-bits (``logical shift'') on others. The unary operator ~ yields the one's complement of an integer; that is, it converts each 1-bit into a 0-bit and vice versa. For example x = x & ~077 sets the last six bits of x to zero. Note that x & ~077 is independent of word length, and is thus preferable to, for example, x & 0177700, which assumes that x is a 16-bit quantity. The portable form involves no extra cost, since ~077 is a constant expression that can be evaluated at compile time.
25
Bitwise ANDing is frequently used for "masking"operations, i.e., the operator may be used to set specific bits to zero. Any bit that is 0 in either operand causes the corresponding bit to be set to 0. For example, the following resets a parity bit to 0: return (ch & 127); Note that the number 127 has bit 8 set to 0. Here is what happens: parity bit set parity bit unset
1 0 0 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1
0 0 0 1 0 1 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1
ch 127 result
26
Exclusive OR (^) Exclusive OR (XOR) sets a bit only if the bits being compared are different. One interesting property of XOR is that any value XOR'd with itself produces 0. This is useful in assembly programming. Swapping Values. An interesting application of XOR is that it can be used to exchange two values without the need for an extra memory location, e.g.: a ^= b; b ^= a; a ^= b; Shift Operators (<< and >>) Shift operators move all bits left or right as specified. As bits are shifted off one end, zeroes are brought in at the other. A shift is not a rotate; the bits shifted off one end are lost. Left shifting has the effect of multiplying the shifted value by two. For right shifts, what is shifted in on the left depends on the sign of the value being shifted and also on how the operation is implemented on the particular machine. If the sign is 0 (positive), then zeroes will be shifted in. If the sign is 1 (negative), on some machines 1s will be shifted in and on others, 0s. The former is known as an arithmetic right shift; the latter is known as a logical right shift. C does not guarantee a defined result if a value is shifted by an amount greater or less than the number of bits in the data item.
27
The ? Operator The ternary operator ? replaces certain statements of the if-then-else form. In the following: y = x >10 ? 100 : 200 the first expression is evaluated. If it evaluates to true, y is made equal to 100. If it evaluates to false, y is made equal to 200.
The & and * Operators Preamble. A pointer is the memory address of a variable. A pointer variable is a variable specifically declared to hold a pointer. Pointers: provide a fast means of referencing array elements, allow C functions to modify their calling parameters, and support linked lists and other dynamic data structures. A pointer is of sufficient size to hold an address as defined by the architecture of the computer. Pointer Operators. The following operators are used to manipulate pointers:
The & Operator The & operator returns the memory address of its operand. For example: m = &count; places the address of count into m. & can be thought of as "address of".
28
The Compile-Time Operator sizeof sizeof is a unary compile time operator which returns the length, in bytes, of the variable or parenthesized type specifier that precedes it. Usage is illustrated in the following: printf("%f", sizeof f); printf("%d", sizeof(int));
The Comma Operator The comma operator may be used to string together several expressions. For example, in: x - (y = 3, y + 1); the left side of the comma operator is evaluated as void, which means that y is first assigned the value 3 and then x is assigned the value 4.
The . and -> Operators The . and -> operators reference individual elements in structures and unions. The . operator is used when working with the actual structure or union, e.g.: employee.wage = 123.23; The -> is used when working with a pointer to the structure or union, e.g.: emp_ptr->wage = 123.23;
29
An expression can be forced to be of a particular type by using a cast. Casts are often considered to be operators. As an operator, casts are unary, and have the same precedence as other unary operators. An example of a cast which ensures that an expression evaluates to type float is as follows: x = (float) x / 2; In the following example, a fractional number is truncated to a whole number: double x = 3.141592654; double y; y = (short) x; // resulting value of y is 3.0 In the following example, casting is used to round to the nearest integer: double x, y; x = 4.67; y = (short) (x + 0.5); // resulting value of y is 5.0 x = 4.45; y = (short) (x +.05); // resulting value of y is 4.0
2.8.2 C Shorthand
C has a special shorthand which simplifies the coding of certain assignments. For example: x = x + 10; can be written as x += 10; x = x * 10; can be written as x *= 10; Some further examples using the bitwise operators are as follows:
30
Usage
a >>= b a shifted right by b bits a <<= b a &= b a ^= b a |= b a shifted left by b bits a ANDed with b a exclusive ORed with b a ORed with b
The assignment of a value to many variables is possible using multiple assignment, eg: x = y = z = 0;
3.1 Introduction
One of the reasons that has prevented many programming languages from becoming widely used for real programming is their poor support for I/O, a subject which has never seemed to excite language designers. C has avoided this problem, oddly enough, by having no I/O at all! The C language approach has always been to do I/O using library functions, which ensures that system designers can provide tailored I/O instead of being forced to change the language itself. As C has evolved a library package known as the Standard I/O Library or stdio, has evolved with it and has proved to be both flexible and portable. This package has now become part of the Standard. The old stdio package relied heavily on the UNIX model of file access, in particular the assumption that there is no distinction between unstructured binary files and files containing readable text. Many operating systems do maintain a distinction between the two, and to ensure that C programs can be written portably to run on both types of file model, the stdio package has been modified. There are changes in this area which affect many existing programs, although strenuous efforts were taken to limit the amount of damage.
32
2. putchar
3.3.1 getchar
getchar always returns the next character of keyboard input as an int. The EOF (end of file) is returned,if there is an error . It is usual to compare this value against EOF before using it. So error conditions will not be handled correctly,if the return value is stored in a char, it will never be equal to EOF. The following program is used to count the number of characters read until an EOF is encountered. EOF can be generated by typing Control - d. #include main() { int ch, i = 0; while((ch = getchar()) != EOF) i ++; printf(%d\n, i); }
3.3.2 putchar
The putchar() function writes ch to STDOUT. The code putchar( ch );
33
The return value of putchar() is the written character, or EOF if there is an error putchar puts its character argument on the standard output (usually the screen). The following example program converts any typed input into capital letters.It applies the function toupper from the character conversion library ctype.h to each character in turn to do this.
#include /* For definition of toupper */ #include /* For definition of getchar, putchar, EOF */ main() { int ch; while((ch = getchar()) != EOF) putchar(toupper(ch)); }
3.4.1 printf
34
The %s means, "insert the first argument, a string, right here." The %d indicates that the second argument (an integer) should be placed there. There are different %-codes for different variable types, as well as options to limit the length of the variables and whatnot.
Code ---%c %d %i %e %E %f %g %G %o %s %u %x
Format -----character signed integers signed integers scientific notation, with a lowercase "e" scientific notation, with a uppercase "E" floating point use %e or %f, whichever is shorter use %E or %f, whichever is shorter octal a string of characters unsigned integer unsigned hexadecimal, with lowercase letters
35
%n the argument shall be a pointer to an integer into which is placed the number of characters written so far %% a '%' sign
An integer placed between a % sign and the format command acts as a minimum field width specifier, and pads the output with spaces or zeros to make it long enough. If you want to pad with zeros, place a zero before the minimum field width specifier. You can use a precision modifier, which has different meanings depending on the format code being used. With %e, %E, and %f, the precision modifier lets you specify the number of decimal places desired. For example, %12.6f will display a floating number at least 12 digits wide, with six decimal places. With %g and %G, the precision modifier determines the maximum number of significant digits displayed. With %s, the precision modifer simply acts as a maximum field length, to complement the minimum field length that precedes the period.
All of printf()'s output is right-justified, unless you place a minus sign right after the % sign. For example,
%-12.4f
will display a floating point number with a minimum of 12 characters, 4 decimal places, and left justified. You may modify the %d, %i, %o, %u, and %x type specifiers with the letter l and the letter h to specify long and short data types (e.g. %hd means a short integer). The %e, %f, and %g type specifiers can have the letter l before them to indicate that a double follows. The %g, %f, and %e type specifiers can be preceded with the character '#' to ensure that the decimal point will be present, even if there are no decimal digits. The use of the '#' character with the %x type
36
a 0 prefix.
You can also include constant escape sequences in the output string.The return value of printf() is the number of characters printed, or a negative number if an error occurred. Example: char name[20] = "Bob"; int age = 21; printf( "Hello %s, you are %d years old\n", name, age ); OUTPUT: Hello Bob, you are 21 years old
3.4.1 scanf
To grab things from input,scanf() is used. Beware though; scanf isnt greatest function that C has to offer. Some people brush off the scanf as a broken function that shouldnt be used often. The prototype for scanf is: int scanf( const char *format, );
To read of data from the keyboard scanf allows formatted. Like printf it has a control string, followed by the list of items to be read. However scanf wants to know the address of items to be read, since it is a function which will change that value. Therefore the names of variables are preceded by the & sign. Character strings are an exception to this. Since a string is already a character pointer, we give the names of the string variables unmodified by a leading &. Control string entries which match values to be read are preceded by the percentage sign in a similar way to their printf equivalent. Looks similar to printf, but doesnt completely behave like the printf does. Take the example:
scanf(%d, x);
37
int x, args; for ( ; ; ) { printf(Enter an integer bub: ); if (( args = scanf(%d, &x)) == 0) { printf(Error: not an integer\n); continue; } else { if (args == 1) printf(Read in %d\n, x); else break; } }
3.5.1 puts
The function puts() writes str to STDOUT. puts() returns non-negative on success, or EOF on failure. Explanation: This function, puts, will output the string pointed to by astring. It will then add a newline character. This is built in to the function. It returns a nonnegative integer if it was successful. It returns EOF if there was an error Syntax: #include <stdio.h>
38
//Example outputs "Hello, World" with a newline #include <cstdio> using namespace std; int main() { puts("Hello World"); }
3.5.2 gets
The gets() function reads characters from STDIN and loads them into str, until a newline or EOF is reached. The newline character is translated into a null termination. The return value of gets() is the read-in string, or NULL if there is an error. Syntax: #include <stdio.h>
Looping 4.1.2.1 4.1.2.2 4.1.2.3 For loop While do while Break - continue
39
Preliminaries
C provides two styles of flow control: Branching Looping These branching and looping in C can be achieved with the help of following keywords If-Else While For Break / Continue Switch-Case We will discuss each of these one by one to understand their syntax and their application in programming language
4.1.1Branching
Branching is deciding what actions to take and looping is deciding how many times to take a certain action.Branching is so called because the program chooses to follow one branch or another
4.1.1.1 if statement
This is the simplest form of the branching statements. It takes an expression in parenthesis and an statement or block of statements. if the expression is true then the statement or block of statements gets executed otherwise these statements are skipped. Programs need to make decisions. Should this statement be executed or that one? Are these parameters correct and so on. This is done using the if statement. The syntax is pretty easy.
if ( conditional expression ) statement; This can be extended with else.
40
If-Else
The if else statement is used to make decisions. The syntax is: if (expression) statement-1 else statement-2 expression is evaluated; if it is not equal to zero (e.g., logic true), then statement-1 is executed. The else clause is optional. If the if part of the statement did not execute, and the else is present, then statement-2 executes.
if ( conditional expression ) statement1; else statement2; So if the expression is true, statement1 is executed, otherwise statement2 is executed.
NOTE: Expression will be assumed to be true if its evaulated values is non-zero. if , if-else , if-elseif-else statements take the following form: if (expression) statement; or if (expression) { Block of statements; } or if (expression) { Block of statements; } else { Block of statements; }
41
Be
Careful
that
you
don't
write
when
you
mean
==
When there are many choices, a switch statement may be better than an if. The syntax of a switch statement is: switch ( expression) { case a: statement1; break; case b: statement2; case d: statement3; break; default: statement4; } Notes: Expression should be an int or a char type. e.g. switch (character) { case 'B': 43
4.1.2 Looping
Loops provide a way to repeat commands and control how many times they are repeated. C provides a number of looping way.
44
Note This is the one place where there is no need to put brackets around a conditional expression. This executes the initial statement once, then while the conditional expression is true, the loop statement and the main statement are executed. All three sections are optional so the following is allowed. It is an infinite loop as the conditional expression is always true if absent.
for ( ;; ) mainstatement; This will keep executing main statement for ever. The conditional expression is the most important of the three sections. As long as it is true the main statement is always run. Once the expression is false, the loop exits. for (index=1 ;index <= 10;index++ ) printf("The value of i is %i\n\r",i) ; This outputs ten lines The value of i is 1 The value of i is 2 .. The value of i is 10
45
while
statement is evaluated. Then the expression is evaluated again, and the same check is performed. The loop exits when expression becomes zero. One can easily create an infinite loop in C using the while statement: while (1) statement
There are two loop statements that use while.
46
Do While
do ... while is just like a while loop except that the test condition is checked at the end of the loop rather than the start. This has the effect that the content of the loop are always executed at least once.Less popular than the while statement is the do while statement. This puts the expression at the end.
47
A while loop might never execute a statement if the expression is false but a do while will always execute the statement at least once. Here is an example of a do while loop. int count =0; int index =9; do if (value[ index] ==999) count++; index--; while ( index >= 0) ; Break and Continue work equally well with for, while and do while loops. Note For and while can be used for same purpose
for loop is similar to while, it's just written differently. for statements are often used to proccess lists such a range of numbers: The syntax of a for loop is the following: for (expr-1;expr-2;expr-3) statement
48
Break
Use of the break provides an early exit from a while or a for loop. If a condition is met in switch case then execution continues on into the next case clause also if it is not explicitly specified that the execution should exit the switch statement. This is achieved by using break keyword.
Here's an example:
49
Continue
This does the opposite of break; Instead of terminating the loop, it immediately loops again, skipping the rest of the code So lets sum that integer array again, but this time we'll leave out elements with an index of 4 and 5. int value =0; for (index=0 ;index < 10;index++ ) { if (index==4 || index==5) continue; value += numbers[index];
50
for( i = 0; i <= j; i ++ ) { if( i == 5 ) { continue; } printf("Hello %d\n", i ); } } This will produce following output: Hello 0 Hello 1 Hello 2 Hello 3 Hello 4
51
52
Chapter 5 Functions
Contents:
5.1 What is a function? 5.2 Structure of the function 5.2.1 5.2.2 5.2.3 function header function body function prototype
5.3 Need of function 5.4 Parts of function 5.5 Types of function 5.6 Categories of function 5.7 Call by value 5.8 Call by reference 5.9 Recursive function
//holds the answer that will be returned //calculate the sum //return the answer
Function Body What ever is written with in { } in the above example is the body of the function. Function Prototypes The prototype of a function provides the basic information about a function which tells the compiler that the function is used correctly or not. It contains the same information as the function header contains. The prototype of the function in the above example would be like
54
Declared : it is like registering the function to make itself known for use Defined : related with actual working or functionality of fuinction
Function Declaration
Just as you cant use a variable without first telling the compler what it is, you also cant use a funciotns without teling the compiler about it, There are two ways to do this . The approach we show here ist o declare the funtion before it is called. The other approach is to define it before its called. ; well examine that next.) in the Table program, the functions starline() is declared in the line. Void starline ( ); The declaration tells the compiler that at some later point we plan to present a function called starline. The keyword void specifies that the function has no return value, and the empty parentheses indicate that it takes no arguments. Notice that the functions declarations is terminated with a semicolon It is a complete statement in itself. Function declarations are also called prototypes, since they provide a model or blueprint for the function. They tell the compiler, a function that looks like this is coming up later in the program, so its all right if you see references to it before you see the function itself.
56
Function definition
[ data type] function name (argument list) argument declaration; { local variable declarations; statements; [return expression] } Example : mul(a,b) int a,b; { int y; y=a+b; return y; } When the value of y which is the addition of the values of a and b. the last two statements ie, y=a+b; can be combined as
57
C support the use of library functions and use defined functions. The library functions are used to carry out a number of commonly used operations or calculations. The user-defined functions are written by the programmer to carry out various individual tasks The following point must be noted about functions (i) (ii) C program is a collection of one or more functions A function gets called when the function name is followed by a semicolon for e.g. main ( ) { message ( ); } 3. Function is defined when function name is followed by a pair of braces in which one or more statements may be present for e.g. message ( ) { statement 1;
58
message ( ); } message ( ) { printf ( \n Hello); main ( ); } 5. A function can be called any number of times for eg. main () { message ( ); message ( ); }
59
62
Let us consider the following program /* Program to illustrate a function with no argument and no return values*/ #include main() { staetemtn1(); starline(); statement2(); starline(); } /*function to print a message*/ statement1() { printf(\n Sample subprogram output);
63
The nature of data communication between the calling function and the arguments to the called function and the called function does not return any values to the calling function this shown in example below: Consider the following: Function calls containing appropriate arguments. For example the function call value (500,0.12,5) Would send the values 500,0.12 and 5 to the function value (p, r, n) and assign values 500 to p, 0.12 to r and 5 to n. the values 500,0.12 and 5 are the actual arguments which become the values of the formal arguments inside the called function. Both the arguments actual and formal should
64
main() { function1(a1,a2,a3an) } function1(f1,f2,f3.fn); { function } here a1,a2,a3 are actual arguments and f1,f2,f3 are formal arguments. The no of formal arguments and actual arguments must be matching to each other suppose if actual arguments are more than the formal arguments, the extra actual arguments are discarded. If the number of actual arguments are less than the formal arguments then the unmatched formal arguments are initialized to some garbage values. In both cases no error message will be generated. The formal arguments may be valid variable names, the actual arguments may be variable names expressions or constants. The values 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 actual arguments is passed to the called function. What occurs inside the functions will have no effect on the variables used in the actual argument list. Let us consider the following program /*Program to find the largest of two numbers using function*/ #include main() { int a,b;
65
body;
The function of the type Arguments with return values will send arguments from the calling function to the called function and expects the result to be returned back from the called function back to the calling function. To assure a high degree of portability between programs a function should generally be coded without involving any input output operations. For example different programs may require different output formats for displaying the results. Theses shortcomings can be overcome by handing over the result of a function to its calling function where the returned value can be used as required by the program. In the above type of function the following steps are carried out: 1. The function call transfers the controls along with copies of the values of the actual arguments of the particular function where the formal arguments are creates and assigned memory space and are given the values of the actual arguments.
66
A C function returns a value of type int as the default data type when no other type is specified explicitly. For example if function does all the calculations by using float values and if the return statement such as return (sum); returns only the integer part of the sum. This is since we have not specified any return type for the sum. There is the necessity in some cases it is important to receive float or character or double data type. To enable a calling function to receive a noninteger value from a called function we can do the two things: 1. The explicit type specifier corresponding to the data type required must be mentioned in the function header. The general form of the function definition is
Type_specifier function_name(argument list) Argument declaration; { function statement; } The type specifier tells the compiler, the type of data the function is to return. 2. The called function must be declared at the start of the body in the calling function, like any other variable. This is to tell the calling function the type of data the function is actually returning. The program given below illustrates the transfer of a floating-point value between functions done in a multiple function program.
67
The functions that do not return any values can be explicitly defined as void. This prevents any accidental use of these functions in expressions.
double power(double val, unsigned pow) { if(pow == 0) /* pow(x, 0) returns 1 */ return(1.0); else return(power(val, pow - 1) * val); } Notice that each of these definitions incorporates a test. Where an input value gives a trivial result, it is returned directly, otherwise the function calls itself, passing a changed version of the input values. Care must be taken to define functions which will not call themselves indefinitely, otherwise your program will never finish. The definition of fib is interesting, because it calls itself twice when recursion is used. Consider the effect on program performance of such a function calculating the fibonacci function of a moderate size number.
71
If such a function is to be called many times, it is likely to have an adverse effect on program performance. Don't be frightened by the apparent complexity of recursion. Recursive functions are sometimes the simplest answer to a calculation. However there is always an alternative nonrecursive solution available too. This will normally involve the use of a loop, and may lack the elegance of the recursive solution. As the definition specifies, there are two types of recursive functions. Consider a function which calls itself: we call this type of recursion immediate recursion. One can view this mathematically in a directed call graph. A -- -| ^ | | | |---- | void A() { A(); return; } A() is a recursive function since it directly calls itself. The second part of the defintion refers to a cycle (or potential cycle if we use conditional statements) which involves other functions. Consider the following directed call graph
72
73
Chapter 6 Arrays
Contents:
6.1 Introduction 6.2 Need of an array 6.3 Declaration of Arrays 6.4 Initialization of an arrays 6.5 More operations on array 6.5.1 6.5.2 6.5.3 Create an array Printing an array Copying an array
6.6 Multidimensional Array 6.6.1 6.6.2 initialization of multidimensional array more on multidimensional array
6.1 Introduction
The C language provides a capability that enables the user to define a set of ordered data items known as an array. Alternatively, array is a collection of homogeneous element, ,homogeneous means elements of same data type .Suppose we had a set of grades that we wished to read into the computer and suppose we wished to perform some operations on these grades, we will quickly realize that we cannot perform such an operation until each and every grade has been entered since it would be quite a tedious task to declare each and every student grade as a variable especially since there may be a very large number. In C we can define variable called grades, which represents not a single value of grade but a entire set of grades. Each element of the set can then be referenced by means of a number called as index number or subscript.
74
6.3
Declaration of arrays
Like any other variable arrays must be declared before they are used. The general form of declaration is: type variable-name[50]; The type specifies the type of the elements 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 ex: float height[50]; Declares the height to be an array containing 50 real elements. Any subscripts 0 to 49 are valid. In C the array elements index or subscript begins with number zero. So height [0] refers to the first element of the array. (For this reason, it is easier to think of it as referring to element number zero, rather than as referring to the first element). As individual array element can be used anywhere that a normal variable with a statement such as G = grade [50]; The statement assigns the value stored in the 50th index of the array to the variable g. More generally if I is declared to be an integer variable, then the statement g=grades [I]; Will take the value contained in the element number I of the grades array to assign it to g. so if I were equal to 7 when the above statement is executed, then the value of grades [7] would get assigned to g. A value stored into an element in the array simply by specifying the array element on the left hand side of the equals sign. In the statement grades [100]=95;
75
values[1]
values[2]
values[3]
76
values[5]
values[6]
values[7]
values[8]
values[9]
6.4
Initialization of arrays
We can initialize the elements in the array in the same way as the ordinary variables when they are declared. The general form of initialization off arrays is: type array_name[size]={list of values}; The values in the list care separated by commas, for example the statement int number[3]={0,0,0}; Will declare the array size as a array of size 3 and will assign zero to each element if the number of values in the list is less than the number of elements, then only that many elements are initialized. The remaining elements will be set to zero automatically. In the declaration of an array the size may be omitted, in such cases the compiler allocates enough space for all initialized elements. For example the statement int counter[]={1,1,1,1}; Will declare the array to contain four elements with initial values 1. this approach works fine as long as we initialize every element in the array. The initialization of arrays in c suffers two draw backs 1.There is no convenient way to initialize only selected elements. 2. There is no shortcut method to initialize large number of elements.
77
78
80
Since the only difference between each of the short's in the arrays is their index, a loop and a counter can be used to more easily copy all of the elements. The same technique is used to shorten the code that prints the array to the screen. Even though arrays give us some convenience when managing many variables of the same type, there is little difference between an array and variables declared individually. There is no single statement to copy an array, there is no single statement to print an array. If we want to perform any action on an array, we must repeatedly perform that action on each element in the array.
83
85
void set_value(int m_array[][COLS]) { int row, col; for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) { m_array[row][col] = 1; } } }
88
Chapter 7 Pointers
Contents: 7.1 Introduction 7.2 Pointer types and Arrays 7.3 Pointers and Strings 7.4 Pointers to Arrays 7.5 Dynamic Allocation of Memory
7.1 introduction
One of those things beginners in C find difficult is the concept of pointers. The purpose of this chapter is to provide an introduction to pointers and their use to these beginners. I have found that often the main reason beginners have a problem with pointers is that they have a weak or minimal feeling for variables, (as they are used in C). Thus we start with a discussion of C variables in general.A variable in a program is something with a name, the value of which can vary. The way the compiler and linker handles this is that it assigns a specific block of memory within the computer to hold the value of that variable. The size of that block depends on the range over which the variable is allowed to vary. For example, on 32 bit PC's the size of an integer variable is 4 bytes. On older 16 bit PCs integers were 2 bytes. In C the size of a variable type such as an integer need not be the same on all types of machines. Further more there is more than one type of integer variable in C. We have integers, long integers and short integers which you can read up on in any basic text on C. This document assumes the use of a 32 bit system with 4 byte integers. If you want to know the size of the various types of integers on your system, running the following code will give you that information. #include <stdio.h>
89
On seeing the "int" part of this statement the compiler sets aside 4 bytes of memory (on a PC) to hold the value of the integer. It also sets up a symbol table. In that table it adds the symbol k and the relative address in memory where those 4 bytes were set aside. Thus, later if we write:
k = 2;
we expect that, at run time when this statement is executed, the value 2 will be placed in that memory location reserved for the storage of the value of k. In C we refer to a variable such as the integer k as an "object". In a sense there are two "values" associated with the object k. One is the value of the integer stored there (2 in the above example) and the other the "value" of the memory location, i.e., the address of k. Some texts refer to these two values with the nomenclature rvalue (right value, pronounced "are value") and lvalue (left value, pronounced "el value") respectively. In some languages, the lvalue is the value permitted on the left side of the assignment operator '=' (i.e. the address where the result of evaluation of the right side ends up). The rvalue is that which is on the right side of the assignment statement, the 2 above. Rvalues cannot be used on the left side of the assignment statement. Thus: 2 = k; is illegal. Actually, the above definition of "lvalue" is somewhat modified for C. According to K&R II "An object is a named region of storage; an lvalue is an expression referring to an object."
90
In the above, the compiler interprets the j in line 1 as the address of the variable j (its lvalue) and creates code to copy the value 7 to that address. In line 2, however, the j is interpreted as its rvalue (since it is on the right hand side of the assignment operator '='). That is, here the j refers to the value stored at the memory location set aside for j, in this case 7. So, the 7 is copied to the address designated by the lvalue of k. In all of these examples, we are using 4 byte integers so all copying of rvalues from one storage location to the other is done by copying 4 bytes. Had we been using two byte integers, we would be copying 2 bytes. Now, let's say that we have a reason for wanting a variable designed to hold an lvalue (an address). The size required to hold such a value depends on the system. On older desk top computers with 64K of memory total, the address of any point in memory can be contained in 2 bytes. Computers with more memory would require more bytes to hold an address. The actual size required is not too important so long as we have a way of informing the compiler that what we want to store is an address. Such a variable is called a pointer variable (for reasons which hopefully will become clearer a little later). In C when we define a pointer variable we do so by preceding its name with an asterisk. In C we also give our pointer a type which, in this case, refers to the type of data stored at the address we will be storing in our pointer. For example, consider the variable declaration:
int *ptr;
ptr is the name of our variable (just as k was the name of our integer variable). The '*' informs the compiler that we want a pointer variable, i.e. to set aside however many bytes is required to store an address in memory. The int says that we intend to use our pointer variable to store the
91
92
And then we could print out our array either using the array notation or by dereferencing our pointer. The following code illustrates this:
94
int my_array[] = {1,23,17,4,-5,100}; int *ptr; int main(void) { int i; ptr = &my_array[0]; printf("\n\n"); for (i = 0; i < 6; i++) { printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */ printf("ptr + %d = %d\n",i, *(ptr + i)); } return 0; } Compile and run the above program and carefully note lines A and B and that the program prints out the same values in either case. Also observe how we dereferenced our pointer in line B, i.e. we first added i to it and then dereferenced the new pointer. Change line B to read: printf("ptr + %d = %d\n",i, *ptr++); and run it again... then change it to: printf("ptr + %d = %d\n",i, *(++ptr)); and try once more. Each time try and predict the outcome and carefully look at the actual outcome. In C, the standard states that wherever we might use &var_name[0] we can replace that with var_name, thus in our code where we wrote: ptr = &my_array[0]; we can write:
95
/*<-- B */
it simply uses this address as a constant in the code segment and there is no referencing of the data segment beyond that.
97
When the double quotes are used, instead of the single quotes as was done in the previous #include <stdio.h>
char strA[80] = "A string to be used for demonstration purposes"; char strB[80];
int main(void) { char *pA; char *pB; /* a pointer to type character */ /* another pointer to type character */
puts(strA); /* show string A */ pA = strA; puts(pA); /* point pA at string A */ /* show what pA is pointing to */
98
while(*pA != '\0') /* line A (see text) */ { *pB++ = *pA++; /* line B (see text) */ } *pB = '\0'; puts(strB); return 0; } In the above we start out by defining two character arrays of 80 characters each. Since these are globally defined, they are initialized to all '\0's first. Then, strA has the first 42 characters initialized to the string in quotes. Now, moving into the code, we declare two character pointers and show the string on the screen. We then "point" the pointer pA at strA. That is, by means of the assignment statement we copy the address of strA[0] into our variable pA. We now use puts() to show that which is pointed to by pA on the screen. Consider here that the function prototype for puts() is: int puts(const char *s); For the moment, ignore the const. The parameter passed to puts() is a pointer, that is the value of a pointer (since all parameters in C are passed by value), and the value of a pointer is the address to which it points, or, simply, an address. Thus when we write puts(strA); as we have seen, we are passing the address of strA[0]. Similarly, when we write puts(pA); we are passing the same address, since we have set pA = strA; Given that, follow the code down to the while() statement on line A. Line A states: While the character pointed to by pA (i.e. *pA) is not a nul character (i.e. the terminating '\0'), do the following: Line B states: copy the character pointed to by pA to the space pointed to by pB, then increment pA so it points to the next character and pB so it points to the next space. /* line C (see text) */ /* show strB on screen */
99
100
int *ptr; ptr = &my_array[0]; /* point our pointer at the first integer in our array */
As we stated there, the type of the pointer variable must match the type of the first element of the array. In addition, we can use a pointer as a formal parameter of a function which is designed to manipulate an array. e.g.
102
103
104
Even with a reasonably good understanding of pointers and arrays, one place the newcomer to C is likely to stumble at first is in the dynamic allocation of multi-dimensional arrays. In general, we would like to be able to access elements of such arrays using array notation, not pointer notation, wherever possible. Depending on the application we may or may not know both dimensions at compile time. This leads to a variety of ways to go about our task. As we have seen, when dynamically allocating a one dimensional array its dimension can be determined at run time. Now, when using dynamic allocation of higher order arrays, we never need to know the first dimension at compile time. Whether we need to know the higher dimensions depends on how we go about writing the code. Here I will discuss various methods of dynamically allocating room for 2 dimensional arrays of integers.
105
Passing structure to elements to functions Passing entire function to functions Arrays of structure
8.3 Union
8.4 More on structures and Union
Structure is a method of packing the data of different types. When we require using a collection of different data items of different data types in that situation we can use a structure.
A structure is used as a method of handling a group of related data items of different data types.
struct tag_name {
106
struct lib_books { char title[20]; char author[15]; int pages; float price; }; To holds the details of four fields namely title, author pages and price,the keyword struct declares a structure. These are the members of the structures. Each member may belong to same or different data type. The tag name can be used to define the objects that have the tag names structure. The structure we just declared is not a variable by itself but a template for the structure. We can declare the structure variables using the tag name any where in the program. For example the statement, struct lib_books book1, book2, book3; declares the book1, book2, book3 as variables of type struct lib_books each declaration has four elements of the structure lib_books. The complete structure declaration might look like this The complete structure declaration might look like this struct lib_books { char title[20]; char author[15]; int pages; float price; };struct lib_books, book1, book2, book3;
A structure may be passed into a function as individual member or a separate variable. A program example to display the contents of a structure passing the individual elements to a function is shown below. # include < stdio.h > void main() { int emp_id; char name[25]; char department[10]; float salary; }; static struct emp1={125,sampath,operator,7500.00}; /* pass only emp_id and name to display function*/ display(emp1.emp_id,emp1.name); } /* function to display structure variables*/ display(e_no,e_name) int e_no,e_name; { printf(%d%s,e_no,e_name);
in the declaration of structure type, emp_id and name have been declared as integer and character array. When we call the function display() using display(emp1.emp_id,emp1.name); we are sending the emp_id and name to function display(0); it can be immediately realized that
108
void main() { static struct employee emp1= { 12, sadanand, computer, 7500.00 };
1)A structure allocates the total size of all elements in it. 2) Members inside a structure are always stored in separate memory locations throughout the lifetime and scope of the entire structure. Manipulations of one member will not affect the values of any of the others in any way unless they are operated on in code to do so.
8.3 Union
However the members that we compose a union all share the same storage area within the computers memory where as each member within a structure is assigned its own unique storage area. Thus unions are used to observe memory. They are useful for the application involving multiple members. Where values need not be assigned to all the members at any time. Unions like structure contain members whose individual data types may differ from one another also. Like structures union can be declared using the keyword union as follows: union item { int m; float p; char c; } code
112
Similarities between structure and union: 1) They both can accept the dot (.) operator to address a member from the object name, as struct.member or union.member. 2) They both use brace delimited declarations to create the template for the data object. Both accept tagname and name as well as explicit initialization as options. 3) They both can have their size correctly determined as maximum size in bytes by use of the sizeof() operator.
An example program is shown below. I hope it helps you understand. #include <stdio.h> #include <stdlib.h> /* Declares union */
113
/* Declares structure */ struct two{ char one; int two; float three; };
int main(void) { /* Uses tag names to create structure S and union U. */ struct two S; union one U;
/* Outputs object sizes to screen. */ printf("%d is the size of S, as structure.\n", sizeof(S)); printf("%d is the size of U, as union.\n\n", sizeof(U)); /* Loads values into S and U, as below. */ S.one = 'A'; S.two = 3645; S.three = 678.32; U.one = 'A'; U.two = 3645; U.three = 678.32;
114
9.1 Introduction 9.2 File Types 9.2.1 Text streams 9.2.2 Binary streams 9.3 Stdio.h header file 9.4 Oprations on file 9.4.1 Opening named files 9.4.2 Reading from a stream using fgetc 9.4.3 Writing to a stream using fputc 9.4.4 Closing files
9.1 Introduction
One of the reasons that has prevented many programming languages from becoming widely used for real programming is their poor support for I/O, a subject which has never seemed to excite language designers. C has avoided this problem, oddly enough, by having no I/O at all! The C language approach has always been to do I/O using library functions, which ensures that system designers can provide tailored I/O instead of being forced to change the language itself.As C has evolved, a library package known as the Standard I/O Library or stdio, has evolved with it and has proved to be both flexible and portable. This package has now become part of the Standard We frequently use files for storing information which can be processed by our programs. In order to store information permanently and retrieve it we need to use files Files are not only used for data. Our programs are also stored in files.The editor which you use to enter your program and save it, simply manipulate files for you.
115
116
The above statement opens a file called prog.c for reading and associates the file pointer fp with the file. When we wish to access this file for I/O, we use the file pointer variable fp to refer to it. You can have up to about 20 files open in your program - you need one file pointer for each file you intend to use. If you attempt to read from an non-existent file, your program will crash!! The fopen function was designed to cope with this eventuality. It checks if the file can be opened appropriately. If the file cannot be opened, it returns a NULL pointer. Thus by checking the file pointer returned by fopen, you can determine if the file was opened correctly and take appropriate action e.g.
118
if ( fp == NULL) { printf(Cannot open %s for reading \n, filename ); exit(1) ; /*Terminate program: Commit suicide !!*/ } The above code fragment show how a program might check if a file could be opened appropriately.The function exit() is a special function which terminates your program immediately. exit(0) mean that you wish to indicate that your program terminated successfully whereas a nonzero value means that your program is terminating due to an error condition.Alternatively, you could prompt the user to enter the filename again, and try to open it again: fp = fopen (fname, r) ;
while ( fp == NULL) { printf(Cannot open %s for reading \n, fname ); printf(\n\nEnter filename : ); gets( fname ); fp = fopen (fname, r) ; } In this code fragment, we keep reading filenames from the user until a valid existing filename is entered.
119
fclose( fp ); } In this program, we open the file prog.c for reading. We then read a character from the file. This file must exist for this program to work. If the file is empty, we are at the end, so getc returns EOF a special value to indicate that the end of file has been reached. (Normally -1 is used for EOF) The while loop simply keeps reading characters from the file and displaying them, until the end of the file is reached
int fclose(FILE *stream); Any unwritten data buffered for stream is flushed out and any unread data is thrown away. If a buffer had been automatically allocated for the stream, it is freed. The file is then closed.Zero is returned on success, EOF if any error occurs The function fclose is used to close the file i.e. indicate that we are finished processing this file. We could reuse the file pointer fp by opening another file. /* Prompt user for filename and display file on screen */
#include <stdio.h>
c = getc( fp ) ;
fclose( fp ); }
In this program, we pass the name of the file to be opened which is stored in the array called filename, to the fopen function. In general, anywhere a string constant such as prog,c can be used so can a character array such as filename. (Note the reverse is not true).The above programs suffer a major limitation. They do not check whether the files to be used exist or not.
Example usage
The following C program opens a binary file called myfile, reads five bytes from it, and then closes the file. #include <stdio.h> #include <stdlib.h> int main(void) {
122
123
BIBLIOGRAPHY
1. Programming in ANSI C, E Balagurusamy , TMH 2. Let Us C, Y Kanetkar , BPB 3. The C Programming Language, B.W. Kernigham & Ritchie, PHI 4. Programming in C , Gottrified, TMH
124