1
NATURE THOUGHTS & SYMMETRY
Fundamentals
TURBO C Nature Thoughts & Symmetry
2
Table of Contents PART-1 ..............................................................................................................................................................6 Introduction to C ................................................................................................................................................7 • Basic Data Types ...................................................................................................................................7 • Case, format, spacing, comments ..........................................................................................................7 • Identifiers ...............................................................................................................................................8 • Storage Classes ......................................................................................................................................8 • Block statements ................................................................................................................................8 • Declaration, Definition ......................................................................................................................8 • The ‘SCOPE’ of a variable ................................................................................................................9 • Local variable.....................................................................................................................................9 • Global variable.................................................................................................................................10 • Type Qualifiers: (Const, Volatile) ...................................................................................................11 • Register Variables............................................................................................................................11 • Source, Object and Compiler...............................................................................................................11 • Structure of C program ........................................................................................................................12 • Character constants ..............................................................................................................................12 • Operators & arithmetic Instruction ......................................................................................................12 Decision Control Structure ..............................................................................................................................14 • if – (else if)n – (else)0 or 1 statement, n = 0, 1, 2, …..............................................................................14 • True and False in C ..........................................................................................................................14 • Making the conditional-code shorter ...............................................................................................14 The Loop Control Structure .............................................................................................................................15 • The for statement .................................................................................................................................15 • Some useful statements........................................................................................................................15 • The break statement .........................................................................................................................15 • The continue statement ....................................................................................................................15 • The exit() function ...........................................................................................................................15 Functions..........................................................................................................................................................16 • General form of a Function..................................................................................................................16 • Scope of a Function .........................................................................................................................16 • The return statement ........................................................................................................................16 • Declaring variable length parameter list ..........................................................................................17 • Call by Value, Call by Reference ........................................................................................................17 • Passing a Pointer to a variable .........................................................................................................17 • Passing a Pointer (name of array itself) to a single-dimension array ..............................................17 • Passing a Pointer (name of string itself) to a string .........................................................................18 • Types of functions: ..............................................................................................................................18 • Calling conversion ...............................................................................................................................18 • Don’t practice the following ................................................................................................................18
Nature Thoughts & Symmetry
3 Pointers ............................................................................................................................................................20 • Pointers basics......................................................................................................................................20 • Why we need pointers?....................................................................................................................20 • What are pointers? ...........................................................................................................................20 • The pointer operators .......................................................................................................................20 • Pointer Conversions .........................................................................................................................20 • Pointer Arithmetic................................................................................................................................21 • Pointer Comparisons............................................................................................................................21 • Array of Pointers..................................................................................................................................21 • Initializing Pointers..............................................................................................................................21 • C’s Dynamic Allocation Functions......................................................................................................22 • The malloc() function ......................................................................................................................22 • The free() function ...........................................................................................................................23 Arrays & Strings ..............................................................................................................................................24 • Basics ...................................................................................................................................................24 • Indexing Pointers .................................................................................................................................24 • Some peculiar properties of Array and Strings....................................................................................25 • Initialization during declaration.......................................................................................................25 • Accessing Arrays and Strings, after declaration ..............................................................................26 • Read out ...........................................................................................................................................26 • Accessing array elements.................................................................................................................26 • Passing arrays.......................................................................................................................................26 • Assigning the values of one array to another...................................................................................26 • Passing 1-D Array to Functions.......................................................................................................27 • Finding the minimum (or maximum) of an array ................................................................................27 • Bringing smallest element to first position ......................................................................................27 • Not altering the arrangement of given array ....................................................................................27 • String and Character functions.............................................................................................................27 • The strlen function ...........................................................................................................................27 • The strcpy function ..........................................................................................................................27 • The strcat function ...........................................................................................................................28 • The sprintf function..........................................................................................................................28 • Using sscanf to Validate Input.........................................................................................................28 • The sizeof operator ..........................................................................................................................28 • Mathematical functions........................................................................................................................29 • The sin(), cos(), & tan() ...................................................................................................................29 • The sinh(), cosh(), & tanh() .............................................................................................................29 • The asin(), acos(), & atan() ..............................................................................................................29 • The atan2() .......................................................................................................................................29 • The exp()..........................................................................................................................................29 • The pow().........................................................................................................................................29 • The log()...........................................................................................................................................29 • The log10().......................................................................................................................................29 • The fabs() .........................................................................................................................................29 • The floor()........................................................................................................................................29 • The fexp().........................................................................................................................................29 • The ldexp().......................................................................................................................................29 PART-2 ............................................................................................................................................................30
Nature Thoughts & Symmetry
4 Console I/O ......................................................................................................................................................31 • Types of Input and Output in C ...........................................................................................................31 • Unformatted functions .....................................................................................................................31 • Formatted functions .........................................................................................................................32 • The printf .............................................................................................................................................32 • Control string (a character string) of printf......................................................................................32 • Calling convention in C ...................................................................................................................32 • Conversion specification:.................................................................................................................33 • Escape sequence and control character............................................................................................33 • Octal and hexadecimal notation.......................................................................................................33 • Marks that can not be printed directly by inserting them in control string..........................................34 • The scanf function: ..............................................................................................................................34 • Scanning octal and hexadecimal numbers .......................................................................................34 • Discarding unwanted white space....................................................................................................34 • Non-white-space characters in the control string.............................................................................35 • Maximum field width specifier........................................................................................................35 The Preprocessor..............................................................................................................................................36 • #define..............................................................................................................................................36 • #include............................................................................................................................................36 Structures .........................................................................................................................................................38 • Declaration of a Structure ....................................................................................................................38 • Initializing a structural variable ...........................................................................................................38 • Accessing Structure-variable’s elements .............................................................................................38 • Array of structure.................................................................................................................................38 • Additional features...............................................................................................................................39 • Assigning one structure variable to another.....................................................................................39 • Passing a structure variable to a function ........................................................................................39 • Nesting of structures ........................................................................................................................39 • Structure-pointers.................................................................................................................................39 • Accessing structures-pointer’s elements..............................................................................................40 • The typedef ..........................................................................................................................................40 PART-3 ............................................................................................................................................................41 File Input/ Output.............................................................................................................................................42 • Opening and reading a file...................................................................................................................42 • Opening the file................................................................................................................................42 • Closing the file.................................................................................................................................42 • Errors and End of the file.....................................................................................................................42 • Error in opening the file...................................................................................................................42 • Error in closing the file ....................................................................................................................43 • Determining end of the file ..............................................................................................................43 • File Opening Modes.............................................................................................................................43 • “r”.....................................................................................................................................................43 • “w” ...................................................................................................................................................43 • “a” ....................................................................................................................................................43 • “r+” ..................................................................................................................................................44 • “w+”.................................................................................................................................................44 • “a+” ..................................................................................................................................................44 • Reading and Writing in files ................................................................................................................44
Nature Thoughts & Symmetry
• • • • • • • •
• • •
5 The putc() function ..........................................................................................................................44 The getc() function...........................................................................................................................44 The fputs() function .........................................................................................................................44 The fgets() function..........................................................................................................................45 Flushing a Stream ............................................................................................................................45 The fread() function .........................................................................................................................45 The fwrite() function........................................................................................................................46 Changing the cursor position ...............................................................................................................46 The rewind() function ......................................................................................................................46 The fseek() Random-Access I/O......................................................................................................46 Counting No. of characters in a C-program.....................................................................................46
Nature Thoughts & Symmetry
6
PART-1
Nature Thoughts & Symmetry
7
Introduction to C Basic Data Types C89 defines five foundational data types: character, integer, floating-point, double floatingpoint, and valueless. These are declared using char, int, float, double, and void, respectively. These types form the basis for several other types. Type signed char char int unsigned int long int long unsigned int float double long double
CS %c %c %d %u %ld %lu %f, %e %lf %Lf
Typical Size in Bytes 1 1 2 2 4 4 4 8 10
Minimum Range -(27) to (27-1) (0) to (28-1) -(215) to (215-1) (0) to (216-1) -(231) to (231-1) (0) to (232)
The letter e stands for the word exponent. The exponent is the whole number following the letter e; the part of the number before the letter e is called the mantissa. In ‘float’, there are 7 significant figures. There can be maximum of 6 significant digits in decimal part. Significance of integral part is more important. In ‘double’ there are 17 significant figures. There can be maximum of 6 significant digits in decimal part. Significance of integral part is more important. The printf() format specifiers for decimal values: Code Format %f Decimal floating point %e Scientific notation (lowercase e) %E Scientific notation (lowercase E) The Cast Operator: The name of data to which conversion is to be made (such as int or float) is enclosed in parentheses and placed directly to the left of the value to be converted. The cast operator can be used on a constant or expression as well as on a variable: (int)3.1415 (double)4*3/7 + (double)4/3 (float)a q = (int *)p //Here, p and q are defined to be void and int pointers respectively. Note that do not apply overall bracket to the expression besides (float), for example following syntax is wrong: (float)(4*3/7) That is, cast operator should be applied just before a term, the term itself should not be placed within brackets. Case, format, spacing, comments Case: C knows the difference between uppercase and lowercase letters. Lowercase letters are characteristic of C language. Free format:
Nature Thoughts & Symmetry
8
C program instructions are written in free format. That is to say, they may appear anywhere on the line. Notice that braces always line up with the letter m of main-function. This alignment is not strictly necessary, but it makes the program more readable. Notice, too, that the body of the function is indented within the braces. Once again, this makes no difference to the computer or the compiler, but it helps us to read the program more easily. Spacing: In C there is almost never any need of a space to appear anywhere, except to separate a keyword from a variable name. Usually we add single space before and after the assignment operator. Relational operators containing two symbols, must not contain spaces. There should be a space between ‘else’ and ‘if’, in else if statement. Comments: Comments are added by beginning it with the two characters /* and ending it with the characters */. No space can be included between the two characters. The comments should not contain the closing delimiter */ as part of the comment’s text. Many programmers are tempted to postpone the inclusion of comments until the program has been checked out and passed, but then the task of including the comments is not very attractive.
Identifiers In C, the names of variables, functions, labels, and various other user-defined items are called identifiers. Identifier name must start with a letter of the alphabet and the name may contain digits or alphabets. In C, the underscore character is considered as letter or alphabet. In an identifier, upper- and lowercase are treated as distinct. An identifier cannot be the same as a C keyword and should not have the same name as functions that are in the C library. In C89, at least the first 6 characters of external identifier and at least the first 31 characters of and internal identifier will be significant. A variable is a name location in memory that is used to hold a value that can be modified by the program. All variables must be declared before they can be used. There are three places to declare a variable: i) Outside all functions; Global variable ii) Inside a function; Local variable iii) In definition of a function; parameters Storage Classes Local Variables: 1. Auto, Static 2. Const, Volatile Global Variables: 1. Extern, Static 2. Const, Volatile Parameters: Acts as local variables and receives the value of argument passed to the function. Block statements Block statements are simply groups of related statements that are treated as a unit. A block is begun with a { and terminated by its matching }. Programmers use block statements most commonly to create a multi-statement target for some other statement, such as if. However, you may place a block statement anywhere you would put any other statement. Declaration, Definition
Nature Thoughts & Symmetry
9
A declaration declares the name and type of an object. A definition causes storage to be allocated for the object. The same object may have many declarations, but there can be only one definition. The statement of assigning some fixed value to a variable, is called definition only when this is done along with declaration. And ‘declaration along with definition’ can be done only once for a variable. If we don’t explicitly assign some fixed value while declaration, the definition is done automatically as per its default initial value. The case of more than one declarations is possible for global variables. The places where they are only declared and not defined, we use the keyword ‘extern’ while declaration. (Page No. 31, CR to C) C defines three categories of linkage: external, internal, and none. In general, functions and global variables have external linkage. This means they are available to all the files that constitute a program. File scope objects declared as static have internal linkage. These are known only within the file in which they are declared. Local variable have no linkage and are therefore known only within their own block.
The ‘SCOPE’ of a variable When a variable is out of scope, we mean that its value cannot be accessed but it may have life. Block Scope: A block of code begins with an opening curly brace and terminates with a closing curly brace. However, block scope also extends to function parameters in a function definition. If a variable has a block scope, it is accessible only within that block and inner blocks. When we call a function, execution is transferred from current block to that function, so local variables would not be available in called function. To the inner-blocks, its value is available as well as can be changed, as long as same variable is not declared in that inner-block. When a variable declared within an inner block has the same name as a variable declared by an enclosing block, the variable in the inner block hides the variable in the outer block. APNE GHAR ME KUTTA BHI SHER HOTA HAI. Note that if we call a function, the execution is transfer to that function, after returning to the original function, the last values of the variables will be not be lost, but its value can not be accessed from the called function. File Scope: Starts at the beginning of the file (also called a translation unit) and ends with the end of the file. It refers only to those identifiers that are declared outside of all functions. File scope identifiers are visible throughout the entire file. Variables that have file scope are global. But it is local variable that gets preference over the global variable, whenever conflict arises. “APNE GHAR ME KUTTA BHI SHER HOTA HAI”. Local variable Auto local Variable: A variable declared inside a block, without storage class name, is called Auto local variable. Keyword: auto (This keyword is virtually never used.) Declaration: Local variables are always declared at start of a block (not necessarily at start of a function), prior to any “action” statements. Default initial value: Garbage value. Scope: They have block scope. Life: Life of an auto local variable is lost when execution encounters that block terminator, ‘}’. When a function returns a value, the execution is passed to the called function, we may think as execution has directly encountered the function terminator after returning a particular value. Benefits: Declaring variables within the block of code that uses them helps prevent unwanted side effects. Since the variable does not exist outside the block in which it is declared, it cannot be accidentally altered by other code.
Nature Thoughts & Symmetry
10 Static local variables: A static local variable has the same scope as that of local variable but has life that of a global variable. Thus, it retains its value between function calls as it does not looses its life when execution encounters block terminator of function. Keyword: static Declaration: Local variables are always declared at start of a block (not necessarily at start of a function), prior to any “action” statements. Default initial value: Zero. Scope: They have same scope as that of auto local variables. Life: They have same life as that of global variables. That is, life of a static local variable is there, as long as the program’s execution doesn’t come to an end. Benefits: If static variables were not allowed, globals would have to be used, opening the door of possible side effects. Parameters: They are declared in the definition of the function, to accept the arguments. They behave like any other local variable declared just after the start of the block of function, prior to any “action” statement. Global variable Global variables: They are declared outside of all functions (not necessarily at top of the program). Any expression may access them, regardless of what block of code that expression is in. Keyword: no keyword (not even ‘auto’) Declaration: They are declared outside and before all the functions. In a multi-file program, declare all the global variables in main file (file having main() function). In other files, do the extern declaration for the global variables, which are used in them. Default initial value: Zero. Scope: The have file scope with external linkage. To extend there scope to other files, we use ‘extern’ declaration in the fie, where a particular global variable is needed. Life: As long as the program’s execution doesn’t come to an end. Benefits: If we declare global variables in the program there is no need to pass these variables to as other function. We should avoid using unnecessary global variables, however. They take up memory the entire time our program is executing, not just when they are needed. In addition, using a global where a local variable will do makes a function less general because it relies on something that must be defined outside itself. How to do extern declaration? In any particular file, extern declaration is done outside and before all the functions using the keyword ‘extern’. The principal use of extern is to specify that a variable is declared with external linkage elsewhere in the program. For example extern int sum; The extern declaration lets the compiler know what the types and names are for the used global variables without actually creating storage for them again. When the linker links the two modules, all references to the external variables are resolved. An important use of extern relates to multiple-files programs. C allows a program to be spread across two or more files, compiled separately, and then linked together When this is the case, there must be some way of telling all the files about the global variables required by the program. The best (and most portable) way to do this is to declare all of your global variables in one file (which contains main-function, and declaration should be done before main-function) and use extern declarations in the other (before all of the functions). One last point: In real-world, multiple-file programs, extern declarations are normally contained in a header file that is simply included with each source code file. This is both easier and less error prone than manually duplicating extern declarations in each file.
Nature Thoughts & Symmetry
11
Moreover in such programs it is good to declare all global variables of the program, just before the main function. Static global variables: Applying the specifier static to a global variable instructs the compiler to create a global variable known only to the file in which it is declared. Thus, a static global variables has internal linkage. Keyword: static Declaration: They are declared outside and before all the functions. Default initial value: Zero. Scope: They have file scope with internal linkage. There scope can not be extended to other files. Life: As long as the program’s execution doesn’t come to an end. Benefits: Suppose we place the function a() that contains static global variables, name_1, in a library. We can use the function but cannot reference the variable name_1, which is hidden from rest of the code in our program. In fact, we can even declare and use another variable called name_1 in our program (in another file, of course). By using static variables, we can hide portion of our program from other portions. This can be a tremendous advantage when we are trying to manage a very large and complex program. Type Qualifiers: (Const, Volatile) Constant variable: Variable of type const can not be changed by your program. (A const variable can be given an initial value, however.) The compiler is free to place variables of this type into read-only memory (ROM). For example, const long int x = 1; Note that the compiler protects the value of 'x' from modifications. The user cannot assign any value to 'm', but using scanf() statement the value can be replaced. A variable of type const can be modified by something outside your program. The const qualifier can be used to prevent the object pointed to by an argument to function from being modified by that function. That is, when a pointer is passed to a function, the function can modify the actual object pointed to by the pointer. However, if the pointer is specified as const in the parameter declaration, the function code won’t be able to modify what it points to. Volatile variable: (not understood, Page No. 30) The modifier volatile tells the compiler that a variable’s value may be changed in ways not explicitly specified by the program. For example, a global variable’s address may be passed to the operating system’s clock routine and used to hold the system time. In this situation, the contents of the variable are altered without any explicit assignment statement in the program.
Register Variables The keyword register tells the compiler that the variable list followed by it is kept on the CPU registers. A value stored in a CPU register can always be accessed faster than the one that is stored in memory. Therefore, if a variable is used at many places in a program it is better to declare its storage class as register. A good example of frequently used variables is loop counters. Declaration as register does not make sure us that the value would be stored in a CPU register because CPU registers are limited in numbers and compiler automatically converts register variables to auto type once the limit is reached. We can only apply the register specifier to local variables and to the parameters in a function. Global register variables are not allowed. Source, Object and Compiler
Nature Thoughts & Symmetry
12 Written program is called as source program (like new.c). The source program is to be converted to the machine language, which is called as object program (like new.obj). Either an interpreter or a compiler will do this activity. Interpreter reads only one line of a source program at a time, so it consumes more time. But, compiler reads the entire program and so it consumes little time. Structure of C program Inclusion of Header files Declaring and defining Global variables Declaring User-defined functions Function Main { Declaring Local variables Executable part } Defining user-defined function { } All statement should be written in lower case letters. Upper case letters are only used for symbolic constants. Blank spaces may be inserted between the words, to improve the readability of the statements. However, it is not used while declaring a variable, keyword, constant and function. Character constants They are of two types: 1. Single character constant: They are represented with a single digit or a single symbol or white space enclosed within a pair of single quote marks. Some examples of character constant are ‘a’, ‘*’, ‘;’, ‘\n’. 2. String constant: String constants are sequence of characters enclosed within a double quote marks. The string may be a combination of all kind of symbols. Note that ‘a’ refers to a character constant, but “a” refers to a character string. Operators & arithmetic Instruction Assignment operator: An assignment statement should not be read as if it were a simple algebraic statement of equality. Instead, it means: Take a value on the right side of the equal sign and store it in the variable specified on the left side of the equal sign. Variable name on left side of ‘=’. Variable names, constant with arithmetic operator +, -, *, /, %, on right side of ‘=’. No operator is assumed to present. Arithmetic operators: (+), (-), (*), (/), (%) They are sometimes called binary operator because it operates on two terms or values at a time. In C, there is no such thing as implied multiplication; asterisk has to be included at all time. Note that ‘%’ can not be applied on float and takes the sign of numerator. The Relational operators: (==), (>), (<), (<=), (>=), (!=) Notice that some of these operators consist of only one character, whereas others contain two. Those with two characters must not contain spaces. In programming we use the terms ‘true’ and ‘false’ for relational operators and logical operators. In C, all Boolean values (as true and false sometimes are called) are represented by
Nature Thoughts & Symmetry
13 integers. The value 0 is interpreted as false when it is used with relational or logical operators, and any other integer is regarded as true. The logical operators: (&&, means intersection), (||, means union), (!, means reverse) Note that ! is a unary operator and has the effect the reversing the truth value of the expression to its immediate right. The unary minus operator: The minus sign may also be used as a unary operator, as in the following example: -3, -a, -(-4). The comma operator: The comma operator is used to separate two or more expressions. The comma operator has the lowest priority among all the operators. It is not essential to enclose the expression with comma operator within the parenthesis. a = 2, b= 4, c = a+b; The sizeof() and & operator: Using sizeof() and & operator size and addresses can be displayed of a variable, moreover the function sizeof() can be used on data type itself, instead of variable. For example: long int x; printf("Byte size of 'x' = %d bytes", sizeof(x)); printf(“Bytes size of type ‘char’ = %d bytes”, sizeof(char)); printf("Address of 'x' = %u", &x); Parenthesis: First operation takes place within the innermost parenthesis. Truncation: In C, when one integer is divided by another integer, the result is also displayed as an integer. Any fractional part is discarded. 5/2 = 2, 5.0/2 = 2.5, 5/2.0 = 2.5, 5.0/2.0 = 2.5 Type conversion in assignments: When variables of one type are mixed with variables of another type, a type conversion will occur. In an assignment statement, the type conversion rule is easy: The value of the right side of the assignment is converted to the type of the left side. For example: double x; int y; x = 3.9; y = x ; ⇒y=3 Note that long double x; x = 5/2; /* Here, x will assume 2*/ x = (long double)5/2; /*Here x will assume 2.5*/
Nature Thoughts & Symmetry
14
Decision Control Structure if – (else if)n – (else)0 or 1 statement, n = 0, 1, 2, … The conditions are evaluated from the top downward. As soon as a true condition is found, the statement associated with it is executed and the rest of the ladder is bypassed. If none of the conditions are true, the final else is executed. if (Condition) { do this; and this; } else if (condition) { do this; and this; } else { do this; and this; } Note that we can use if statement alone. In conditions we can use the following, but use parenthesis properly: ‘==’, ‘!=’, ‘<’, ‘>’, ‘>=’, ‘<=’ (relational operators) ‘&&’, ‘||’, ‘!’ (logical operators) Important note: Note that during a condition, if we are executing a statement and comparing its value to some value, the statement will be executed even if comparison is not true. For instance, if (fclose(fp) != 0) { printf(“\nError in closing the file”);} If we use these commands, the execution of fclose(fp) takes place even if statement is not true. True and False in C A conditional expression evaluates to either a true or false value. In C, true is any non-zero value, including negative numbers. A false value is 0. Making the conditional-code shorter The statement: return(ps->top == -1); is precisely equivalent to longer statement: if (ps.top == -1) return(any non-zero value) else return(0)
Nature Thoughts & Symmetry
15
The Loop Control Structure The for statement for ((initialize counter); (test counter); (increment counter)) { do this; and this; } Note the following: i) Multiple initialization can be done using comma. ii) Only one expression is allowed in the test counter but there may be more than one variable in it and it may contain several conditions linked together using logical operators. iii) Use of break, continue and exit(). iv) Infinite loop: When the conditional expression is absent, it is assumed to be true. We may have an initialization and increment expression, by C programmers more commonly use for(;;) construct to signify an infinite loop. Some useful statements The break statement When break is encounter inside a loop control automatically passes to the first statement after the loop. A break is usually associated with ‘if’. Note that a break causes an exit from only the innermost loop. if (condition) break; Note that if break statement is encountered, no increment is performed as per increment counter. The continue statement The continue statement works somewhat like the break statement. Instead of forcing termination, however, continue forces the next iteration of the loop to take place, skipping any code in between. For the for loop, continue causes the increment and then the conditional test portions of the loop to execute. if (condition) continue; The exit() function You can break out of a program by using the standard library function exit(). This function causes immediate termination of the entire program, forcing a return to the operating system. In effect the exit() function acts as if it were breaking out of the entire program. The exit() function requires the header <stdlib.h>. The general form of the exit() function is void exit(int return_code); void exit(0); The value of return_code is returned to the calling program, which is usually the operating system. Zero is commonly used as a return code to indicate normal program termination. You can also use the macros EXIT_SUCCESS and EXIT_FAILURE for return_code. (Page No. 90)
Nature Thoughts & Symmetry
16
Functions General form of a Function The values of arguments passed by the calling function are received by the parameters of the called function. The number of arguments and parameters should be the same. Any C program contain at least main() function, because to execute a function we need to call it. But main() function is called first by default by the program. Note that a function cannot be declared or defined in some other function. Also note that while calling a function, instead of its arguments, we may call some other function also. The return statement may also call a function to collect the value. Declaring a function: ret-type function_name (parameter list); The ret-type specifies the type of data that the function returns. A function may return any type of data except an array. The parameter list is a comma-separated list of variable names and their associated types. Note that all function parameters must be declared individually, each including both the type and name. Calling a function: Z = function_name (argument list);, or function_name(); The argument list is a comma-separated list of variable names without their association types. Defining a function: ret-type function_name (parameter list) { local variable declaration; statement1; statement2; return (VALUE); } Scope of a Function Each function is discrete block of code. Thus, a function defines a block scope. This means that a function’s code is private to that function and cannot be accessed by any statement in any other function except through a call to that function. The code that constitutes the body of a function is hidden from the rest of the program, and unless it uses global variables, it can neither affect nor be affected by other parts of the program. The return statement Termination of a function: A function terminates execution and returns to the caller in two ways: 1. When the last statement in the function has executed, and conceptually, the function’s ending curly brace (}) is encountered. 2. Actually, not many functions use this default method of terminating their execution. Most functions rely on the return statement to stop execution either because a value must be returned or to make a function’s code simple and more efficient. The return statement has two important uses. First, it causes program execution to return to the calling code. Second, it can be used to return a value. The void & non-void functions: All functions, except those of type void, return a value. This value is specified by the return statement. If we want that a function should not return any value, in that case, we must
Nature Thoughts & Symmetry
17
mention so by using the keyword void as: void Display(), while declaring and defining the function. The void functions must not contain any return statement. Working of return statement: Values of arguments are passed to parameters. Then the function perform the task using the values of parameters. Then the function returns a value using return statement, which is then collected by the variable ‘Z’ of calling function. With in the parenthesis of return statement, we may have an expression, variable, constant, or even another function call. return (0); return (a+b+c); Exit from the called function to the calling function is done by the use of return statement. A function may use one or more return statements but can return only one value. It is used when we want to return a value depending upon certain conditions. return (sqrt(r)); If such a format is used, when control reaches to the return statement, control again passes to function sqrt(). The return statement collects the result obtained from sqrt() function and returns it to the calling function. Here the return statement calls the function sqrt(). Note that a pointer can also be returned. Declaring variable length parameter list We can specify a function that has a variable number of parameter. The most common example is printf(). To tell the compiler that an unknown number of arguments will be passed to a function, we must end the declaration of its parameters using three periods. For example, int func1(int a, int b, …) This form of declaration is also used by the function’s definition. Any function that uses a variable number of parameters must have at least one actual parameter. Call by Value, Call by Reference In a computer language there are two ways that arguments can be passed to a subroutine. Call by value: This method copies the value of an argument into parameter of the subroutine. In this case, changes made to the parameter have no effect on the argument. Call by reference: In this method, the address of an argument is assigned to the parameter (that means, the variable will have the same address as the passing pointer is pointing to). Inside the subroutine, the address is used to access the actual argument used in the call. This means that the changes made to the parameter affect the argument. Some cases: Passing a Pointer to a variable Here the passed pointer points to a variable. It can be received by a pointer only: Then both the points will point to same variable. For example int func1(int *p) { … } Passing a Pointer (name of array itself) to a single-dimension array Received by pointer Here, the pointer will point to first element of the array. By pointer arithmetic (or pointer indexing) we can access whole of the array. For example int func1(int *p) { }
Nature Thoughts & Symmetry
18
Received by sized array (do not practice) First element of the parameter array will have the same address as that of first element of the argument array. And thus the next elements of parameter array will have the same address as the corresponding elements of argument array, up to length of sized array. int func1(int x[10]) { } Received by unsized array (do not practice) It is the modified version of the previous case, which will receive whole of the argument array. int func1(int x[]) { } Passing a Pointer (name of string itself) to a string If name of string is passed to a function, it acts as pointer to the string. Now, consider the following cases Received by pointer Here, the pointer will point to first element of the string. By pointer arithmetic (or by pointer indexing) we can access whole of the string. Note that a pointer to string (to its first element only) is enough to access whole of the string, without taking any pains, by the use of string functions. Received by sized string (do not practice) Same as in case of arrays Received by unsized string (do not practice) Same as in case of arrays
Types of functions: There can be three type of functions, 1) Without arguments and return values. (Here neither the data is passed through the calling function nor the data is sent back from the called function.) 2) With arguments but without return values. (Arguments are passed through the calling function. The called function operates on the values. But no result is sent back.) 3) With arguments and return values. (Copy of actual argument is passed to the arguments. The return statement returns a changed value which is collected by some variable of calling function.) Calling conversion Calling convention indicates the order in which arguments are passed to a function when a function call is encountered. Note that arguments are always passed from right to left. For example, the out of following statements is ‘331’ instead of ‘122’: int a = 1; printf(“%d%d%d”, a, ++a, a++); Function as an argument: For example: X = double(square(y)); The inner most function is executed first. The double function uses the square() function as an argument. It operates on return value of square() as an argument. Don’t practice the following
Nature Thoughts & Symmetry
1. 2.
3.
19 A function can also serve as its prototype (declaration) if the definition occurs prior to the function’s first use in the program. Page No. 167, CR to C. In C, when a function has no parameters, its prototype uses void inside the parameter list. This tells the compiler that the function has no parameters, and any call to that function that has arguments is an error. In C++, the use of void inside an empty parameter is still allowed, but redundant. The ‘implicit int’ rule: This rule states that in the absence of an explicit type specifier, the type int is assumed. This rule was included in C89 standard, but has been eliminated by C99.
Nature Thoughts & Symmetry
20
Pointers Pointers basics Why we need pointers? The correct understanding and use of pointers is crucial to successful C programming. There are several reasons for this: First, pointers provide the means by which functions can modify their calling arguments. Second, pointers support dynamic allocation. Third, pointers can improve the efficiency of certain routines. Finally, pointers provide support for dynamic data structures, such as binary trees and linked lists. Memory addresses are global to all functions, whereas local variable names are meaningful only within the functions in which they are declared. A function can pass the address of a local variable to another function, and the second functions can use this address to access the contents of the first function’s local variable. What are pointers? A pointer is a variable that holds a memory address. This address is the location of another object (typically another variable) in memory. For example, if one variable contains the address of another variable, the first variable is said to be point to the second. The pointer operators There are two pointer operators: * and &. The & is a unary operator that returns the memory address of its operand. You can think of & as returning “the address of”. The second pointer operation, *, is the complement of &. It is a unary operator that returns the value located at the address that follows. You can think of * as “value at address”. If we declare the following: int *a, b, *c; It means that ‘a’ and ‘c’ is a pointer of type int, and ‘b’ is simply a variable of type int. Suppose we have integral variable ‘v’ and its value is 10. The variable ‘p’ is declared as a pointer variable. The statement p=&v assign address of ‘v’ to ‘p’. i.e. ‘p’ is the pointer to variable ‘v’. The pointer ‘p’ is noting but address of the variable ‘v’. To display the value stored at that location *p is used. The pointer variables also have address and are displayed using ‘&’ operator. For example: printf(“\n Address of v = %u”, p); /* Always use %u for displaying address. */ printf(“\n Address of v = %u”, &v); printf(“\n Value of v = %d”, *p); printf(“\n Value of v = %d”, v); printf(“\n Value of v = %d”, *(&v)); printf(“\n Address of p = %u”, &p); So, *p means value at some address, p. And &v means address of some variable, v. p = q; /*means that address ‘q’ is over-written over the address ‘p’ */ *p = *q; /*means that value of address ‘q’ is over-written over the address ‘p’*/ p = &a; /*means that pointer p points to address of a*/ *p = a; /*means that the value at the address, at which p is already pointing, is overwritten by the value of a*/ Pointer Conversions You can use a pointer on the right-hand side of an assignment statement to assign its value to another pointer. Let us consider some of the cases: Case 1: When both pointers are of same type: The situation is straightforward. No explicit cast is required. For example,
Nature Thoughts & Symmetry
21
p1 = &x; //here, p1 and x are of same data type p2 = p1; //here, p2 and p1 are of same data type Case 2: Converting one type of pointer to another type, without using void * pointer: The conversion must be performed by using an explicit cast. However, the conversion of one type of pointer into another type may create undefined behavior. For example, p = (int *) &x; //here, data type of x is ‘double’ Case 3: Conversion between a pointer and void * pointer: A void * pointer is called a generic pointer. The void * pointer is used to specify a pointer whose base type is unknown. The void * type allows a function to specify a parameter that is capable of receiving any type of pointer argument without reporting a type mismatch. No explicit cast is required to convert to or from a void * pointer. Note: In C++, in all cases it is illegal to convert one type of pointer into another type of pointer without the use of an explicit type cast. This includes void * pointer conversions, too. For this reason, many C programmer cast all pointer conversions so that their code is also compatible with C++. Pointer Arithmetic There are only two arithmetic operations that you can use on pointers: Addition or subtraction of an integer to a pointer: Let p1 be an integer pointer with a current value of 2000. Also, assume ints are 2 bytes long. p1++; //p1 is jumped from 2000 to 2002 p1--; //p1 is jumped from 2000 to 1998 p1 = p1 + 10; //p1 is jumped from 2000 to 2020 p1 = p1 – 10; //p1 is jumped from 2000 to 1980 Subtraction of a pointer from another: You can subtract one pointer from another in order to find the number of objects of their base type that separate the two. All other arithmetic operations are prohibited. Pointer Comparisons We can compare two pointers in a relational expression. For instance, given two pointers p and q, the following statement is perfectly valid: if (p < q) printf(“p points to lower memory location then q\n”); Generally, pointer comparison are useful only when two pointers point to a common object, such as an array.
Array of Pointers Pointers can be arrayed like any other data type. The declaration for an int pointer array of size is int *x[10]; To assign the address of an integer variable called var to the third element of the pointer array, write x[2] = &var; To find the value of var, write *x[2] Note that there is no pre-defined relation between the address to which the elements of a ‘array of pointer’ will point. So here, we are to assign the address to each of the element of ‘array of pointers’. Initializing Pointers Consider the following statements:
Nature Thoughts & Symmetry
22 int *p; //Declares a pointer pointing to the, first cell of the, piece of memory of integral size and having known (garbage) address and garbage value. *p = 70; //Now, that particular piece of memory has a value of 70. Now, consider the following: int *p = 70; //Declares a pointer pointing to the, first cell (having address 70), piece of memory of integral size having garbage value. So, this way we can initialize a pointer to any particular memory address. This happens because while declaration, we talk about the pointer; not about its value. By default, the ASCII value of first cell of the zero-address is zero, unless we assign some value to this cell. After a non-static, local pointer is declared but before it has been assigned a value, it contains an unknown value. (Global and static pointers are automatically initialized to null). A pointer that does not currently point to a valid memory location is given the value null (which is zero). Null is used because C guarantees that no object will exist at the null address. Thus, any pointer that is null implies that it points to nothing and should not be used. Make a habit to define pointer while declaration, as follows: data_type *p = 0; //Now, the pointer p, points to zero-address. data_type *p = NULL; //same as above. C defines a macro NULL which means ‘a null pointer’. To use this macro, we need to include the header file <stdlib.h>. C’s Dynamic Allocation Functions Dynamic allocation is the means by which a program can obtain memory while it is running. Memory allocated by C’s dynamic allocation functions is obtained from the heap. The heap is free memory that is not used by your program, the operating system, or any other program running in the computer. The size of heap can not usually be known in advance, but it typically contains fairly large amount of free memory. Although the size of the heap is often quite large, it is finite and can be exhausted. The core of C’s allocation system consists of functions malloc() and free(). These functions work together using the free memory region to establish and maintain a list of available storage. The malloc() function allocates memory, and the free() function releases it. Any program that uses these functions must include the header <stdlib.h>. The malloc() function The malloc() functions has the prototype: void *malloc(size_t number_of_bytes); It returns a pointer of the type void *, which means that you can assign it to any type of pointer. After successful call, it returns a pointer to first byte of the region of memory of allocated from the heap. If there is not enough available memory to satisfy the malloc() request, an allocation failure occurs and malloc() returns a null. C defines (using typedef) a special type called size_t, which corresponds loosely to an unsigned integer. Technically, the value returned by sizeof is of type size_t. For all practical purposes, however, you can think of it (and use it) as if it were an unsigned integer value. So, if we wish to point a float pointer to a memory of size 5 times the size of float, we can write: p = (float *)malloc(5*sizeof(float)); Here, we used the type cast (float *) to convert pointer of the type (void *) to the type of the pointer to the left side of the assignment. Since the heap is not infinite, whenever you allocate memory, you must check the value returned by malloc() to make sure that it is not null before using the pointer. Using null
Nature Thoughts & Symmetry
pointer will automatically crash your program. The proper way to allocate memory and test for a valid pointer is illustrated in this code fragment: p = (int *)malloc(100); if (!p) { printf(“Out of memory.\n”); exit(1); }
23
The free() function The free() function is the opposite of malloc() in that it returns previously allocated memory to the system. Once the memory has been freed, it may be reused by a subsequent call to malloc(). The function free() has the prototype: void free(void *p); Here, p is a pointer to the memory that was previously allocated using malloc(). It is critical that you never call free() with an invalid argument; this will damage the allocation system. It is good practice to explicitly set p to NULL after executing free(p).
Nature Thoughts & Symmetry
24
Arrays & Strings Basics Arrays: The general form of declaring a single dimension array is data _ type arr _ name[ size ] ; By this we are actually declaring a pointer of data type ‘data_type’, with name ‘arr_name’. This pointer points to the first cell (of size corresponding to the data type) of the arbitrarily fixed continuous array of unused cells, of size ‘ size ’. In C89, the size of an array must be specified using a constant expression(In C99 we can declare array of variable size). In C, all arrays have 0 as the index of their first element. Within index box [], we can use any expression while accessing. For example: [i+j], [i++], etc. Strings: String is a array of characters with its last meaningful character followed by NULL character. In C language the group of characters, digits, and symbols enclosed within quotation marks are called as string. There is no string type in C; strings are merely a sort of abbreviated notation for specifying character arrays. The control string of printf(), that we include with in double quotes, is just a string. For a character array to be treated as a string, its last meaningful character must be followed by the ASCII value 0, known as the null character and indicated in C by ‘\0’. For example, the string “review” would be stored as shown in figure: r e v i e w \0 You do not need to add the null to the end of string constants manually—the compiler does this for you automatically. When declaring a character array that will hold a string, you need to declare it to be one character longer than the largest string that it will hold. Length of a string is defined as the number of non-null characters it contains, so the number of locations needed to store a string is one more than the string’s length. Note that one can display character string without knowing the length of the string. Every character array always ends with NULL (‘\0’) character. By using NULL character in while loop we can write a program to display the string. Note that ‘\0’ and ‘0’ are not same. ASCII value of ‘\0’ is 0, whereas ASCII value of ‘0’ is 48. Multidimensional arrays and strings: C supports multidimensional arrays. The simplest multi-dimensional arrays the 2-D arrays are stored in a row-column matrix, where the left index indicates the row and the right indicates the column. This means that the rightmost index changes faster than the leftmost when accessing the elements in the array in the order in which they are actually stored in memory. Indexing Pointers Pointers and arrays are closely related. As stated, an array name without an index generates a pointer. Now let us see, how a indexed name of array acts as variable: To 1-D array: Consider the following declaration of an array of 10 elements: int a[10]; If we are to print 3rd element of the array, we can do so as follows: printf(“%d”, * ((int *)a + 2) ); The term * ((int *)a + 2) is equivalent to a[ 2] . This is what we call indexing pointers.
Nature Thoughts & Symmetry
Let p = a; Then a[5] , p[5] , * ((int *)a + 5) , and * ((int *) p + 5) all have the same meaning. The first two indexes pointer, the third and fourth one use pointer arithmetic. Note that for 1-D array, we need not to specify (int *) . That is, we can simply write * ( p + 5)
25
instead of * ((int *) p + 5) . We can use + + p , + + a , etc. To 2-D array: This same concept also applies to arrays of two or more dimensions. Consider the declaration: int a[10][5]; Let p be the pointer to 1st element of 10 by 5 integer array, a[10][10]. That is, p = a; Then, a[ j ][k ] ≡ p[ j ][k ] ≡ *((int *)a + ( j × 5) + k ) ≡ *((int *) p + ( j × 5) + k ) . Note in case of 2-D and multi-dimensional arrays, we may attempt to find the value of a[0][0] as follows: printf(“%d”, *a); //This will not work printf(“%d”, *((int *)a); //This will work, a[0][0] is equivalent to *((int *)a) Printf(“%d”, *p); //This will work Once we have declared that ‘p’ points where ‘a’ points. we need not to specify (int *) with ‘p’. That is, we can simply write * ( p + 5) instead of * ((int *) p + 5) . We can use + + p , etc. The cast of the pointer to the array into a pointer of its base type is necessary in order for the pointer arithmetic to operate properly. Page No. 109-110, CR to C Some peculiar properties of Array and Strings Initialization during declaration Initialization of whole of the array (or string) can be done at once during its declaration. Declaration of an array is done as follows: type _ specifier array _ name[size1]...[sizeN ] The general form of array’s definition along with declaration is similar to that of variables, as shown here: type _ specifier array _ name[size1]...[sizeN ] = {value _ list}; The value _ list is a comma-separated list of constants whose type is compatible with type_specifier. Character arrays that hold strings allow a shorthand initialization that takes the form: char array _ name[ size ] =" string " ; For example: int marks[3] = {40, 95, 76}; char Name[7] = {‘M’, ‘u’, ‘n’, ‘i’, ‘s’, ‘h’};, or char Name[7] = “Munish”; Declaration and Initialization of multi-dimensional arrays (or strings): Multi-dimensional arrays are initialized the same as single-dimension ones. When initializing a multi-dimensional array, you may add braces around the initializes for each dimension. This is called sub-aggregate grouping. For example: int sqrs[3][2] = {{1,1}, {2,4}, {3,9}} When using sub-aggregate grouping, if you don’t supply enough initializes for a given group, the remaining members will be set to zero, automatically. For example:
Nature Thoughts & Symmetry
26
char word_list[6][15] = {“hello”, “goodbye”, “nice day”, “it’s raining”} Since only four literals are specified, all the elements of last row got null value. Unsized array initialization: If, in an array’s (may be any data type) initialization statement, the size of the array is not specified, the compiler automatically creates an array big enough to hold all the initializes present. For multi-dimensional arrays, you must specify all but the leftmost dimension.
Accessing Arrays and Strings, after declaration Overwriting the values of 1-D Array and String: We already know that an array name is pointer of data type ‘data_type’ to the first cell (of size corresponding to the data type) of the arbitrarily fixed continuous array of unused cells, of size ‘ size ’. This pointer is just as another pointers, so we access arrays as if we know a pointer to starting cell of array of cells. After declaration, while giving values to array, each element must be specified. For example: scanf(“%d %d %d”, a[0], a[1], a[2]); For string there are some inbuilt functions, where input is given in pointers, that ease our job. For example: gets(Name); (Note that ‘Name’ is a pointer to a string) Overwriting the values of Multi-dimensional Array and Strings: Singly indexed name of 2-D array (or string) acts as pointer to corresponding part of the array. For a array of string, we can get each string individually. It is easy to access an individual string: We simply specify only the left index. For example, the following statement calls gets() with the third string in str_array. gets(str_array[2]); //for scanning whole of the particular string Read out Similarly, we can not print all elements of an array as; printf(“%d”, a);, instead we are to write following: printf(“%d %d %d”, a[0], a[1], a[2]); The following command displays starting address of the array: printf(“%u”, a); Unlike arrays, you can print all the elements of a string at once as follows: puts(Name); Note that the following command will print whole of the string ‘Name’ except its first 2 elements: puts(Name + 2); //’Name+2’ pointer points to 3rd element of string We can also print it as we do for arrays, as: printf(“%c%c%c%c%c%c”, Name[0],Name[1],Name[2],Name[3],Name[4],Name[5]); Accessing array elements Values to array elements can be given as follows: a[1] = 6; …etc a[2] = a[1]; a[++i] = k; *((int *)a + 1) = 6; Passing arrays Assigning the values of one array to another
Nature Thoughts & Symmetry
27 An entire array cannot be assigned to another array because we have no variable that stands for whole of the array. Each element of x must be assigned separately to the corresponding element of y. Passing 1-D Array to Functions In C, we cannot pass an entire array as an argument to a function. We can, however, pass a pointer to an array by specifying the array’s name without and index. For example: fucnt1(a); If a function receives a pointer to a single-dimension array, we can declare its parameter in one of three ways: i) As a pointer: (int *x) ii) As a sized array: (int x[5]) iii) As an un-sized array: (int x[]) Note that in all the three cases, we are assigning address of pointer ‘a’ to pointer ‘x’. Finding the minimum (or maximum) of an array Bringing smallest element to first position The first element of the array is successively compared with each of the remaining elements of the array, beginning with the second and ending with the last element. Each time an element is found which is smaller than the first element, then there values is swapped. It is done as follows: temp = a1; a1 = an; an = temp; The comparison continues from the next element of the array. Not altering the arrangement of given array Take a variable ‘temp’. Assign value of 1st element to ‘temp’. Then successively compare this value with each of the element of array, starting from 2st element. Each time an element is found which is smaller than ‘temp’, its value is assigned to ‘temp’. The comparison continues from the next element of the array. String and Character functions The string functions operate on null-terminated arrays of characters and require the header <string.h>. The character functions use the header . Because C has no bounds checking on array operations, it is the programmer’s responsibility to prevent an array overflow. Neglecting to do so may cause your program to crash. In C, a ‘Printable character’ is one that can be displayed on a terminal. In ASCII environments, these are the characters between a space (0x20) and tilde (0xFE). ‘Control characters’ have values between (0) and (0x1F), and DEL (0x7F) in ASCII environments. The strlen function This function counts the number of characters present in a string. While calculating length it does not count ‘\0’. Its format is given below: len1 = strlen(arr); len2 = strlen(“Humpty Dumpty”); printf(“%u”, strlen(arr)); The strcpy function The function strcpy copies the string pointed by the second argument (or string stated within in double quotes instead of second argument) in to the string pointed by its first argument. Thus the copy is performed in the same direction as in an assignment statement: transfer the value on the right to the location on the left. For example:
Nature Thoughts & Symmetry
strcpy(string1, “This the message”); strcpy(string1, string2); strcpy(target, source); (NTS) Target string’s dimensions should be big enough to hold the string being copied into it. Its use: 9 If we have not initialized a string during its declaration, then we can initialize it later using this command. 9 If we have to copy a values of string to another.
28
The strcat function Now, we shall discuss another important string operation: that of joining two strings to form a third. This operation is known as concatenation. The strcat functions concatenates the source string at the end of the target string. Its format is given below: strcat(target, source); Note that the target string should be big enough to hold the final string. The sprintf function The sprintf function stands for string printf. It performs all the same conversions as the printf function, but instead of displaying its results on the standard output device (usually on screen), it stores the result in a string. The resulting string is an exact image of what would have been displayed had the printf function been used instead of sprintf at that stage. The sprintf function has an extra parameter preceding the control string. This is the array that will receive the resulting string. For example: sprintf(Name, “Munish Goyal”); sprintf(value, “The value of ‘x’ at this stage is: %d”, x); Its use: 9 If we have not initialized a string during its declaration, then we can initialize it later using this command. (But, use instead strcpy function for this purpose.) 9 If we have to print same type of format many number of times, then it is easier to do it using this function. (But, use instead user-defined function for this purpose.) Using sscanf to Validate Input It is possible to input all data as strings and then use the sscanf function to convert it to the required data type. Before this conversion takes place, however, the input string can be checked character by character to make sure it is valid. The sscanf function is used to convert a string to a desired data type. Its format is given below: sscanf(string_name, “conversion specification”, &variable_address); For example; sscanf(input, “%d”, &number); The sizeof operator The sizeof operator returns the size in bytes (chars) of its operand. The operand can take either of two forms: 1. When sizeof operates on a data type, it returns the number of bytes which a variable of that type occupies in memory. 2. The sizeof operator can also be used with a variable as an operand. In this case, it returns the size of the operand. Note that sizeof operator cannot be used to determine size of an array passed as an array. C defines (using typedef) a special type called size_t, which corresponds loosely to an unsigned integer. Technically, the value returned by sizeof is of type size_t. For all practical purposes, however, you can think of it (and use it) as if it were an unsigned integer value.
Nature Thoughts & Symmetry
29
Mathematical functions All math functions require the header <math.h>. In addition to declaring the math function, this header defines one or more macros. For C89, the only macro defined by <math.h> is HUGE_VAL, which is a double value indicating that an overflow has occurred. Functions that are supported by C89: The sin(), cos(), & tan() double sin(double arg ); The sin() function returns the sine of arg . The value of arg must be in radians. The sinh(), cosh(), & tanh() double sinh(double arg ); It returns the hyperbolic sine of arg . The asin(), acos(), & atan() double asin(double arg ) It returns arc sine of arg . The arg must be in the range -1 to 1; otherwise a domain error will occur. The atan2() double atan2(double a, double b); It returns arc tangent of a/b. The function use the signs of its arguments to compute the quadrant of the return value. The exp() // e
x
double pow(double base, double exp);
// a
x
The log() double log(double x);
// ln x
double exp(double exp); The pow()
The log10() double log10(double x);
// log10 x
The fabs() double fabs(double x); The floor() double floor(double x);
// x // [x]
The fexp() Page No. 399 The ldexp() Page No. 401
Nature Thoughts & Symmetry
30
PART-2
Nature Thoughts & Symmetry
31
Console I/O Types of Input and Output in C The input / output functions are classified in to two types: Unformatted functions They work only with the character data type. They do not require conversion symbol for identification of data types because they work only with character data type. In case values of other data types are passed to these functions, they are treated as the character data. Input: gets(p), ch = getchar() Output: puts(p), putchar(ch) The puts() function Input: Within parenthesis of the function, there may be double quoted string or pointer to the string variable (hence un-indexed name of string). puts(pointer to the string variable); puts(“a string”); Working: It writes its string argument to the screen followed by a newline. The gets() function Input: Within parenthesis of the function, there should be pointer to the string variable (hence un-indexed name of string). gets(pointer to the string variable); Working: It reads a string of characters entered at the keyboard and stores them at the address pointed to by its argument. You can type characters at the keyboard until you strike a carriage return. The carriage return does not become part of the string; instead, a null terminator is placed at the end, and gets() returns. You can correct typing mistakes by using the backspace key before pressing ENTER. a) Length of string variable >= No. of characters typed before hitting ENTER key: here, ENTER key acts as new line character. b) Length of string variable < No. of characters typed before hitting ENTER key: here, length of the string will become equal to No. of characters typed before ENTER key. But, this should be avoided. It is not possible to scan new line using gets() function. The putchar() function Input: Within in parenthesis of the function, there may be a character variable or single quoted character. putchar(variable_name); // variable should be character variable. putchar(‘character_constant’); Working: This function prints one character on the screen at a time which is read by the standard input. New-line will not be printed automatically. The getchar() function
Nature Thoughts & Symmetry
32
Note that getchar() is quite different from other three functions, puts(), putchar(), and gets(). This is because of two reasons: 1. Buffer problem, and 2. We use this function as ch = getchar () instead of getchar () . Input: It contains no parameters within parenthesis. Syntax is given below: ch = getchar(); // ch is a character variable Working: This function reads single character. In my compiler it is implemented in such a way that it buffers input until ENTER is pressed. That is, after the first character has been read in by getchar(), the execution of further statements takes place in the buffer. And when ENTER is pressed, then printing, of all the commands that are in buffer, on screen takes place. ENTER is also a character constant, but if it is used as character constant for getchar() function there is no need to press ENTER key again. Note that you can correct typing mistakes by using the backspace. ch = getchar(); The getch() function Reads a character without echo; does not wait for carriage return. So, use getch() only to still the screen at end of the program, because at end if you are using this function then it waits for you to press and accept any key. Since they accept the values, the accepted value can be used as: a = getch(); Formatted functions They read and write all type of data values. They require conversion symbol to identify the data type. Input: scanf() Output: printf() The printf() statement: In case a mismatch occurs between conversion symbol and the data type, the value of the variable is converted according to the conversion symbol given. Sometimes if no conversion is possible between two data types; some garbage value is printed. The scanf() statement: It also requires conversion symbol to identify the data to be read during the execution of a program. Compatible data types: ‘int’ and ‘char’ are compatible to each other. When two data types are compatible to each other, then the compatible range is equal to the lowest range from the two data types.
The printf The printf function is used to print out a message on screen. (The letter “f” in printf could stand for either “formatted” or “function”.) Control string (a character string) of printf Unlike, Pascal, C restricts the programmer to a single control string in the printf statement. The contents of this string, called the control string, are printed out. A character string in C is a series of characters written within the double quotation marks. These punctuation marks are not actually part of the literal, but serve to delimit it. Blank space in a string counts as a character. The newline character: Even though the newline character is composed of two separate symbols, they are translated by the compiler into a single character. printf(“%s %s also %s %s”, “This”, “is”, “valid”, “\n”); Calling convention in C
Nature Thoughts & Symmetry
33
Calling convention indicates the order in which arguments are passed to a function when a function call is encountered. In C, arguments passes from right to left. For example, Printf(“%d %d %d”, a, ++a, a++, a*a); Note that here, there is no use of “a*a”. First the argument corresponding to %d will be called, i.e., “a++”. Then the argument corresponding to %d will be called, and then %d. Thus, the output will be: 3 3 1
Conversion specification: (Check Page No. 218-219, CR to C) Note that there are 80 columns with 40th & 41st as the middle one. In (%x.yf) or (%-x.yf) x: Minimum field length (including integral part, its sign, decimal part, decimal and spaces). -: Ordinarily, numbers are right justified in the output field. When the minus sign is included, however, the number is left-justified. y: No. of decimal points. In (%x.yd) or (%-x.yd) x: Minimum field length (including the length of given integer, added zeros and extra spaces). -: For left-justification y: To add (y-n) zeros in front of number, if it is positive. Here, n is the length of given integer, excluding its sign. In (%x.ys) or (%-x.ys) x: Minimum field length (including length of given string and extra spaces) y: No. of characters to be taken from the beginning of the string -: For left-justification Note that %f and %e displays 6 digits after decimal, but they may be correct or not. Escape sequence and control character Certain ASCII characters are unprintable, which means that they are not displayed on the screen or printer. For this reason, C includes the backslash character constants, shown on Page 39 (CR to C). You should use the backslash codes instead of their ASCII equivalents to help ensure portability. These characters perform special functions other than producing text. Such characters may be used within the single quotes (when specifying a character constant) or within double quotes (such as in a control string). Escape Sequences Meaning \n newline \t tab \b backspace Octal and hexadecimal notation In program, when a assign integer to a variable (not in scanning), if that integer starts with 0 then it is assumed to be a octal value. If it starts with any digit from 1 to 9, then it is assumed to be decimal (base 10). If it starts with 0x, then it is assumed to be hexadecimal. In octal representation, we use only digits from 0 to 7. In hexadecimal representation, we use digits from 0 to 9, the A (=10), B, C, D, E, F. Conversion specification for integer data type in various notation: For int of type Conversion specification Decimal %d Octal %o Hexadecimal (unsigned, lowercase) %x Hexadecimal (unsigned, uppercase) %X For example:
Nature Thoughts & Symmetry
34
int a = 0x80; (Otherwise, int a = 128;) int b = 012; (Otherwise, int b = 10;) But, during scanning there is no need of 0 or 0x with input, conversion specifier is sufficient. Marks 1. 2. 3. 4. 5. 6.
that can not be printed directly by inserting them in control string Double quotation: (To insert, proceed it with backslash). Backslash: (To insert, proceed it with another backslash). The symbol %: (To insert, follow it immediately with another % symbol). Single quotation: It can be inserted directly in the control string. But, while declaring it as character constant, we must proceed with a backslash. When a backslash is followed by any letter or punctuation mark other than those mentioned here, the character is printed as is. When a backslash is followed by digit, it yields the character whose ASCII value is the number represented by those digits. Also note that those digits always represent a octal number.
The scanf function: The name stands for “scan function” or “scan formatted”. While reading numbers: Note that blank space in the control string, while reading a number, do not mean that there must be spaces at the corresponding locations in the input. We don’t need to put \t or \n in between format specifiers inside control string while reading numbers. Even then if we use, they are useless. scanf(“%u, %d”, &var1, &var2); ≡ scanf(“%u%d”, &var1, &var2); There are three rules for determining when scanf stops reading in digits of an number: 1. When white-space is reached (space, tab and newline) 2. When a non-digit is reached 3. When the maximum field width is exceeded (using %5d) While reading characters: (don’t use it for this purpose) The scanf reads in characters much differently from the way it reads number. We can read individual characters by the use of %c format specifier. While reading a character, white-space characters(space, tab and newline) are read like any other character. We don’t have to press ‘tab’ or ‘enter’ keys to insert successive characters, even a newline character is read by scanf. If we put \t or \n in between %c format specifiers inside control string, then we can respectively separate our successive characters by ‘tab’ or ‘new Line’. While reading strings: (don’t use if for this purpose) The scanf() function can also be used to read string using %s format specifier. Using %s causes scanf() to read characters until it encounters a white-space character. Scanning octal and hexadecimal numbers Like printf, the scanf function uses %o to indicate that an octal number is expected, and %x to indicate a hexadecimal number. It is not necessary to precede the octal value with a leading 0, or hex value with 0x, because the conversion specification determines how the input digits should be interpreted. Even though we can enter letters for hex number in uppercase, they are always printed out from printf in lowercase. Discarding unwanted white space A white-space character in the control string causes scanf() to skip over one or more leading white-space characters in the input stream. A white-space character is either a space, a tab, vertical tab, formfeed, or a newline. In essence, one white-space character in the control
Nature Thoughts & Symmetry
string causes scanf() to read, but not store, any number (including zero) of white-space characters up to the first non-white-space character.
35
Non-white-space characters in the control string A non-white-space character in the control string causes scanf() to read and discard matching characters in the input stream. For example, “%d, %d” causes scanf() to read an integer, read and discard a comma, and then read another integer. If the specified character is not found, scanf() terminates. If you want to read and discard a percent sign, use %% in the control string. Maximum field width specifier The format specifier can include a maximum field length modifier. This is an integer, placed between the % and the format specifier, that limits the number of characters read for that field. For example, to read no more than 20 characters into str, write scanf(“%20s”, str); If you enter more than 20 characters, only the first 20 characters, are placed into str because of the maximum field width specifier. If another scanf() call is made, the remaining characters will be used by that.
Nature Thoughts & Symmetry
36
The Preprocessor We can include various instructions to the compiler in the source code of a c program. These are called preprocessor directives, and they expand the scope of the programming environment. The preprocessor directives are shown here: #define #include #if #else #line #under #line #pragma #elif #endif #ifdef #ifndef All preprocessor directives begin with a # sign. In addition, each preprocessing directive must be on it own line. #define The #define directive defines an identifier and a character sequence (a set of characters) that will be substituted for the identifier each time it is encountered in the source file. The identifier is referred to as a macro name and the replacement process as macro replacement. #define macro-name char-sequence 9 Notice that there is no semicolon in this statement. There may be any number of spaces between the identifier and the character sequence, but once character sequence begins, it is terminated only by a newline. 9 Once a macro name has been defined, it may be used as part of the definition of other macro names. For example: #define ONE 1 #define TWO ONE+ONE 9 No text substitution occur if the identifier is within a quoted string. 9 Note that char-sequence can be a integer (then use %d or %u in printf()), float (%f) double (%lf), a condition (or function) that deals with numbers (integral, floating, double) only, or it can be set of statements. 9 If the character is longer than one line, you may continue it on the next by placing a backslash at the end of the line, as shown here: #define LONG_STRING “this is a very long \ String that is used as an example” 9 C programmers often use uppercase letters for defined identifiers. This convention helps anyone reading the program know at a glance that a macro replacement will take place. Also, it is usually best to put all #define at the start of the file or in a separate header file rather than sprinkling them throughout the program. Defining Function-like Macros The #define directive has another powerful feature: The macro name can have arguments. Each time the macro name is encountered, the arguments used in its definition are replaced by the actual arguments found in the program. This form of a macro is called a function-like macro. For example: #define CONDITION(a) 8<=(a)<11 The parentheses that enclose ‘a’ ensure proper substitution in all cases. #include The #include directive tells the compiler to read the another source file in addition to the one that contains the #include directive. The name of the source file must be enclosed between double quotes or angle brackets. #include “stdio.h” #include <stdio.h>
Nature Thoughts & Symmetry
37
9 Both cause the compiler to read and compile the header for the I/O system library functions. Include files can have #include directives in them. This is referred to as nested includes. 9 Whether the filename is enclosed by quotes or by angle brackets determines how the search for the specified file is conducted. If the file name is enclosed in angle brackets, the file is searched for in a manner defined by the creator of the compiler. Often, this means searching some special directory set aside for include files. If the filename is enclosed in quotes, the file is looked for in another implementationdefined manner. For many compilers, this means searching the current working directory. If the file is not found, the search is repeated as if the filename had been enclosed in angle brackets.
Nature Thoughts & Symmetry
38
Structures Declaration of a Structure A structure is a definition of new a data-type. It contains a number of old data-types grouped together. These data-types may or may not be of the same type. The general form of a structure is given below (definition of new-data type): struct <struct_name> { Declaration of <structure_element_1>; Declaration of <structure_element_2>; … }; Once the new structure data-type has been defined one or more variables can be declared to be of that type. Now, ‘struct <struct_name>’ will start functioning as new-data type. struct <struct_name> <structure_variables_1>, …, <structure_variable_n> ; Initializing a structural variable Like primary variables and arrays, structure-variables can also be initialized where they are declared. The format used is quite similar to that used to initiate arrays. struct book { char name[10]; float price; int pages; }; struct book b1 = {“Basic”, 130.00, 550}; struct book b2 = {“Physics”, 150.50, 800}; Note that the definitions like above, can be done only during declaration. The ‘structure variables’ to which definition is to be done, should not be part of ‘array of structure variables’. Whatever be the elements of a structure, they are always stored in contiguous memory locations. Accessing Structure-variable’s elements In arrays we can access individual elements of an array using a subscript. Structures use a different scheme. They use a dot (.) operator. So to refer to pages of book b1 we have to use; b1.pages That is, <structure_variable>.<structure_element> We can treat it as our simple variable (just forget <structure_variable> and dot-operator) Array of structure The way of declaring and accessing an array of structures is given below: Declaration: struct book { char name[10]; float price; unsigned int pages; }; struct book b[50];
Nature Thoughts & Symmetry
Accessing: int i; for (i=0, i<=49, i++) { printf(“\nEnter name, prices and pages”); scanf(“%c %f %u”, &b[i].name, &b[i].price, &b[i].pages); }
39
Additional features Assigning one structure variable to another The value of a structure variable can be assigned to another structure variable of the same type using the assignment operator. We do not need to assign the value of each member separately. Both structures must be of same structure-type. Passing a structure variable to a function Passing structure-variable’s members to functions: When we pass a member of a structure-variable to a function, we are passing the value of that member to the function. It is irrelevant that the value is obtained from a member of a structure. Passing entire structure-variable to functions: When a structure-variable is used as an argument to a function, the entire structure-variable is passed using the normal call-by-value method. When using a structure as a parameter, remember that the type of the argument must match the type of the parameter. It is not sufficient for them simply to be physically similar; their type names must match. Thus in this case, structure definition should be global, and both argument and parameter structures should be of structure-type defined globally. Nesting of structures One structure can be nested within another structure. Using this facility complex data types can be created. main() { struct address { char phone[15]; char city[25]; int pin; }; struct emp { char name[25]; struct address a; } struct emp e = {“jeru”, “5311024”, “nagpur”, 10}; }
printf(“\ncity = %s pin = %d”, e.a.city, e.a.pin);
Structure-pointers Use of pointer to structure:
Nature Thoughts & Symmetry
40 There are two primary uses for structure pointers: to pass a structure to a function using call by reference and to create linked lists and other dynamic data structure that rely on dynamic allocation. This heading covers the first use. There is one major drawback to passing all but the simplest structures to functions: the overhead needed to push the structure onto the stack when the function call is executed. (Recall that arguments are passed to functions on the stack.) For simple structure with few members, however, or if some of its members are arrays, run-time performance may degrade to unacceptable levels. The solution to this problem is to pass a pointer to the structure. When a pointer to a structure is passed to a function, only the address of the structure is pushed on the stack. This makes for very fast function calls. A second advantage, in some cases, is that passing a pointer makes it possible for the function to modify the contents of the structure used as the argument. Assigning pointer to structure: To find the address of a structure variable, place the & operator before the structure’s name. For example, the following places the address of the structure person into the pointer p. struct bal *p, person; p = &person; Accessing structures-pointer’s elements To access the member of a structure using a pointer to that structure, we must use the -> operator. For example, this references the variable named balance of structure named person and type bal. p->balance The -> is usually called the ‘arrow operator’. The arrow is used in place of the ‘dot operator’ when you are accessing a structure member through a pointer to the structure. The typedef You can define new data type names by using the keyword typedef. You are not actually creating a new data type, but rather defining a new name for an existing type. The general form of typedef statement is: typedef type new_name; where, type is any valid data type, and new_name is the new name (preferably in CAPS) for this type. The new name you define is in addition to, not a replacement for, the existing type name. For example: typedef float BALANCE; typedef struct node *NODE; This statement tells the compiler to recognize BALANCE as another name for float. Next, you could create a float variable using BALANCE; BALANCE over_due; NODE p; //Here, p is a pointer of the type (strut node *). Now the BALANCE has been defined, it can be used in another typedef. typedef BALANCE OVERDRAFT;
Nature Thoughts & Symmetry
41
PART-3
Nature Thoughts & Symmetry
42
File Input/ Output Opening and reading a file There is an inbuilt structure called FILE, which is template for properties and data of a file. So, all the information of a file is arranged in a structural manner. Once the file has been opened for reading using fopen() the file’s contents are brought into buffer and a pointer is set up that points to the first character in the buffer. The function fopen() gives the starting address of this information when the contents of the file are brought into buffer. So, the pointer assigned to this address is a structure pointer. The FILE structure has been defined in the header file “stdio.h”. If we attempt to open a file (say new.txt) using fopen() function, the file will be loaded in buffer and its starting address will be assigned to file-pointer (say fp). If it finds error in opening the file, the file-pointer will be made NULL pointer. After successful opening, whatever we do with file, the address to which fp points will not change. Change in cursor position, does not alters the address to which fp points. Even if we close that file, file-pointer shows the same address, unless we assign it to some other address. Opening the file FILE *fp; (No need to write struct here, as FILE is inbuilt structure) fp = fopen(“PRI.C”, “r”); Instead of name of the file in double quotes, we can use a pointer to a string also. Note that fopen() performs four important tasks when you open the file in “r” mode. a) Firstly it searches on the disk the file to be opened. b) Then it loads the file from the disk into a place in memory called buffer. c) It sets up a character pointer that points to the first character of the buffer. d) If it finds any problem in opening the desired file, then it makes fp to be a NULL pointer (pointer pointing to 0 address). Closing the file When we have finished reading from the file, we need to close it. This is done using the function fclose() through the statement, fclose(fp); When we attempt to write characters into this file using fputc() the characters would get written to the buffer. When we close this file using fclose() three operations would be performed: a) The characters in the buffer would be written to the file on the disk. b) At the end of file a character with ASCII value 26 would get written. c) The buffer would be eliminated from memory. d) After successfully closing the file, there will be no change in addresses to which fp starts pointing (just before and after closing the file). But, fclose(fp) returns a zero value. You may imagine a possibility when the buffer may become full before we close the file. In such a close the buffer’s contents would be written to the disk the moment it becomes full. All this buffer management is done for us by the library functions. Errors and End of the file Error in opening the file To detect any error in opening the file, such as a write-protected or full-disk, before our program attempts to write to it, use the following code: FILE *fp; //After this, fp will point to some Garbage Address clrscr(); //Important to include
Nature Thoughts & Symmetry
fp = fopen(“Test”, “r”); if (fp == NULL) { printf(“Error in opening the file\n”); getch(); exit(0); }
43
Error in closing the file A return value of zero signifies a successful close operation (that’s strange, as usually we associate non-successful operation with zero). The function returns EOF if an error occurs. Generally, fclose() will fail only when a disk has been prematurely removed from the drive or there is no more space on the disk. if (fclose(fp) != 0) { printf(“\nError in closing the file”); getch(); } Determining end of the file The getc() returns EOF when it fails and when it reaches the end of the file. Using only the return value of getc(), it is impossible to know which occurred. C includes the function feof(), which determines when the end of the file has been encountered. Note that feof() returns true if the end of the file has been reached; otherwise it returns zero. The following routine reads a file until end of the file is encounter. for ((i=0);(!feof(fp));(++i)) { ch = getc(fp); putchar(ch); } We can use ‘feof(fp)==0’ instead of ‘!feof(fp)’ File Opening Modes Following is a list of all possible modes in which a file can be opened. The tasks performed by fopen() when a file is opened in each of these modes are also mentioned. “r” Which file: Searches for already existing file. Operations possible: Initially pointer points to the first character in the file. Only reading the already existing contents. “w” Which file: First searches for already existing file. If file doesn’t exist, new file is created. Operations possible: Initially pointer points to the first character in the file. Already existing data can be modified. Just written data can also be modified. Printing will result in display error. “a” Which file: First searches for already existing file. If file doesn’t exist, new file is created. Operations possible:
Nature Thoughts & Symmetry
Initially pointer points just after the last character of already existing data. Thus, already existing data can not be modified or accessed. After writing the data there pointer points to next position, and this becomes its minimum position. Thus, just written data can also not be modified nor accessed.
44
“r+” Complete access to already existing file. Note that after writing anything (even a single character) anywhere (even in middle of the file) in the file, if we are interested in reading; we must set pointer of the file. In case we are interested only in reading the further part of the file, even then we must use: fseek ( fp , 0, SEEK _ CUR ); Also note that after writing anything to a file, we can not use the condition ! feof ( fp ) until we close that file using fclose ( fp ) and open it again. “w+” (“w” + reading) “a+” (“a” + reading) If you are interested in writing, it behaves just as “w”. If you are interested in reading, all the contents of the file (both already existing and just written) can be read out. Thus, pointer may be set to point to first character of the file. Reading and Writing in files Input: fgets(p, strlen(p)+1, fp), ch = getc(fp) Output: fputs(p, fp), putc(ch, fp) Note that no new-line character will be written automatically by fputs(). The putc() function Input: Its syntax is given below: putc(ch, fp); putc(‘character_constant’, fp); Working: The putc() function writes characters to a file that was previously opened for writing using fopen() function. New line will not be printed automatically. Return value: If putc() operation is successful, it returns the character written. Otherwise, it returns EOF. The getc() function Input: Its syntax is given below: ch = getc(fp); Working: The getc() function reads characters from a file opened in read mode by fopen(). Return Value: The getc() function returns an EOF when the end of the file has been reached. However, getc() also returns EOF if an error occurs. The fputs() function Input: Syntax: fputs ( str , fp ); Working:
Nature Thoughts & Symmetry
The fputs() function writes the string pointed to by str to the specified stream. No new-line character is written automatically (unlike puts()). Return Value: It returns EOF if an error occurs.
45
The fgets() function Note: Do not practice this function. Input: Its syntax is given below: fgets ( str , length , fp ); where, length = strlen ( str ) + 1; Working: The fgets () function reads a string from the specified stream until either a newline character is read or a maximum of length − 1 characters have been read. If a newline is read, it will be part of the string (unlike the gets() function). The resultant string will always be null terminated. A newline character is always kept in str by fgets () after length − 1 characters or already read newline character. Cases 1: Characters before newline (in specifies stream) ≥ length − 1 The string str : M U N I S \n \0 Case 2: Characters before newline = length − 2 The string str : S I T A \n \n \0 Case 3: Characters before newline = length − 3 The string str : R A M \n \n \0 You do not need to add the null to the end Return value: The function returns str if successful and null pointer if an error occurs. Flushing a Stream If you wish to flush the contents of an output stream, use the fflush() function. fflush(fp); This function writes the contents of any buffered data to the file associated with fp. If you call fflush() with fp being null, all files opened for output are flushed. The fflush() function returns zero if successful; otherwise, it returns EOF. The fread() function For fread(), buffer is a pointer to a region of memory (for instance an integer-array) that will receive the data from the file. The value of count determines consecutively how many times are read, with each item being num_bytes bytes in length. Finally, fp is a file pointer to a previously opened stream. fread(void *buffer, size_t num_bytes, size_t count, FILE *fp); For example: num[3];
Nature Thoughts & Symmetry
46
fread(&num, sizeof(int), 3, fp);
The fwrite() function For fwrite(), buffer is a pointer to a information (for instance an integer-array) that will be written to the file. The value of count determines consecutively how many times are written, with each item being num_bytes bytes in length. Finally, fp is a file pointer to a previously opened stream. fwrite(const void *byffer, size_t num_bytes, size_t count, FILE *fp); For example: num[3] = {2, 4, 6}; fwrite(&num, sizeof(int), 3, fp); Changing the cursor position The rewind() function Do not practice it. The rewind() function resets the file position indicator to the beginning of the file (to where the pointer was pointing initially when file was opened) specified as its argument. rewind(fp); The fseek() Random-Access I/O You can perform random read and write operations using the C I/O system with the help of fseek(), which sets the file position indicator. Its prototype is shown here: int fseek(FILE *fp, long int numbytes, int origin); Here, fp is a file pointer returned by a call to fopen(), numbytes is the number of bytes from origin, which will become the new current position, and origin is one of the following macros: Origin Macro Name Beginning of file SEEK_SET Current position SEEK_CUR End of file SEEK_END You can use fseek() to seek in multiples of any type of data by simply multiplying the size of the data by the number of the item you want to reach. For example: fseek(fp, -(9*sizeof(struct addr)), SEEK_CUR); You can determine current location of a file using ftell(). Its prototype is long int ftell(FILE *fp); It returns the location of the current position of the file associated with fp. If a failure occurs, it returns -1. Counting No. of characters in a C-program Count each of new-line (‘\n’) and a tab (‘\t) as 1 character. The spaces that we insert at the end of each line, while writing a C-program, are not counted. But if we wish to deliberately insert spaces after any line, then first complete program using C and then edit that “*.c” file using “notepad” and insert spaces. Our writing will replace the character next to out cursor position. While reading, treat newline character as one character, but while writing treat it as 2 characters.
Nature Thoughts & Symmetry