Top Banner
Problem Solving and Logic Building using C Prepared by Mr. K. G. Page 1 Unit-1 Elements of C Language 1.1 Algorithm: In order to write computer programs without any logical error, it is recommended programmers prepare a rough writing showing the steps involved in the program. This is called algorithm. An algorithm presents step-by-step instructions required to solve any problem. These steps can be shown diagrammatically using a flowchart. Example: 1. Read a, b 2. Sum a + b 3. Product a × b 4. Print sum, product 5. Stop Characteristics of Algorithm: Finiteness: Finiteness implies that algorithm may have finite number of steps also the time taken to execute all the steps of the algorithm should be finite. Definiteness: Each step of the algorithm is precisely defined, i.e. the actions to be carried out should be specified unambiguously. Effectiveness: All the operations used in the algorithm are basic (division, multiplication, comparison etc) and can be performed exactly in a ‘fixed duration of time’. Input: The term input means supplying initial data for algorithm. These data must be present before any operations can be performs. Generally the initial data is supplied by a READ instruction or a variable can be give initial values using SET. Output: The term output refers to the result obtained when all the steps of algorithm have been performed. An algorithm must have atleast one output. Advantages of Algorithm: It is simple to understand step by step by step solution of the problem. It is easy to debug i.e. errors can be easily pointed out. It is independent of programming languages. It is compatible to computers in the sense that each step of algorithm can be easily coded into the equivalent in high level language. 1.2 Flowchart: Flowchart is a symbolic or diagrammatic representation of an algorithm. It uses several geometrical figures to represent the operations, and arrows to show the direction of flow. The flowcharts are read from left to right and top to bottom. Following are the commonly used symbols in the flowcharts. Symbol Operation Meaning Start/ Stop Represents the beginning and the end of the flowchart. Input/ Output Represents the values to be given by the user and the results to be displayed. Processing Represents the arithmetic operations to compute a value.
122
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 1

Unit-1 Elements of C Language

1.1 Algorithm: In order to write computer programs without any logical error, it is recommended programmers prepare a rough writing showing the steps involved in the program. This is called algorithm.

An algorithm presents step-by-step instructions required to solve any problem. These steps can be shown diagrammatically using a flowchart. Example:

1. Read a, b 2. Sum ← a + b 3. Product ← a × b 4. Print sum, product 5. Stop

Characteristics of Algorithm:

Finiteness: Finiteness implies that algorithm may have finite number of steps also the time taken to execute all the steps of the algorithm should be finite.

Definiteness: Each step of the algorithm is precisely defined, i.e. the actions to be carried out should be specified unambiguously.

Effectiveness: All the operations used in the algorithm are basic (division, multiplication, comparison etc) and can be performed exactly in a ‘fixed duration of time’.

Input: The term input means supplying initial data for algorithm. These data must be present before any operations can be performs. Generally the initial data is supplied by a READ instruction or a variable can be give initial values using SET.

Output: The term output refers to the result obtained when all the steps of algorithm have been performed. An algorithm must have atleast one output.

Advantages of Algorithm:

It is simple to understand step by step by step solution of the problem. It is easy to debug i.e. errors can be easily pointed out. It is independent of programming languages. It is compatible to computers in the sense that each step of algorithm can be easily coded into

the equivalent in high level language. 1.2 Flowchart: Flowchart is a symbolic or diagrammatic representation of an algorithm. It uses several geometrical figures to represent the operations, and arrows to show the direction of flow. The flowcharts are read from left to right and top to bottom. Following are the commonly used symbols in the flowcharts.

Symbol Operation Meaning

Start/ Stop Represents the beginning and the end of the flowchart.

Input/ Output Represents the values to be given by the user and the results to

be displayed.

Processing Represents the arithmetic operations to compute a value.

Page 2: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 2

Check/ decision making Represents the logical checking to decide the flow sequence.

Looping Represents the looping which is repeated based on a condition/ value of a variable.

Connector Represents the continuity of the flowchart in other place/ page.

Arrows Represents direction of flow.

Example:

Flowcharting Rules:

1. First consider the main logic, and then incorporate the details. 2. Maintain a consistent level of detail for a given flowchart. 3. Do not include all details in a flowchart. 4. Words in the flowchart symbols should be common statement and easy to understand. Use

meaningful descriptions in the flowchart symbols. 5. Be consistent in using names and variables in the flowchart. 6. Go from left to right and top to bottom in constructing flowcharts. 7. Keep the flowchart as simple as possible. The crossing of flow lines should be avoided as for

as practicable. 8. If a new flowcharting page is needed it is recommended that the flowchart be broken at an

input or output point. Moreover properly labeled connectors should be used to link the portions of the flowchart on different pages.

Advantages of Flowcharts

1. Better Communication 2. Effective Analysis 3. Effective Synthesis 4. Proper Program Documentation 5. Efficient Coding 6. Systematic Debugging 7. Systematic Testing

Page 3: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 3

1.3 History of C: C was developed at Bell Laboratories in 1972 by Dennis Ritchie. Many of its principles and ideas were taken from the earlier language B and B's earlier ancestors BCPL and CPL. CPL (Combined Programming Language) was developed with the purpose of creating a language that was capable of both high level machine independent programming and would still allow the programmer to control the behavior of individual bits of information. The one major drawback of CPL was that it was too large for use in many applications.

In 1967, BCPL (Basic CPL) was created as a scaled down version of CPL while still retaining its basic features. In 1970, Ken Thompson, while working at Bell Labs, took this process further by developing the B language. B was a scaled down version of BCPL written specifically for use in systems programming.

Finally in 1972, a co-worker of Ken Thompson, Dennis Ritchie, returned some of the generality found in BCPL to the B language in the process of developing the language we now know as C.

C's power and flexibility soon became apparent. Because of this, the UNIX operating system which was originally written in assembly language was almost immediately re-written in C (only the assembly language code needed to "bootstrap" the C code was kept).

During the rest of the 1970's, C spread throughout many colleges and universities because of its close ties to UNIX and the availability of C compilers. Soon, many different organizations began using their own versions of C causing compatibility problems.

In response to this in 1983, the American National Standards Institute (ANSI) formed a committee to establish a standard definition of C which became known as ANSI Standard C. Today C is in widespread use with a rich standard library of functions. Why C is called as C language? Because it is developed after the B language. The B language has been developed also in Bell Labs by Key Thompson. The C itself is improvement on the B language. Why C is called Middle Level Language: C Programming language is called as Middle Level Language because

1. It gives or behaves as High Level Language through Functions - gives a modular programming and breakup, increased efficiency for reusability

2. It gives access to the low level memory through Pointers. Moreover it does support the Low Level programming i.e. Assembly Language.

As it is a combination of these two aspects, it is neither a High Level nor a Low level language but a Middle Level Language. 1.4 Advantages of C Language

C is a building block for many other currently known languages. Take a look at Python for example a fully Object-Oriented High-Level programming language. It is written in C (perhaps C++ too). That tells you if you ever want to know what is going on under the hood in other languages; understanding C and how it works is essential.

A lot of libraries are written in C and it's easy to find reference code, and to get support. The main advantage of C language is that there is not much vocabulary to learn, and that the

programmer can arrange for the program is very fast. C programming language is very easier to learn. C programming language is still a practical and compact language. It comprises a good semantic. Syntax is of C is clear also.

Page 4: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 4

C language is very near to assembly programming i.e. the hard use of pointers for example is a very powerful mechanism.

C has features that allow the programmer to organize programs in a clear, easy, logical way. For example, C allows meaningful names for variables without any loss of efficiency, yet it gives a complete freedom of programming style, including flexible ways of making decisions, and a set of flexible commands for performing tasks repetitively (for, while, do).

C is a portable language. 1.5 Disadvantages of C Language

C does not have OOPS feature that's why C++ is developed. If you know any other modern programming language then you already know its disadvantages.

There is no runtime checking in C language. There is no strict type checking (for ex: we can pass an integer value for the floating data

type). C doesn't have the concept of namespace. C doesn't have the concept of constructors and destructors. As the program extends it is very difficult to fix the bugs.

1.6 Library Functions: The C language has a wide range of library functions. A function is a self-contained program segment that carries out some specific task to carry out various commonly used operations or calculations. The other names of library functions are standard functions, built-in-functions or pre-defined functions, as they are not written (define) by the user or programmer, during development of the program. Example: Suppose we want to calculate the square root of 9 in mathematics we will write √9 gives 3 but in C programming, it will carried out by using library function sqrt() as follows: sqrt(9) gives 3 1.7 Header Files: To use the library functions successfully, it is necessary to include certain specific information (regarding their definition and prototype) in our main portion of the program. These information are generally stored in special files which are supplied with the compiler. These special files that contain details of functions and types used in the library is called header file with extension .h in the include directory. Some commonly used header files are stdio.h and math.h. The suffix “h” generally designates a “header” file. Note: Header files must be included at the beginning of the program of before the program can make use of library functions.

Function Data Type Task ctype.h isalnum(c) int Determine if argument is alphanumberic. Return nonzero value if

true; 0 otherwise. isalpha(c) int Determine if argument is alphanumeric. Return nonzero value if

true; 0 otherwise. isascii(c) int Determine if argument is an ASCII character. Return nonzero value

if true; 0 otherwise. iscntrl(c) int Determine if argument is an ASCII control character. Return

nonzero value if true; 0 otherwise. isdigit(c) int Determine if argument is a decimal digit. Return nonzero value if

true; 0 otherwise. isgraph(c) int Determine if argument is a graphic printing ASCII character.

Page 5: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 5

Return nonzero value if true; 0 otherwise. islower(c) int Determine if argument is lowercase. Return nonzero value if true; 0

otherwise. isodigit(c) int Determine if argument is an octal digit. Return nonzero value if

true; 0 otherwise. isprint(c) int Determine if argument is a printing ASCII character. Return

nonzero value if true; 0 otherwise. ispunct(c) int Determine if argument is a punctuation character. Return nonzero

value if true; 0 otherwise. isspace(c) int Determine if argument is a whitespace character. Return nonzero

value if true; 0 otherwise. isupper(c) int Determine if argument is uppercase. Return nonzero value if true; 0

otherwise. isxdigit(c) int Determine if argument is a hexadecimal digit. Return nonzero

value if true; 0 otherwise. toascii(c) int Convert value of argument to ASCII. tolower(c) int Convert letter to lowercase. toupper(c) int Convert letter to uppercase. <math.h> acos(d) double Return the arc cosine of d. asin(d) double Return the arc sine of d. atan(d) double Return the arc tangent of d. atan2(d1,d2) double Return the arc tangent of d1/d2. ceil(d) double Return a value rounded up to the next higher integer. cos(d) double Return the cosine of d. cosh(d) double Return the hyperbolic cosine of d. exp(d) double Raise e to the power h. fabs(d) double Return the absolute value of d. floor(d) double Return a value rounded down to the next lower integer. fmod(d1,d2) double Return the remainder of d1/d2 (with same sign as d1). labs(l) long int Return the absolute value of l. log(d) double Return the natural logarithm of d. log10(d) double Return the logarithm (base 10) of d. pow(d1,d2) double Return d1 raised to the d2 power. sin(d) double Return the sine of d. sinh(d) double Return the hyperbolic sine of d. sqrt(d) double Return the square root of d. tan(d) double Return the tangent of d. tanh(d) double Return the hyperbolic tangent of d. <stdio.h> fclose(f) int Close file f. return 0 if file is successfully closed. feof(f) int Determine if an end-of-file condition has been reached. If so, return

a non zero value; otherwise return 0. fgetc(f) int Enter a single character from file f. fgets(s,i,f) har* Enter string s, containing I characters, from file f. fopen(s1,s2) file* Open a file named s1 of type s2. Return a pointer to the file. fprintf(f,…) int Send data items to file f. fputc(c,f) int Send a single character to file f. fputs(s,f) int Send string s to file f. fread(s,i1,i2,f) int Enter i2 data items, each of size i1 bytes, from file f to string s. fscanf(f,…) int Enter data items from file f. fseek(f,l,i) int Move the pointer for file f a distance 1 bytes, from location i. ftell(f) long int Return the current pointer position within file f.

Page 6: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 6

fwrite(s,i1,i2,f) int Send i2 data items, each of size i1 bytes from string s to file f. getc(f) int Enter a single character from file f. getchar(void) int Enter a single character from standard input device. gets(s) char* Enter string s from standard input device. printf(…) int Send data items to the standard output device. putc(c,f) int Send a single character to file f. putchar(c) int Send a single character to the standard output device. puts(s) int Send string s to the standard output device. rewind(f) void Move the pointer to the beginning of file f. scanf(..) int Enter data items from the standard input device. <stdlib.h> abs(i) int Return the absolute value of i. atof(s) double Convert string s to a double-precision quantity. atoi(s) int Convert string s to a integer. atol(s) long Convert string s to a long integer. calloc(u1,u2) void* Allocate memory foe an array having u1 elements, each of length

u2 bytes. Return a pointer to the beginning of the allocated space. exit(u) void Close all files and buffers, and terminate the program. (value of u is

assigned by the function, to indicate termination status). free(p) void Free a block of allocated memory whose beginning is indicated by

p. malloc(u) void* Allocate u bytes of memory. Return a pointer to the beginning of

the allocated space. rand(void) int Return a random positive integer. relloc(p,u) void* Allocate u bytes of new memory to the pointer variable p. return a

pointer to the beginning of the new memory space. srand(u) void Initialize the random number generator. system(s) int Pass command string s to the operating system. Return 0 if the

command is successfully executed; otherwise, return a nonzero value typically -1.

1.8 Debugger: Debugger is a program which runs other programs in such a way as to let you see every step of program execution. A debugger will let you stop the program while it is running, change the program or program variables, and start the program running again.

Difference between Debugger and Compiler

Debugger Compiler Debugger is another program that is used for testing and debugging purpose of other programs. Most of the time it is using to analyze and examine error conditions in application. It will be able to tell where exactly in your application error occurred, give you all needed addressed of variables, variable representation in code, stack trace and all other low level and sometimes high level information. Debugger allows you to run your code step by step, make breakpoints in application (to examine specific parts of code) and it can halt application after it crashed in order to examine the problem.

Compiler is special software or set software that translates source code from one computer language to another, in most cases from high-level programming language to low-level programming language.

Page 7: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 7

1.9 COMPILERS, ASSEMBLERS and LINKERS Normally the C’s program building process involves four stages and utilizes different ‘tools’

such as a preprocessor, compiler, assembler, and linker. At the end there should be a single executable file. Below are the stages that happen in order

regardless of the operating system/compiler and graphically illustrated in figure. 1) Preprocessing is the first pass of any C compilation. It processes include-files,

conditional compilation instructions and macros. 2) Compilation is the second pass. It takes the output of the preprocessor, and the source

code, and generates assembler source code. 3) Assembly is the third stage of compilation. It takes the assembly source code and

produces an assembly listing with offsets. The assembler output is stored in an object file.

4) Linking is the final stage of compilation. It takes one or more object files or libraries as input and combines them to produce a single (usually executable) file. In doing so, it resolves references to external symbols, assigns final addresses to procedures/functions and variables, and revises code and data to reflect new addresses (a process called relocation).

5) The following Figure shows the steps involved in the process of building the C program starting from the compilation until the loading of the executable image into the memory for program running.

Here is a simple table showing input and output of each step in the compilation and execution process:

Input Program Output Source Code Preprocessor Expanded Source Code Expanded Source Code Compiler Assembly Source Code Assembly Code Assembler Object Code Object Code Linker Executable Code Executable Code Loader Execution

Page 8: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 8

Figure Compile, link and execute stages for running program (a process)

Number of files created when c source file is compiled

1. .c // source code 2. .i // preprocessor 3. .obj // object file 4. .bak // backup file 5. .exe // executable file

Linker and Loader: Linker is a stage before loader. Linker is a person who is responsible for linking the different object file and the outcome will be a executable file. Loader is a person who reads the content of executable files and placed it into memory. This code shall be executed when the operating system control is coming to the loaded program. The compilation and execution process of C can be divided in to multiple steps:

Page 9: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 9

Preprocessing - Using a Preprocessor program to convert C source code in expanded source code. "#includes" and "#defines" statements will be processed and replaced actually source codes in this step.

Compilation - Using a Compiler program to convert C expanded source to assembly source code.

Assembly - Using a Assembler program to convert assembly source code to object code. Linking - Using a Linker program to convert object code to executable code. Multiple units of

object codes are linked to together in this step. Loading - Using a Loader program to load the executable code into CPU for execution.

Here are examples of commonly used programs for different compilation and execution steps on a Linux system:

"cpp hello.c -o hello.i" - Preprocessor preprocessing hello.c and saving output to hello.i. "cc1 hello.i -o hello.s" - Compiler compiling hello.i and saving output to hello.s. "as hello.s -o hello.o" - Assembler assembling hello.s and saving output to hello.o. "ld hello.o -o hello" - Linker linking hello.o and saving output to hello. "load hello" - Loader loading hello and running hello.

Simple Flowchart of Executing a C Program:

Running a Program Using Turbo C: Turbo C comprises turbo text editor and C compiler. Turbo C compiler is easy to learn and fast in compilation. It is an interactive compiler in MS-DOS environment. Consider the following steps to run C programs in Windows operating system. Step 1: Select Start → Program → MS-DOS prompt (or select MS DOS icon from the desktop, if displayed) Now the computer displays the system prompt (C:\>)

Page 10: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 10

Step 2: Type C:\>tc Now the turbo editor is displayed

Step 3: Type all the command lines or statements of the program. Step 4: Press F2 key to save the program in suitable file name (e.g. hello.c) Step 5: Press F10 key to select the main menu. Step 6: Select Compile option or press F9 key to compile and link the program. Step 7: Press F10 key and then select Run option to run the program. Now the input values are entered and results are displayed. Then the control is transferred to the editing screen. Press Alt+F5 to switch to input/output screen to read the results. Commonly Used Turbo Editing Commands/Key Controls:

Cursor Control Keys Arrow keys To move cursor in any direction (up, down, left and right) Backspace To move cursor to the left by one place and erase the character in that position Space bar To move cursor/ character to the right by one place Delete key To delete a character after the point the cursor is placed Enter key To move cursor to a new line Insert key (on/off) To insert characters/lines Function Keys F1 Help F2 Save the program F3 Open a new file or program F4 Run program, but stop at the line where cursor is placed F5 Zoom and unzoom editing window F6 Switch to main menu Ctrl+F9 Run program ALT+F5 Switch between TC editing screen and output screen Alt+F6 Restore previous content of the screen window Alt+F9 Compile the program Alt+X Exit Turbo C Shift+F10 Identify the version of Turbo C

Page 11: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 11

Editing Keys Del Delete a character after the point the cursor is placed Ctrl+G Delete a character after the point cursor is placed Ctrl+T To delete a string of characters from the pint the cursor is placed Ctrl+Y To delete a line where the cursor is placed Block Operations Ctrl+K+B Mark the beginning of a block Ctrl+K+K Mark the end of a block Ctrl+K+C Copy the marked block in the current cursor position Ctrl+K+V Move the marked block to the current cursor position Ctrl+K+Y Delete the marked block Ctr+K+H Remove the highlighted block marks

Compiling and Running on UNIX: UNIX operating system comprises a C language compiler called cc. the commonly used editor in UNIX environment is vi editor. Consider the fillowing steps to run C programs in UNIX operating system.

Step 1: Type $vi hello.c to invoke the editor. Note that hello.c is the file name of the program.

Step 2: Press Esc+i to insert the program. Step 3: Enter the C program using keyboard. Step 4: Press Esc to exit typing. Step 5: Press Shift+: and then:wq to save the program. Step 6: Type cc hello.c to compile the program. Step 7: Type a.out to run the program.

1.10 Character Set: The C character set consists of the upper and lower case alphabets, digits, special characters and white spaces. The combination of alphabets and digits together form alphanumeric set. The complete character set is given below. Alphabets: Uppercase: A, B,….., Z Lowercase: a, b,……, z Digits: 0 1 2 3 4 5 6 7 8 9 Special Characters: , comma & ampersand . period ^ caret ; semicolon * asterisk : colon - minus sign # number sign + plus sign ‘ apostrophe < opening angle bracket “ quotation mark > closing angle bracket

! exclamation mark ( left parenthesis | vertical bar ) right parenthesis ~ tilde [ left bracket _ underscore ] right bracket $ dollar sign { left brace % percent sign } right brace

Page 12: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 12

? question mark / slash \ back slash

White Space Characters: blank space newline carriage return formfeed horizontal tab vertical tab

1.11 Variables: A variable is an entity that has a value and is known to the program by a name. A variable definition associates a memory location with the variable name. A variable can have only one value assigned to it at any given time during the execution of the program. Its value may change during the execution of the program. Example:

f=1.8*c+32 In above example, f and c are variable. 1.12 C-Tokens: A C-Token is the smallest individual unit of a C program. C has six types of tokens.

1. Keywords 2. Identifiers 3. Constants 4. Strings 5. Special Symbols 6. Operators

1.12.1 Keywords: Keywords are those words whose meaning has been fixed and is known to the compiler. We cannot change the meaning of the keywords. If we try to do then an error message will occur. Keywords serve as basic building blocks for program statements. All keywords must be written in lowercase. Example:

auto break Case char Continue default do double else Float for goto if int Long return static switch void While

1.12.2. Identifiers: Identifiers refers to the names of variables, functions, and arrays. They are the fundamental requirement of any language. Identifiers are user defined name and consists of a sequence of letters and digits, with a letter as a first character.

Both uppercase and lowercase letters are permitted although lowercase letters are commonly used. The underscore character is also permitted in identifiers. It is usually used as a link between two words in long identifiers. The following rules should be followed when an identifier is named:

(a) An identifier must begin with a letter and must be followed by letters and digits. (b) Underscore is permitted and considered as a letter. (c) A declared keyword (such as int, char, void, if, for, while, etc) cannot be used as a

variable name. (d) C is case sensitive.

Example: a, b, name, str, no, n, fact etc. 1.12.3. Constants: Constant in C refers to fixed values that do not change during the execution of a C program. C supports several types of constants as shown in fig.

Page 13: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 13

Figure Basic types of C constant

Numeric Constant: Integer and floating point constants are collectively referred as numeric constant.

1. Integer Constant: An integer constant refers to a sequence of digits. These are whole numbers without any fractional part. The following rules are allowed for constructing integer constant:

(a) It must have atleast one digit. (b) It must not contain a decimal point. (c) It may either plus or minus sign. (d) When no sign is present it is assumes be positive. (e) Commas and blanks are not permitted.

There are three types of integers: (a) Decimal integer (base 10) (b) Octal integer (base 8) (c) Hexadecimal integer (base 16)

2. Real Constant: These have fractional parts to represent quantities like average, height, area

etc. which cannot be written in either fractional form or exponent form. Example: 215.007 Fractional form 2.1565 e 2 Exponent form 3.44 E 3 The exponent form consists of two parts mantissa and exponent Mantissa e exponent The following rules are followed for constructing real constant in exponent form.

(a) The mantissa and exponent are separated by e. (b) The mantissa must be either an integer or a proper real constant. (c) The mantissa may either plus or minus sign. When no sign is present it is assumes be

positive. (d) The exponent must be at least one digit integer.

Character Constant: Single character and string constants are collectively referred as character constant.

1. Single Character Constant: A single character contains a single quote marks. A character constant cannot be a length more than 1. Examples: ‘3’ ‘x’ ‘;’ ‘ ‘ etc.

2. String Constant: A string constant is a sequence of character enclosed in double quotes. The character may be letters, numbers, special characters, and blank spaces. Examples: “Hello” “1987” etc.

Page 14: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 14

An Important Difference: ‘A’ and ”A” The notations ‘A’ and “A” have an important difference: the first (‘A’) is a character constant, while the second (“A”) is a string constant. The notation ‘A’ is a constant occupying a single byte containing the ASCII code of the character A. The notation “A” on the other hand, is a constant that occupies two bytes, one for the ASCII code of A and another for the null character with the value 0, that terminates all strings.

1.12.4 Operands and Expression: The data items that operators act upon are called operands. Operation instructions are specified by operators (like +, −, *, / etc.) while operand can be variables or expressions. Example: In a + b, a and b are operands while ‘+’ is the operator.

An expression is a combination of variables, constants and operators written according to the syntax of the language. In C, every expression evaluates to a value i.e. every expression result in some value of a certain type that can be assigned to a variable. Example: j=i=5; 1.12.5 Operator: An operator is a symbol that tells the computer to perform certain mathematical or logical manipulations. Operators are used in programs to manipulate data and variables. There are basically three types of operators.

a. Unary operators: Unary operators are those which are applied on a single operand. Some common unary operators are −, ++, −−, sizeof and cast i.e. (type) etc.

b. Binary operators: Binary operators are those which are applied on two operands. Some common binary operators are +, −, *, /, %, &&, ||, <, >, etc.

c. Ternary operator: Ternary operators are those which are applied on three operands. Ternary operator is ?: .

C operator can be classified into a number of categories: 1. Arithmetic operators 2. Relational operators 3. Logical operators 4. Assignment operators 5. Increment and decrement operators 6. Conditional operator 7. Bitwise operators 8. Special operators

1. Arithmetic Operators:

C provides all the arithmetic operators. They are listed in table. The operators +, −, * and / all work the same way as they do in other languages. The unary minus operator negate the value of a variable by putting minus (−) sign

prefix of the number or variable.

Operators Meaning + Addition

− Subtraction

* Multiplication

Page 15: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 15

/ Division % Modulus (remainder)

1) Integer Arithmetic: An arithmetic operation involving only integer operands is called integer arithmetic. Example:

int x = 3, y = 2; x + y = 5 x - y = 1 x * y = 6 x / y = 1 x % y = 1

2) Real Arithmetic: An arithmetic operation involving only real operands is called integer

arithmetic. Example:

float x = 3.0, y = 2.0; x + y = 5.0 x - y = 1.0 x * y = 6.0 x / y = 1.50

Note: % operator is not used when both operands are real.

3) Mixed-mode Arithmetic: When one of the operand is real and the other is integer, then the expression is called mixed-mode arithmetic expression. Example:

int y = 2; float x = 3.0; x + y = 5.0 x - y = 1.0 x * y = 6.0 x / y = 1.5

2. Relational Operators:

Relational operators are used to compare the values of operands (expressions) to produce a logical value.

A logical value is either true or false. The relational operator returns zero values or nonzero values. The zero value is taken as FALSE while the nonzero value is taken as TRUE.

Operators Meaning < is less than

<= is less than equal to

> is greater than

>= is greater than equal to

== is equal to

!= is not equal to

Page 16: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 16

3. Logical Operators: Logical operators are used to connect more relational operations to form a complex

expression called logical expression. A value obtained by evaluating a logical expression is always logical, i.e. either TRUE or

FALSE.

Operators Meaning Description && logical AND If both side of the condition is true, the whole expression results

in true. || logical OR If either side of the condition is true, the whole expression results

in true. ! logical NOT If the condition is true, the whole expression results in false and

vice versa. 4. Assignment Operators:

The single “equal to” symbol (=) is called the assignment operator. It is an operator that assigns the value of the expression to the variable.

Syntax: variable = expression;

Example: x = 3; // x has value 3 Sorthand Assignment Operators: C has a rich set of sorthand assignment operators. Syntax:

variable op = expression; Where variable: It is any valid variable. op: It is a C binary operator. The operator op = known as the sorthand assignment operator.

Operators Equivalent Assignment operator Description a += 1 a = a + 1 Additional assignment (+=) a -= 1 a = a – 1 Subtraction assignment (-=)

a *= n+1 a = a * (n+1) Multiplication assignment (*=) a /= n+1 a = a / (n+1) Division assignment (/=) a %= b a = a % b Modulus assignment (%=)

5. Increment and Decrement Operators:

Increment operator (++) is used to increase the value of an integer or char variable by 1. Decrement operator (−−) is used to reduce the value of an integer or char variable by 1. These are applied on a single variable. These are two types:

1) Prefix: The value is incremented / decremented first and then applied. 2) Postfix: The value is applied and the value is incremented / decremented.

Page 17: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 17

Operators Meaning ++ variable Pre-increment operator

−−variable Pre-decrement operator variable ++ Post-increment operator

variable −− Post-decrement operator

Example:

#include<stdio.h> main() { int i=3,j=4,k; k = i++ + --j; printf("i = %d, j = %d, k = %d",i,j,k); }

Output:

i = 4, j = 3, k = 6

Difference between Prefix and Postfix Operator

Prefix Operator Postfix Operator 1. A prefix operator first

incremented/decremented the value of operand by 1 and then applied.

A postfix operator applied first and then incremented/decremented the value of operand by 1.

2. Example: int a = 1, b; b = ++a; Here the value of variable a and b is 2 because first increment the value of variable a by 1 and then assign value of a to b.

Example: int a = 1, b; b = a++; Here the value of variables a is 2 and b is 1 because the value of a is first assign to b and then it is increment by 1.

6. Conditional Operators:

This is only one operator in C that takes three operands. A conditional pair “? :” available in C to construct conditional expression of the form:

Conditional expression

result = test-expression ? expression1 : expression2;

If test-expression is TRUE then expression1 is performed and assigned to result otherwise expression2 is performed and assigned to result.

Example:

#include<stdio.h> main() { int i=2; int j=3; int k =(i>j) ? i : j; printf("\n k = %d",k); }

Page 18: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 18

7. Bitwise Operators: Bitwise operators are used to perform operations at binary digital level. These operators are not commonly used and are used in special applic ations where

optimized use of storage is required.

Operators Meaning ~ bitwise inversion (one’s complement)

>> shift the bits to right

<< shift the bits to left & bitwise logical AND | bitwise logical OR

^ bitwise XOR

Example: #include<stdio.h> main() { char c1=1,c2=2,c3=3; c3=c1 & c2; printf("\nBitwise AND i.e. c1 & c2 = %c",c3); c3=c1 | c2; printf("\nBitwise OR i.e. c1 | c2 = %c",c3); c3=c1 ^ c2; printf("\nBitwise XOR i.e. c1 ^ c2 = %c",c3); c3=~c1; printf("\nOnes complement of c1 = %c",c3); c3=c1<<2; printf("\nLeft shift by 2 bits c1 << 2 = %c",c3); c3=c1>>2; printf("\nRight shift by 2 bits c1 >> 2 = %c",c3); }

Consider the following examples to understand the use of bitwise operators when a=13 and b=6 as 8-bit sort int (1 byte).

1) ~ Bitwise Inversion (One’s Complement): Let a=13; its binary equivalent is 00001101. Consider ~a; which converts all 0’s to 1’s and all 1’s to 0’s. The result obtained in this operation is 11110010(-14).

2) >> Shift the Bits to Right: Let a=13; its binary equivalent is 00001101. Consider a>>2; which shifts two bits to the right. That is, the zeros are inserted at the left to shift two bits at the right to move out as shown below.

Insert 2 bits at the left 00 00001101 2 bits move out

Page 19: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 19

The result obtained in this operation is 00000011(3).

3) << Shift the Bits to Left Let a=13; its binary equivalent is 00001101. Consider a<<2; which shifts two bits to the left. That is, the zeros are inserted at the right to shift two bits at the left to move out as shown below.

00 Insert 2 bits at the right

00001101

2 bits move out

The result obtained in this operation is 00110100 (52).

Example:

#include <stdio.h> void displayBits(unsigned value); void main() { unsigned number1=960; printf("\nThe result of left shifting\n"); displayBits(number1); printf("8 bit positions using the "); printf("left shift operator << is\n"); displayBits(number1 << 8); printf("\nThe result of right shifting\n"); displayBits(number1); printf("8 bit positions using the "); printf("right shift operator >> is\n"); displayBits(number1 >> 8); } void displayBits(unsigned value) { unsigned c; unsigned displayMask=1<<31; printf("%7u=", value); for(c=1;c<=32;c++) { putchar(value & displayMask ? '1' : '0'); value <<= 1; if(c%8==0) { putchar(' '); } } putchar('\n'); }

Output:

The result of left shifting 960 = 00000000 00000000 00000011 11000000 8 bit positions using the left shift operator << is 245760 = 00000000 00000011 11000000 00000000

Page 20: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 20

The result of right shifting 960 = 00000000 00000000 00000011 11000000 8 bit positions using the right shift operator >> is 3 = 00000000 00000000 00000000 00000011

4) & Bitwise Logical AND:

Let a=13; its binary equivalent is 00001101 b=6; its binary equivalent is 00000110 a & b produces result 00000100(4)

5) | Bitwise Logical OR

Let a=13; its binary equivalent is 00001101 b=6; its binary equivalent is 00000110 a | b produces result 00001111(15)

6) ^ Bitwise XOR Let a=13; its binary equivalent is 00001101 b=6; its binary equivalent is 00000110 a ^ b produces result 00001011(11)

8. Special Operators: C supports some special operators of interest such as comma operator, sizeof operator, pointer operators (& and *) and member selection operators (. and ->). ANSI committee has introduced two preprocessor operators known as “string-izing” and token-parsing” operators (# and ##).

1) Comma Operator: The comma operator can be used to link the related expressions together. A comma-linked list of expressions are evaluated from left to right and the value of right most expression is the value of the combined expression.

Example:

#include<stdio.h> main() { int i,j,k; k = (i = 10, j = 5, i+j); printf("k = %d",k); }

Output:

k=15

2) sizeof Operator: The sizeof operator returns the size of operand in bytes. The sizeof

operator always preceds its operand. Syntax:

sizeof(data type); sizeof(variable name);

Example:

Page 21: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 21

#include <stdio.h> main() { int i=10; float f=3.14; printf(“Size of int is %d\n”,sizeof(int)); printf(“Size of int variable is %d\n”,sizeof(i)); printf(“Size of float is %d\n”,sizeof(float)); printf(“Size of variable is %d\n”,sizeof(f)); printf(“Size of char is %d\n”,sizeof(char)); printf(“Size of double is %d”,sizeof(double)); }

Output:

Size of int is 2 Size of int variable is 2 Size of float is 4Size of variable is 4 Size of char is 1 Size of double is 8

3) Type Conversion: During programming, it is not necessary both the operands in an expression must be of same data type. In such situation when constants and variables of different types are mixed in an expression, they are converted to the same type, before evaluation, to maintain compatibility between data type. It can be either carried out by the following two methods:

(a) Implicit/Automatic/Silent conversion (b) Explicit conversion/Type casting/Casting

Thus, the process of converting one predefined data type into another is called type conversion.

(a) Implicit/Automatic/Silent conversion: This type of conversion is carried out by the compiler automatically, without programmer’s intervention. So it is also called silent conversion. It is generally applied on mixed mode expressions, i.e., where different data types are intermixed in an expressions. The table shown below lists the implicit type conversion rules.

Step No.

If either’s type is Then resultant type of other operand

Otherwise

1. long double long double Step 2 2. double double Step 3 3. float float Step 4 4. - integral promotion takes place

followed by step -

5. unsigned long unsigned long Step 6 6. long int and other

is unsigned int (i) long int (provided long int can represent all values of unsigned int) (ii) unsigned long int (if all values of unsigned int can’t be represented by long int)

Step 7 Step 7

7. long long Step 8 8. unsigned unsigned Both

Page 22: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 22

operands are int

Promotion: When the variable of lower data type is converted to a higher type is called promotion. Example:

float i; i=5;

Demotion: When the variable of higher data type is converted to a lower type is called demotion. Example:

int i; i=5.5;

(b) Explicit Conversion/Type Casting/Casting: This conversion is done by the

programmer explicitly, in which the programmer himself instruct the compiler to convert one type of variable into another. The operator used for this conversion is known as the cast operator and the process is known as casting. Suppose we have

int i=7; float f=8.5;

Then the expression (i+f)%4 will be invalid because the result of (i+f) will be in floating-point and the modulus will not operated on floating-point variables.

So expression will become valid when we use casting ((int)(i+f))%4 forces the first operand to be an integer and is therefore valid resulting in the integer remainder.

Example:

#include <stdio.h> main() { double f1 = 12.23456; printf("%d \n", (int)f1); }

Output:

12 1.13 Operator Precedence and Associativity: Operator has two important properties their precedence and their associativity.

Precedence (priority) rules help in removing the uncertainty about the order of performing operations while evaluating an expression.

Example: It is remains uncertain how to evaluate following expression either by method-1 or by method-2. Expression: 2+3*5 Method-1: (2+3)*5 5*5=25 Method-2: 2+(3*5) 2+15=17

Page 23: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 23

According to precedence rule operator having highest precedence will be evaluate first after that operator having lower precedence will be evaluate. In the above expression method-2 will return the correct answer because multiplication operator has higher precedence than addition operators. Thus, expression will firstly evaluate 3*5 and then evaluate the expression where the result from the multiplication is added to 2 to produce answer 17.

Associativity: Associativity of an operator can be from left to right or right to left. Example: Consider the following expression:

total = price – discount + surcharge The binary minus (-) and plus (+) operators have equal precedence and they have higher precedence than the assignment (+) operator. Therefore the order of evaluation proceeds left to right starting with ‘+’ and ‘-‘ operator according to their associativity. The evaluation computes the value (price – discount) add surcharge to the value and assign the value to total.

Table Operator for Precedence and Associativity

# Category Operator What it is (or does) Accociatvity 1. Highest ()

[] -> .

Function call Array subscript Indirect component selector Direct component selector

Left to right

2. Unary ! ~ + - ++ -- & * sizeof

Logical negation (NOT) Bitwise (1's) complement Unary plus Unary minus Preincrement or postincrement Predecrement or postdecrement Address Indirection (returns size of operand, in bytes)

Right to left

3. Multiplicative * / %

Multiply Divide Remainder (modulus)

Left to right

4. Additive + -

Binary plus Binary minus Left to right

5. Shift << >>

Shift left Shift right Left to right

6. Relational Less than Less than or equal to Greater than Greater than or equal to

Left to right

7. Equality == !=

Equal to Not equal to Left to right

8. Bitwise AND & Bitwise AND Left to right 9. Bitwise XOR ^ Bitwise XOR Left to right 10. Bitwise OR | Bitwise OR Left to right 11. Logical AND && Logical AND Left to right 12. Logical OR || Logical OR Left to right 13. Conditional ?: (a ? x : y means "if a then x, else y") Right to left 14. Assignment =

*= /= %=

Simple assignment Assign product Assign quotient Assign remainder (modulus)

Right to left

Page 24: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 24

+= -= &= ^= |= <<= >>=

Assign sum Assign difference Assign bitwise AND Assign bitwise XOR Assign bitwise OR Assign left shift Assign right shift

15. Comma , Evaluate Left to right 1.14 Formatted Input/Output Functions 1.14.1 printf() Function:

1. printf function is used to displays the output data using the standard output device (monitor). The output data can be any combination of numerical values, single character and strings.

2. printf returns the number of characters printed. 3. printf requires the backslash characters/escape sequences to display some special

characters. Escape sequences are control characters used to move the cursor and print characters such as ?, “, \ and so on.

Table Escape Sequences

Sequence Meaning \a Beeps the speaker \b Backspace (moves the cursor back, no erase) \f Form feed (ejects printer page; may clear the screen on some computers) \n Newline, like pressing the Enter key \r Carriage return (moves the cursor to the beginning of the line) \t Tab \v Vertical tab (moves the cursor down a line) \\ The backslash character \' The apostrophe \" The double-quote character \? The question mark \0 The "null" byte (that's 0, not the letter O) \Onn A character value in octal (base 8) \xnnn A character value in hexadecimal (base 16)

4. printf can display variables by using the format specifiers listed in table.

printf Conversion Type Characters for Numeric data Types

Format specifier

Type of argument

Output

%d integer signed decimal integer %i integer signed decimal integer %o integer unsigned octal integer %u integer unsigned decimal integer %x integer unsigned hexadecimal integer

(with a, b, c, d, e, f) %X integer unsigned hexadecimal integer

(with A, B, C, D, E, F) %f floating-point signed value of the form

Page 25: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 25

[-]dddd.dddd %e floating-point signed value of the form

[-]d.dddd or e[+/-]ddd %g floating-point signed value in either e or f form, based on

given value and precision: Trailing zeros and the decimal point are printed if necessary

%E floating-point same as e; with E for exponent %G floating-point same as g; with E for exponent if e format is

used printf Conversion Type Character for Qualified Data Types

Format specifier

Type of argument

Output

%ld, %li long decimal long integer %lu unsigned long decimal unsigned long integer %hd, %hi short decimal short integer %hu unsigned short decimal unsigned short integer %le, %lf, %lg double signed, double %Le,%Lf,%Lg long double signed, long double %lo long octal long integer %lx long hexadecimal long int

printf Conversion Type Character for Character Data Types

Format specifier

Type of argument

Output

%c char single character %s sequence of char prints characters until a null-terminator is

pressed or precision is reached

Syntax: printf(“format string”, v1,v2,……,vn);

where “fomat string” is the control string which represents the format specification and v1,v2,……,vn are variables whose values are to be displayed on the monitor.

Example: #include <stdio.h> void main() { int i = 0; i=printf("abcde\n"); printf("total characters printed %d\n",i); }

1.14.2 scanf() Function:

1. scanf function is used to read/input values of variable using the standard input device (keyboard).

2. The format specifier argument tells scanf how to convert the incoming data.

Page 26: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 26

scanf Conversion Type Characters for Numeric data Types

Type character

Expected input Type of argument

d decimal integer address of an integer D decimal integer address of a long int o octal integer address of an integer O octal integer address of a long int i decimal, octal or hexadecimal

integer address of an integer

I decimal, octal or hexadecimal integer

address of a long int

u unsigned decimal integer address of an unsigned integer U unsigned decimal long address of an unsigned long x hexadecimal integer address of an integer X hexadecimal integer address of a long int

e, E floating-point address of a float f floating-point address of a float

g, G floating-point address of a float

scanf Conversion Type Character for Character Data Types

Type character

Expected input Type of argument

s character string name of the string c Character address of a char variable % % character no conversion done; scanf looks

for the % character in the input

3. Common scanf starts with a string argument and may contain additional arguments. Additional arguments must be pointers.

4. Search sets (%[…], %^[…]) are also used in formatted input. In this case scanf reads the input field up to the first character it meets that does not appear in the search set or inverted search set.

5. scanf returns the number of successful inputs. Syntax:

scanf(“format string”,& v1,&v2,….,&vn);

where “fomat string” is the control string which represents the format specification and v1,v2,….,vn are variables whose values are to be read from keyboard.

Example:

#include <stdio.h> void main() { int i = 0; int k,j=10; printf("Input three integers and press enter to confirm."); i=scanf("%d%d%d",&j,&k,&i); printf("total values inputted %d\n",i);

Page 27: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 27

printf("The input values %d %d\n",j,k); }

1.14.3 More about Formatted Output Functions: Output values can be printed with specific width using command for formatted output. A simple format specification has the following form:

%w.p format-specifier

where w is an integer number that specifies the total number of columns for the output value and p is another integer number that specifies the total number of digits to the right of the decimal point or the number of characters to be printed from a string. We can make display left-justified in by placing a minus sign before the integer w. The default value for w is 1.

Example:

Output of Format Output

Integer Numbers

printf(“%d”,9876);

9 8 7 6 .

printf(“%6d”,9876);

9 8 7 6 .

printf(“%2d”,9876);

9 8 7 6 .

printf(“%-6d”,9876);

9 8 7 6 .

printf(“%06d”,9876);

0 0 9 8 7 6 .

Real Numbers

printf(“%7.4f”,98.7654);

9 8 . 7 6 5 4 .

printf(“%7.2f”,98.7654); .

9 8 . 7 7 .

printf(“%-7.2f”,98.7654);

9 8 . 7 7 ..

printf(“%f”,98.7654);

9 8 . 7 6 5 4 . .

printf(“%10.2e”,98.7654);

9 . 8 8 e + 0 1 .

printf(“%11.4e”,-98.7654);

- 9 . 8 7 6 5 e + 0 1 .

printf(“%-10.2e”,98.7654);

9 . 8 8 8 e + 0 1 .

printf(“%e”,98.7654);

9 . 8 7 6 5 4 0 e + 0 1 .

Strings

printf(“%s”,”New Delhi”);

N e w D e l h i .

printf(“%12s”,”New Delhi”);

N e w D e l h i .

printf(“%12.6s”,”New Delhi”);

N e w D e .

printf(“%.6s”,”New Delhi”);

N e w D e .

printf(“%-12.7s”,”New Delhi”);

N e w D e l .

printf(“%5s”,”New Delhi”);

N e w D e l h i .

1.14.4 More about Formatted Input Functions: Values can be read/input with specific width using command for formatted input. A simple format specification has the following form:

%w format-specifier

where w is an integer number that specifies the field width of the number to be read.

Example:

Input of Format Input Actual Input

Page 28: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 28

Integer Numbers scanf(“%d%*d%d”,&a,&b,&c); scanf(“%2d%4d%3d”,&a,&b,&c); scanf(“%2d%4d”,&a,&b);

1 2 3 123456789 1234 5678

a=1, b=3, c=garbage a=12, b=3456, c=789 a=12, b=34

Real Numbers scanf(“%f%f”,&a,&b); 75.89 43.21e-1 a=75.89, b=4.321

Strings

scanf(“%s”,&str); scanf(“%5s”,&str); scanf(“%[a-z]”,&str); scanf(“%[^aeiou]”,&str);

New Delhi Delhi Abc123ef String

str=New str= Delhi str=Abc str=Str

Note: * skip the input value. #include <stdio.h> void main() { int month1; int day1; int year1; int month2; int day2; int year2; printf( "Enter a date in the form mm-dd-yyyy: " ); scanf( "%d%*c%d%*c%d", &month1, &day1, &year1 ); printf( "month = %d day = %d year = %d\n\n", month1, day1, year1 ); printf( "Enter a date in the form mm/dd/yyyy: " ); scanf( "%d%*c%d%*c%d", &month2, &day2, &year2 ); printf( "month = %d day = %d year = %d\n", month2, day2, year2 ); }

Output:

Enter a date in the form mm-dd-yyyy: 01-01-2001 month = 1 day = 1 year = 2001 Enter a date in the form mm/dd/yyyy: 01/01/2002 month = 1 day = 1 year = 2002

When scanf Stops Scanning:

(i) scanf stops and skips to the next input field: The scanf function stops scanning and storing the current input field: it proceeds to the next if any one of the following situation occurs:

(a) An assignment-suppression character (*) appears after the % in the format specifier: the current input field is scanned but not stored.

(b) The number of characters specified by the width specifier have been read. (c) The number of character read cannot be converted under the current format (for

example, the character A is entered when the format is %i). (d) The next character in the input field does not appear in the search set, or does not

appear in the inverted search set. (ii) scanf stops scanning entirely, and returns: The scanf function terminates under the

following circumstances: (a) The next character in the input field has a conflict with a corresponding non-

whitespace character in the format string. (b) The next character in the input field is EOF. (c) The format string specification has been exhausted.

Page 29: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 29

(d) If a character sequence that is not a part of the format specifier occurs in the format string, it must match the current sequence of characters in the input field.

1.15 Character Input/Output Functions 1.15.1 getchar() Function: getchar() function is used to read one character at a time from the standard input device (keyboard). It has the following form:

char_variable=getchar();

Example:

#include<stdio.h> void main() { char ch; printf("Enter any character"); ch=getchar(); printf("Entered character is %c",ch); }

When this function is executed, the computer will wait for a key to be pressed and assigns the value to the variable ‘ch’ when the enter key is pressed. 1.15.2 put char() Function: putchar() function is used to display one character at a time on the monitor screen. It has the following form:

putchar(char_variable); Example:

#include<stdio.h> void main() { char ch; printf("Enter any character"); ch=getchar(); putchar(ch); }

When this function is executed, the computer will display the value of the char variable ‘ch’ on the monitor screen. 1.15.3 getch() Function: getch() function is used to read a character from the keyboard and it does not expect the enter key press. It has the following form:

char_variable=getch(); Example:

#include<stdio.h> void main() { char ch; printf("Enter any character"); ch=getch(); printf("Entered character is %c",ch); }

When this function is executed, the computer will wait for a key to be pressed from the keyboard. As soon as a key is pressed, the control is transferred to the next line of the program and the value is

Page 30: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 30

assigned to the char variable ‘ch’. It is to be noted that the key (letter) pressed will not be displayed on the monitor screen. 1.15.4 putch() Function: putch() function is used to display a character on the monitor screen. It has the following form:

putch(char_variable);

Example:

#include<stdio.h> void main() { char ch; printf("Enter any character"); ch=getchar(); putch(ch); }

When this function is executed, the computer will display the value of the char variable ‘ch’ on the monitor screen. 1.15.5 getche() Function: getche() function is used to read a character from the keyboard without expecting the enter key press. However any key pressed by the user will be displayed on the monitor. It has the following form:

char_variable=getche(); Example:

#include<stdio.h> void main() { char ch; printf("Enter any character"); ch=getche(); printf("Entered character is %c",ch); }

When this function is executed, the computer will wait for a key to be pressed from the keyboard. The value is assigned to the char variable ‘ch’. Note: geche() is similar to getch() expect that getche() displays the key pressed from the keyboard on the monitor screen. The ‘e’ at the end of getche() stands for echo. 1.15.6 gets() Function: gets() function is used to read a string of characters including white spaces. Note that a string containing white spaces cannot be read using scanf() with “%s” format specifier. It has the following form:

gets(str_variable);

Example:

#include<stdio.h> void main() { char str[10]; printf("Enter any string"); gets(str);

Page 31: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 31

printf("Entered string is %s",str); }

When this function is executed, the computer will wait for the string value. Enter string of characters and press the enter key. It is to be noted that C language will add a null character “\0” to the end of any character string. 1.15.7 puts() Function: puts() function is used to display a characters string on the monitor screen. It has the following form:

puts(str_variable); Example:

#include<stdio.h> void main() { char str[10]; printf("Enter any string"); gets(str); puts(str); }

When this function is executed, the computer will display the value of the character string variable ‘str’ on the monitor screen. 1.16 Data Types: For each variable you have to attach some data type. The data type defines:

a. The amount of storage allocated to variables. b. The values that they can accept. c. The operations that can be performed on variables.

ANSI supports following data types: 1. Basic\Standard\Primary\Fundamental Data Type 2. Derived Data Type 3. User-defined Data Type

1. Basic\Standard\Primary\Fundamental Data Types: All C compilers support four fundamental data types, namely character (char), integer (int), floating point (float), and double-precision floating point (double). Many of them also offer extended data type such as long int and long double. Table shows all the allowed combinations of basic data types and qualifiers and their size and range on a 16-bit machine.

Type Size Value Range Value Range in decimal char or signed char 1 byte -27 to 27-1 -128 to 127 unsigned char 1 byte 0 to 28-1 0 to 255 int or signed int 2 bytes -215 to 215-1 -32768 to 32767 unsigned int 2 bytes 0 to 216-1 0 to 65535 short int or signed short int 1 byte -27 to 27-1 -128 to 127 unsigned short int 1 byte 0 to 28-1 0 to 255 long int or signed long int 4 bytes -231 to 231-1 -2147483648 to 2147483647 unsigned long int 4 bytes 0 to 232-1 0 to 4294967295 Float 4 bytes -231 to 231-1 3.4e-38 to 3.4e38 Double 8 bytes -263 to 263-1 1.7e-308 to 1.7e308 long double 10 bytes -279 to 279-1 3.4e-4932 to 1.1e+4932

Page 32: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 32

Qualifiers: Qualifiers modify the behavior of the variable type to which they are applied. For example int i; This declaration specifies that i is an integer which takes both positive and negative values, that is, i is a signed integer by default. The above declaration could also be written as signed int i; But the qualifier signed is not necessary, since int is signed by default. If the variable i is used to hold only positive values we declare: unsigned int i; Here qualifier unsigned is applied to the data type int. This qualifier modifies the behavior of the integer so that the number contained in a variable of this type is unsigned. Qualifiers can be classified into two types:

Size qualifiers Example: short and long.

Sign qualifiers Example: signed and unsigned.

const Qualifier: It is used to informs the compiler that variable is constant type and it can not be modified anywhere in the program. Example:

const float pi=3.14; 2. Derived Data Types: Some derived data types in C are array, function, and pointer. These are called derived because these are derived by using some other data types. Example: int a[10]; 3. User-Defined Data Types: The data types that are defined by the user with the existing data types are known as user defined data type. Some user-defined data types in C are typedef, and enum. Examples:

(a) typedef int units; units batch1, batch2;

(b) enum day {Monday, Tuesday, ……, Sunday}; enum day week_st, week_end;

Program:

#include <stdio.h> #include <limits.h> #include <float.h> void main() { printf("Variables of type char store values from %d to %d", CHAR_MIN,CHAR_MAX); printf("\nVariables of type unsigned char store values from 0 to %u", UCHAR_MAX); printf("\nVariables of type short store values from %d to %d", SHRT_MIN, SHRT_MAX); printf("\nVariables of type unsigned short store values from 0 to %u", USHRT_MAX); printf("\nVariables of type int store values from %d to %d", INT_MIN,INT_MAX); printf("\nVariables of type unsigned int store values from 0 to %u",

Page 33: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 33

UINT_MAX); printf("\nVariables of type long store values from %ld to %ld", LONG_MIN, LONG_MAX); printf("\nVariables of type unsigned long store values from 0 to %lu", ULONG_MAX); printf("\nVariables of type long long store values from %lld to %lld", LLONG_MIN, LLONG_MAX); printf("\nVariables of type unsigned long long store values from 0 to %llu", ULLONG_MAX); printf("\n\nThe size of the smallest nonzero value of type float is %. 3e", FLT_MIN); printf("\nThe size of the largest value of type float is %.3e", FLT_MAX); printf("\nThe size of the smallest nonzero value of type double is %.3 e", DBL_MIN); printf("\nThe size of the largest value of type double is %.3e", DBL_MAX); printf("\nThe size of the smallest nonzero value of type long double i s %.3Le", LDBL_MIN); printf("\nThe size of the largest value of type long double is %.3Le\n ", LDBL_MAX); printf("\nVariables of type float provide %u decimal digits precision. ", FLT_DIG); printf("\nVariables of type double provide %u decimal digits precision .", DBL_DIG); printf("\nVariables of type long double provide %u decimal digits prec ision.", LDBL_DIG); }

Output:

Variables of type char store values from -128 to 127 Variables of type unsigned char store values from 0 to 255 Variables of type short store values from -32768 to 32767 Variables of type unsigned short store values from 0 to 65535 Variables of type int store values from -2147483648 to 2147483647 Variables of type unsigned int store values from 0 to 4294967295 Variables of type long store values from -2147483648 to 2147483647 Variables of type unsigned long store values from 0 to 4294967295 Variables of type long long store values from -9223372036854775808 to 9223372036854775807 Variables of type unsigned long long store values from 0 to 18446744073709551615 The size of the smallest non-zero value of type float is 1.175e-38 The size of the largest value of type float is 3.403e+38 The size of the smallest non-zero value of type double is 2.225e-308 The size of the largest value of type double is 1.798e+308 The size of the smallest non-zero value of type long double is 3.362e-4932 The size of the largest value of type long double is 1.190e+4932 Variables of type float provide 6 decimal digits precision. Variables of type double provide 15 decimal digits precision. Variables of type long double provide 18 decimal digits precision.

1.16.1 Overflow in char and unsigned char Data Types: Overflow means you are carrying out an operation such that the value either exceeds the maximum value or is less than the minimum value of the data type.

Example:

#include <stdio.h>

Page 34: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 34

void main() { char i,j; i = 1; while (i > 0) { j = i; i++; } printf ("The maximum value of char is %d\n",j); printf ("The value of char after overflow is %d\n",i); }

Output:

The maximum value of char is 127 The value of char after overflow is -128

1.17 Basic Structure of C Program: A ‘C’ program may contain one or more section shown in figure.

Documentation Section Link Section Definition Section Global Declaration Section main () function Section {

Declaration Part Executable Part

} Sub-program Section

Function 1 Function 2

- -

Function n .

1. Documentation Section: This section consists of a set of comment line. Any line of text

bounded by asterisks and inclosed within slashes is a comment (/*-----------*/). The other way is to put double slashes in front of the line i.e. //.

Normally this section contains comments about the name of the program, the author and other details which the programmer would like to use letter. Example:

/* Program name is ADD.C Developed by Naveen Sahu -------------------------------------*/

2. Link Section: This section provides instruction to the compiler to link function from the

system library. 3. Definition Section: This section defines all symbolic constants. Symbolic constants are

usually defined at the beginning of a program. A symbolic constant is defined by writing:

#define Name Text

Page 35: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 35

Where Name: Represents a symbolic name. Example:

#define PI 3.14

4. Global Declaration Section: There are some variables are used in more than one function. Such variables are called global variables and declared in global declaration section. Example:

int x, y=10; //Global Declaration void main { ------ ------ }

5. main () function Section: Every C program must have one main() function. This section

contains two parts, declaration part and executable part. The declaration part and executable part. The declaration part declare all the variables used in the executable part.

These two parts must appear between the opening and closing brace. The program execution begins at the opening brace and ends at the closing brace. All the statements in the declaration and executable parts end with a semicolon. Example:

void main() // main function { // opening brace int a; // declaration part a=a+1; // statement printf(“a=%d”,a); // statement } // closing brace

6. Sub-program Section: This section contains all the user defined functions that are called

within the main() function. User defined functions are generally placed after the main() function. Example:

void add(); void sub(); void main() { add(); sub(); } void add() // User Defined Function 1 { ------ ------ } void sub() // User Defined Function 2 { ------ ------ }

Page 36: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 36

1.18 My First C program #include <stdio.h> void main() { printf("Hello World!\n"); }

First step for running this program is to make a text file containing above code. Be sure that the file is a pure text file. We must save the text file with .c extension. Then we must compile the source code. The result of compile step is an executable file that we can run. Details of hello.c program

#include <stdio.h> The #include in the first line of the program is called a preprocessor directive. A preprocessor is a program that processes the C program before the compiler. All the lines in the C program beginning with a hash (#) sign are processed by the preprocessor.

stdio.h refers to a file supplied along with the C compiler. It contains ordinary C statements. These statements give information about many other functions that perform input-output roles.

Thus, the statement #include<stdio.h> effectively inserts the file stdio.h into the file hello.c making functions contained in the stdio.h file available to the programmer. For example, one of the statements in the file stdio.h provides the information that a function printf() exists, and can accept a string (a set of characters enclosed within the double quotes).

main() C program consist of one or more functions. Functions are building blocks of C programs. main() function is different from other functions by that it is the start point of program execution. Our program contains only function while complicated programs may contain thousands.

{ Opening brace marks the start of a block. Closing brace will mark its end. This one marks main() function start.

printf("Hello world!\n"); This line of code prints the statement between quotation marks on your output screen. \n tells program to start a new line in output screen.

Each command line in C ends with ";" character. Control statements are exceptions. }

Closes main() function. 1.19 Be Cautious About Errors: Errors/bugs are very common while developing a program. If you don't detect them and correct them, they cause a program to produce wrong results. There are three types of errors syntax, logical, and run-time errors.

1. Syntax Errors: These errors occur because of wrongly typed statements, which are not according to the syntax or grammatical rules of the language. For example, in C, if you don’t place a semi-colon after the statement (as shown below), it results in a syntax error. printf(“Hello,world”) - error in syntax (semicolon missing)

Page 37: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 37

printf("Hello,world"); - This statement is syntactically correct. 2. Logical Errors: These errors occur because of logically incorrect instructions in the program.

Let us assume that in a 1000 line program, if there should be an instruction, which multiplies two numbers and is wrongly written to perform addition. This logically incorrect instruction may produce wrong results. Detecting such errors is difficult.

3. Runtime Errors: These errors occur during the execution of the programs though the program is free from syntax and logical errors. Some of the most common reasons for these errors are:

(a) When you instruct your computer to divide a number by zero. (b) When you instruct your computer to find logarithm of a negative number. (c) When you instruct your computer to find the square root of a negative integer.

Unless you run the program, there is no chance of detecting such errors. Working with complex numbers

#include <complex.h> #include <stdio.h> void main() { double complex cx = 1.0 + 3.0*I; double complex cy = 1.0 - 4.0*I; printf("Working with complex numbers:"); printf("\nStarting values: cx = %.2f%+.2fi cy = %.2f%+.2fi", creal(cx),cimag(cx), creal(cy), cimag(cy)); double complex sum = cx+cy; printf("\nThe sum cx + cy = %.2f%+.2fi", creal(sum),cimag(sum)); double complex difference = cx-cy; printf("\nThe difference cx - cy = %.2f%+.2fi", creal(difference),cimag(difference)); double complex product = cx*cy; printf("\nThe product cx * cy = %.2f%+.2fi",creal(product), cimag(product )); double complex quotient = cx/cy; printf("\nThe quotient cx / cy = %.2f%+.2fi", creal(quotient), cimag(quotient)); double complex conjugate = conj(cx); printf("\nThe conjugate of cx = %.2f%+.2fi", creal(conjugate) , cimag(conjugate)); }

Output:

Working with complex numbers: Starting values: cx = 1.00+3.00i cy = 1.00-4.00i The sum cx + cy = 2.00-1.00i The difference cx - cy = 0.00+7.00i The product cx * cy = 13.00-1.00i The quotient cx / cy = -0.65+0.41i The conjugate of cx = 1.00-3.00i

Page 38: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 38

Unit-2 Control Flow Construction

2.1 Decision Making/Conditional Statements: Decision making statements are used to execute the statements or transfer them from one part of program to another depending on a condition. These statements are also called as conditional statements. These statements are as follows:

1. if statement 2. switch statement 3. conditional operator statement 4. goto statement

1. if statement: The if statement is a powerful decision making statement and it is used to control the flow of execution of statements. It is basically a two way decision statement and is used in conjunction with an expression. It takes the following form:

The if statement may be implemented in different forms depending on the complexity of conditions to be tested. Different forms are as follows:

1) Simple if statement 2) if-else statement 3) Nested if-else statement 4) The else-if ladder

1) Simple if Statement: The general form of a simple if statement is:

if(test expression) { statement-block; } statement-x;

Flowchart:

During the execution of simple if statement at first test expression is evaluateded. If test expression is true the statement block is executed otherwise the statement block will be skipped and the control will jump to the statement-x. When the test

Page 39: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 39

expression is true both the statement block and the statement-x are executed in sequence.

Example:

#include<stdio.h> void main() { int a,b; printf("Enter Two Numbers\n"); scanf("%d%d",&a,&b); if(a>b) printf("%d is Greater",a); if(b>a) printf("%d is Greater",b); }

Output:

Enter Two Numbers 1 2 2 is Greater

2) if-else Statement: The general form of an if-else statement is:

if(test expression) { true-block statement(s) } else { false-block statement(s) } statement-x;

Flowchart:

The if-else statement is used to execute statement block or a single statement depending on the test expression. The if-else statement contains two statement blocks. First statement block will be executed if test expression is true otherwise false statement block followed by else will be executed and control is transferred to the statement-x.

Page 40: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 40

Example:

#include<stdio.h> void main() { int a,b; printf("Enter Two Numbers\n"); scanf("%d%d",&a,&b,); if(a>b) printf("%d is Greater",a); else printf("%d is Greater",b); }

Output:

Enter Two Numbers 2 1 2 is Greater

3) Nested if-else Statement: The general form of a nested if-else statement is:

if(test condition-1 ) { if(test condition-2) { statement-1; } else { statement-2; } else { statement-3; } statement-x;

Flowchart:

Page 41: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 41

When a series of decision are involved we have to use more than if-else statement in nested form. The logic of execution is shown in figure.

If the condition1 is false the statement-3 will be executed otherwise it continues to perform the second test. If the condition2 is true the statement-1 will be executed otherwise the statement-2 will be executed and the control is transferred to the statement-x.

Example:

#include<stdio.h> void main() { int a,b,c; printf("Enter Three Numbers\n"); scanf("%d%d%d",&a,&b,&c); if(a>b) { if(a>c) printf("%d is Greater",a); else printf("%d is Greater",c); } else { if(b>c) printf("%d is Greater",b); else printf("%d is Greater",c); } }

Output:

Enter Three Numbers 1 2 3 3 is Greater

4) The else-if Ladder: The general form of an else-if ladder statement is:

if(test condition-1 ) { statement-1; } else if(test condition-2) { statement-2; }

: : :

else if(test condition-n) { statement-n; } else {

Page 42: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 42

default statement; } statement-x;

Flowchart:

This is another way of putting multiple ifs together when multipath decisions are involved. Multipath decision is a chain of ifs in which the statement associated with each else is an if. This construct is known as the else-if ladder.

The conditions are evaluated from the top (of the ladder) downwards. As soon as a true condition is found the statement associated with it is executed and finally the control is transferred to the statement-x.

Example:

#include<stdio.h> void main() { int a,b,c; printf("Enter Three Numbers\n"); scanf("%d%d%d",&a,&b,&c); if(a>b&&a>c) printf("%d is Greater",a); else if(b>c) printf("%d is Greater",b); else printf("%d is Greater",c); }

Output:

Enter Three Numbers 1 2 3 3 is Greater

Page 43: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 43

2. switch Statement: The general form of switch statement is:

switch (expression) { case value-1: statement block-1 break; case value-2: statement block-2 break; ------------------------- ------------------------- default: statement-default } Statement-x;

Flowchart:

The switch statement is used to take one of a number of possible actions. The switch is preferred over multiple if…else statements. The value of the expression can be an integer or character is evaluated and compared with value-1, value-2 and so on. If it matches the corresponding statement block will be executed till break is reached and control is transferred to the statement-x. The following rules should be used for switch statement.

(a) The expression value must be an integer or character. (b) All the cases should be distinct. (c) Cases and default can occur in any order. (d) The break statement transfers the control out of switch statement. In the absence of a

break statement, all statements that are followed by matched cases are executed. (e) The default label is optional. If present it will be executed when the expression does not

find a matching case.

Example:

#include <stdio.h> void main()

Page 44: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 44

{ int n = 3; switch(n%2) { case 0 : printf("The number %d is even \n",n); break; case 1 : printf("The number %d is odd \n",n); break; } }

Output:

The number 3 is odd

3. Conditional Operator Statement (? :) :

This is only one operator in C that takes three operands. A conditional pair “? :” available in C to construct conditional expression of the form:

result = test-expression ? expression 1: expression 2;

If test expression is TRUE then expression 1 is performed and assigned to result

otherwise expression 2 is performed and assigned to result.

Example:

#include<stdio.h> #include<conio.h> void main() { int a,b,x; clrscr(); printf("Enter Two Numbers\n"); scanf("%d%d",&a,&b,); x=(a>b)?a:b; printf("%d is Greater",x); getch(); }

Output:

Enter Two Numbers 2 1 2 is Greater

4. goto Statement: The goto statement is used to shift control from one point to another in the program. The general form of goto statement is:

goto label;

The goto requires a label in order to identify the place where the branch is to be made. A label is any valid variable name must be followed by a colon. The label is placed immediately before the statement where the control is to be transferred. The general forms of goto and label statement are shown below.

Page 45: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 45

goto label; ------------- ------------- label: statement;

label: statement; ------------- ------------- goto label;

Forward Jump Backward Jump

Forward Jump: If the label: is placed after the goto label; some statement will be skipped. This jump is known as forward jumping. Backward Jump: If the label: is placed before the goto label; some statement will be executed repeatedly. This jump is known as backward jumping.

Example:

#include<stdio.h> #include<math.h> void main() { int no,i=0; float s; start: if(i==5) goto end; printf("Enter Number "); scanf("%d",&no); if(no<0) { printf("Number is Negative \n"); goto start; } s=sqrt(no); printf("Square Root of %d is %f\n",no,s); i++; goto start; end: }

Output:

Enter Number 100 Square Root of 100 is 10.000000 Enter Number 81 Square Root of 81 is 9.000000 Enter Number 49 Square Root of 49 is 7.000000 Enter Number 25 Square Root of 25 is 5.000000 Enter Number 2 Square Root of 2 is 1.414214

2.2 Looping or Iteration: In looping or iteration, a section of code to be executed repeatedly (again and again) until a termination condition is met.

A loop consists of two segments one is known as a control statement and the other is known as the body of the loop. There are three types of loop in C.

1. for loop

Page 46: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 46

2. while loop 3. do-while loop

1. for loop: The for loop is often used when the number of times the loop is to be executed is known in advance/predetermined. The general form of for loop is:

for(initialization;test condition;updation) { body of the loop }

The for is an entry-controlled loop statement. The execution of for loop statement is as follows: 1. The initialization part is executed only one. It is used to initialize one or more variables

that control the looping action. 2. The value of the control variable is tested using the test condition. If the test

condition is true the body of the loop is executed otherwise the loop is terminated after that the updation part is executed.

3. When the body of the loop is executed the control is transferred back to the for statement after evaluating the last statement in the loop. Now the control variable is incremented/ decremented (updated).

4. The new value of control variable is again tested to see it satisfies the loop condition. If the test condition is satisfied the body of the loop is again executed. This process of repeated execution is continues until the test condition is false.

Flowchart:

Example:

#include<stdio.h> #include<conio.h> void main() { int i; clrscr(); for(i=1;i<=10;i++) printf("%d\n",i); getch(); }

Page 47: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 47

Output:

1 2 3 4 5 6 7 8 9 10

Features of for Loop: Some common features of for loop are follows:

(i) Negative increment is possible in the for loop. Example: for(i=5;i>=1;i--) printf(“%d\n”,i);

(ii) More than one variable can be initialized at a time in the for loop separated by commas. Example: for(i=5,j=1;i>=1;i--) printf(“%d\n”,i);

(iii) Like initialization, the updation section (increment or decrement section) may also have more than one part, separated by commas. Example: for(i=5,j=1;i>=1;i--,y++) printf(“%d\t%d\n”,i,j);

(iv) Compound test conditions can be used in a for loop. Example: for(i=5,j=1;i>1 && j<4;i--,y++) printf(“%d\t%d\n”,i,j);

(v) One or more section of the for loop can be omitted (but semicolons cannot be omitted). Example: for(;i<=5;i++) printf(“%d\n”,i);

(vi) Infinite Loop: Each of the three parts inside the parentheses of the for loop are optional. Example: for(; ;) printf(“%d\n”,i);

(vii) Time Delay Loop: Can be created using the null statement. Example: for(i=1;i<=100;i++);

(viii) We can also use char variable as loop control variable. Example: for(i=’a’;i<=’e’;i++) printf(“%d\n”,i);

2. while loop: The while loop is often used when the number of times the loop is to be executed is not known in advance. The general form of while loop is:

while(test condition) {

Page 48: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 48

body of the loop }

Flowchart:

The while is also an entry-controlled loop statement. The test condition is evaluated and if it is true then the body of the loop is executed. After the execution of the body the test condition is once again evaluated and if it is true the body is executed once again. This process of repeated execution is continues until the condition is false.

Example:

#include<stdio.h> #include<conio.h> void main() { long int no,r,sum=0; clrscr(); printf("Enter Number "); scanf("%ld",&no); while(no) { r=no%10; sum=sum+r; no=no/10; } printf("Sum of Digit %ld",sum); getch(); }

Output:

Enter Number 123 Sum of Digit 6

3. do-while loop: Sometimes it is needed to execute our set of statements at once while the condition is false. This type of facility is provided in C through do-while loop. The general form of do-while loop is:

do { body of the loop } while(test condition);

Page 49: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 49

Flowchart:

In do-while loop the set of statements will be executed atleast once. The condition is tested after first execution of the body of the loop. So the do-while loop is called an exit control or a bottom tested loop.

Example:

#include<stdio.h> void main() { int no; char choice; do { printf("Enter Number to Check Even or Odd "); scanf("%d",&no); if(no%2) printf("%d is Odd Number",no); else printf("%d is Even Number",no); printf("\nDo You Want to Check another Number [y\\n] "); fflush(stdin); choice=getchar(); } while(tolower(choice)=='y'); }

Output:

Enter Number to Check Even or Odd 3 3 is Odd Number Do You Want to Check another Number [y\n] y Enter Number to Check Even or Odd 4 4 is Even Number Do You Want to Check another Number [y\n] n

Difference between for, while and do- while loop

for loop while loop do-while loop 1. The for loop is often used

when the number of times the loop is to be executed is known in advance.

The while loop is often used when the number of times the loop is to be executed is not known in advance.

The do-while loop is used to execute our set of statements at once while the condition is false.

2. It is entry controlled loop. It is entry controlled loop. It is exit controlled loop. 3. A for loop is commonly A while loop is also widely A do-while loop is used in

Page 50: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 50

used by many programmers.

used by many programmers. some cases where the condition needed to be checked at the end of the loop.

4. Example: void main() { int i; for(i=1;i<=10;i++) printf("%d\n",i); }

Example: void main() { int no=123,r,sum=0; while(no) { r=no%10; sum=sum+r; no=no/10; } printf("Sum=%d",sum); }

Example: void main() { int n; char ch; do { printf(“Enter No.”); scanf(“%d”,&n); printf(“SR=%f”,sqrt(n)); printf(“Continue[y\\n]”); fflush(stdin); ch=getchar(); } while(ch==’y’); printf("Sum=%d",sum); }

Conversion from one loop to another loop

for(A;B;C) { printf(“%d\t”,i); }

A; while(B) { printf("%d\t",i); C; }

A; do { printf("%d\t",i); C; }while(B);

2.3 break statement: Sometimes it is necessary to come out of the loop even before the loop condition becomes false. In such situation we use break statement to terminate the loop.

If break is written inside a nested loop structure then it causes exit from the innermost loop.

Page 51: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 51

Figure: Exiting a loop with break statement

Example:

#include<stdio.h> #include<conio.h> void main() { int i; clrscr(); for(i=1;i<=10;i++) { if(i==5) break; printf("%d\n",i); } getch(); }

Output:

1 2 3 4

2.4 continue statement: The continue statement is used to transfer the control to the beginning of the loop. The loop does not terminate when a continue statement is encountered.

Page 52: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 52

It is generally used with a condition and when continue is encountered all the remaining statement (after continue) in the same iteration are not executed and the loop continues with the next iteration.

Figure: Continuing a loop with continue statement

Example:

#include<stdio.h> #include<conio.h> void main() { int i; clrscr(); for(i=1;i<=10;i++) { if(i==5) continue; printf("%d\n",i); } getch(); }

Output:

1 2 3

Page 53: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 53

4 6 7 8 9 10

Difference between break and continue statement

break statement continue statement 1. A break statement is used to terminate the

loop. The continue statement is used to transfer the control to the beginning of the loop.

2. When a break statement is executed in a loop the repetition of the loop will be terminated.

When a continue statement is executed in a loop the execution is transferred to the beginning of the loop.

3. The keyword is break. The keyword is continue. exit() Function: The exit() function is used to transfer the control to the end of a program (i.e. to terminate the program execution). It uses one argument in () and the value is zero for normal termination or non-zero for abnormal termination.

Example:

#include<stdio.h> #include<conio.h> void main() { long int i,n,f=1; clrscr(); printf("Enter Number "); scanf("%ld",&n); if (n<0) { printf(“Factorial is not available for negative numbers”); exit(0) } else { for(i=n;i>=1;i--) f=f*i; printf(" FACTORIAL of %ld is %ld",n,f); } getch(); }

Note that the program execution is terminated when the value of the variable n is negative. The compiler directive #include<stdlib.h> is used when this function is used in a program.

Page 54: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 54

Unit-3 Defining and Manipulating Arrays

3.1 Arrays: An array refers to a group of data items, where the data item must be of similar types. In other words an array is a group of related data items that share common name.

A particular value is indicated by writing a number called index number or subscript in brackets after the array name. Declaration of Arrays: The declaration of an array is similar to declaration of any other variable. The general form of array declaration is:

data_type array_name[size];

Like any other variable declaration, data type must be declared at first (such as int, float or char) after that a suitable name of array contains then requires size is declared. For example

int age[100]; where int is data type of array, age is name of array and [100] refers the size of array. We can declare an array of character type as following:

char name[15]; where name is an array variable that can hold maximum of 15 characters. Initialization of Arrays: Array can be initialized at the point of their definition by some initial values. These initial values must appear in the same order in which they will be assigned to the individual array elements enclosed in braces and separated by commas. The general form of the array initialization is:

data_type array_name[size]={element 1, element 2, ……, element n };

Example: int no[5]={1,2,3,4,5};

The values of an array’s elements are assigned and stored as given below: Rules for Array Initialization: Some rules are as follows:

1. If the number of initializers are less than the number of elements in the array then remaining elements are set to zero. Example:

int no[5]={1,2,3}; is equivalent to

int no[5]={1,2,3,0,0}; 2. It is an error to specify more initialzers than the number of elements in the array. 3. It is not necessary to specify the length of an array.

Example: int no[]={1,2,3,4,5};

is equivalent to int no[5]={1,2,3,4,5};

Element Value

No[0] No[1] No[2] No[3] No[4]

1 2 3 4 5

Page 55: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 55

Example:

#include<stdio.h> void main() { int no[5],i; printf(“Enter array elements\n”); for(i=0;i<5;i++) scanf(“%d”,&no[i]); printf(“Array elements are:\n”); for(i=0;i<5;i++) printf(“no[%d]=%d\n”,i,no[i]); }

Output:

Enter array elements 10 20 50 40 30 Array elements are: no[0]=10 no[1]=20 no[2]=50 no[3]=40 no[4]=30

Properties of Arrays: An array has the following properties.

1. The type of an array is the data type of its elements. 2. The location of an array is the location of its first element. 3. The length of an array is the number of data elements in the array. 4. Array sequence of character or array of character data items is called string.

For example char name[15];

5. In an array all the items are stored in contiguous memory locations. 3.2 Types of Arrays:

3.2.1. One-Dimensional Arrays: It is very clear to its name “one-dimensional array” that the one dimension is used to store the data items. In other words, list of item can be given one variable name using only one subscript and such array variable is called array single-subscripted variable or a one dimensional array. 3.2.2. Two-Dimensional Arrays: It is very clear to its name “two-dimensional array” that the two dimensions are used to store the data items. The two-dimensional array requires two pairs of square brackets for number of rows and columns. The two-dimensional array is also called matrix. Declaration of Two-Dimensional Arrays: The declaration of two-dimensional array is similar to declaration of one-dimensional array. There will be an extra set of braces [] to indicate the second index. The general form of declaration of two-dimensional array is:

data_type array_name[row-size][column-size];

Page 56: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 56

Example:

int mat[3][3]; means mat is a two-dimensional array that contains 3 rows and 3 columns (total 9 elements) each element is access by their row and column position. Initialization of Two-Dimensional Arrays: Two-dimensional arrays are initialized in a same fashion like one-dimensional array. Example:

int mat[3][3]={{1,2,3},{4,5,6},{7,8,9}}; The array elements have the following initial values:

mat[0][0]=1 mat[0][1]=2 mat[0][2]=3 mat[1][0]=4 mat[1][1]=5 mat[1][2]=6 mat[2][0]=7 mat[2][1]=8 mat[2][2]=9

Example:

#include<stdio.h> void main() { int i,j,mat[3][3]; printf(“Enter elements of 3x3 matrix\n”); for(i=0;i<3;i++) { for(j=0;j<3;j++) { scanf(“%d”,&mat[i][j]); } } printf(“Matrix elements are:\n”); for(i=0;i<3;i++) { for(j=0;j<3;j++) { printf(“%d\t”,mat[i][j]); } printf(“\n”); } }

Output:

Enter elements of 3x3 matrix 1 2 3 4 5 6 7 8 9 Matrix elements are: 1 2 3 4 5 6 7 8 9

3. 2.3 Multidimensional Arrays: It is also possible for array to have more than two dimensions. They are called multidimensional array. 3.3 String: A group of integers can be stored in an integer array similarly array group of characters can be stored in a character array. Many times character arrays are also called strings. Character array or strings are used to manipulate text such as words and sentences.

Page 57: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 57

Declaration of String Variables: A string constant is a one-dimensional array of characters terminated by a null ‘\0’. For example

char name[ ]={‘N’,‘A’,‘V’,‘E’,‘E’,‘N’,‘\0’}; Each character in the array occupies one byte of memory and the last character is always ‘\0’. What character is this? It looks like two characters but it is actually one character. Note that ‘\0’ and ‘0’ are not same. ASCII value of ‘\0’ is 0 whereas ASCII value of ‘0’ is 48. 3.4 String Handling Functions: There are four important string handling functions in C.

1. strlen(): We can find the length of any string by using strlen() function. Means this function counts the number of characters present in string. Syntax:

strlen(string);

Example:

#include<stdio.h> #include<string.h> void main() { int i,l=0; char string[10]; printf(“Enter any string ”); scanf(“%s”,string); l=strlen(string); printf(“Length of %s is %d”,string,l); }

Output:

Enter any string Naveen Length of Naveen is 6

2. strcpy(): This function copies the contents of one string into another. The base addresses of

the source and target strings should be supplied to this function. Syntax:

strcpy(string1, string2); Example:

#include<stdio.h> #include<string.h> void main() { char string1[10],string2[10]; printf(“Enter first string ”); scanf(“%s”,string2); strcpy(string1,string2); printf(“Copied string is %s”,string1); }

Output:

Enter first string Naveen Copied string is Naveen

Page 58: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 58

3. strcmp(): This function is used to compares two strings to find out whether they are same or different. If the two strings are equal strcmp() returns a value zero otherwise it returns the numeric difference between the ASCII value of the first non-matching characters. Syntax:

strcmp(string1, string2); Example:

#include<stdio.h> #include<string.h> void main() { int c; char string1[10],string2[10]; printf(“Enter first string ”); scanf(“%s”,string1); printf(“Enter second string ”); scanf(“%s”,string2); c=strcmp(string1,string2); if(c==0) { printf(“Both strings are same”); } else { printf(“Both strings are different”); } }

Output:

Enter first string Naveen Enter second string Dharam Both strings are different

4. strcat(): The strcat() function is used to join strings. When two strings are joined, it is

referred as concatenation of strings. The string2 is concatenate at the end of string1. Syntax:

strcat(string1, string2); Example:

#include<stdio.h> #include<string.h> void main() { char string1[20],string2[10]; printf(“Enter first string ”); scanf(“%s”,string1); printf(“Enter second string ”); scanf(“%s”,string2); strcat(string1,string2); printf(“Joined string is %s”,string1); }

Output:

Enter first string Naveen Enter second string Sahu

Page 59: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 59

Joined string is NaveenSahu

3.5 Additional String Handling Functions: Some C compilers will accept the following string handling functions which are available in header files string.h and ctype.h. Function Purpose Example Result strupr() To convert all alphabets in a string to

upper case letters. strupr(“Delhi”) DELHI

strlwr() To convert all alphabets in a string to lower case letters.

strlwr(“Delhi”) delhi

strrev() To reverse a string. strrev(“Delhi”) ihleD strncmp() To compare the first n characters of

two strings. m=strncmp(“Delhi”, “Dipak”, 2) m=-4

strcmpi() To compare two strings with case insensitive.

m=strcmpi(“Delhi”, “DELHI”) m=0

strncat() To join specific number of letters to another string.

strncat(“New”, “Delhi”, 3) NewDel

atoi() To convert a string of digits to the integer value.

atoi(“1234”) 1234

Character Handling Functions:

Function Purpose Example Result isupper() To test if a character is an upper case

letter. isupper(‘A’) isupper(‘a’) isupper(‘8’)

1 0 0

islower() To test if a character is a lower case letter.

islower(‘n’) 1

isalpha() To test if a character is an alphabet. isalpha(‘K’) isalpha(‘+’)

1 0

isalnum() To test if a character is an alphabet or number.

isalnum(‘8’) isalnum(‘y’) isalnum(‘-’)

1 1 0

isdigit() To test if a character is a number. isdigit(‘5’) isdigit(‘a’)

1 0

isxdigit() To test if a character is a hexa-decimal number.

isxdigit(‘9’) isxdigit(‘A’) isxdigit(‘M’)

1 1 0

tolower() To convert an alphabet to lower case letter.

tolower(‘A’) a

toupper() To convert an alphabet to upper case letter.

toupper(‘a’) A

Page 60: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 60

Unit-4 User Defined Functions

4.1 Functions: Functions are subprograms which are used to compute a value or perform a task. They cannot be run independently and are always called by the main() program or by some other function. There are two kinds of functions:

1. Library or built-in functions: Library or built-in functions are used to perform standard operations, e.g. square root of a number sqrt(x), absolute value fabs(x), scanf(), printf() and so on. These functions are available along with the compiler and are used along with the required header files such as math.h, stdio.h, string.h and so on at the beginning of the program.

2. User-defined functions: User-defined functions are self-contained blocks of statements which are written by the user (programmer) to compute a value or perform a task. They are called by the main() program or by some other function.

Uses of Functions:

(a) Functions are very much useful when a block of statements has to be written/ executed again and again.

(b) Functions are useful when the program size is too large or complex. Functions are called to perform each task sequentially from the main program. It is like a top-down modular programming technique to solve a problem.

(c) Functions are used to reduce the difficulties during debugging a program. 4.2 Function Definition: A function definition includes the following elements:

1. Return type/function type 2. Function name 3. List of arguments/parameters 4. Local variable declaration 5. Function statements 6. A return statement

All the six elements are grouped into two parts: Function header (first three elements) Function body (last three elements)

A general form of function definition is:

return_type function_name(argument list) { local variable declaration; executable statement1; executable statement2; -------------------------- -------------------------- return statement; }

The first line return_type function_name(argument list) is known as function header and the statements within the opening and closing braces constitute the function body, which is compound statement.

Page 61: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 61

Example: int add(int a, int b) { int c; c=a+b; return(c); }

4.3 Function Declaration or Function Prototype: Function declaration are usually written at the beginning of a program, a head of program defined functions. It is terminated by semicolon. Function declaration consists of four parts.

1. Return type/function type 2. Function name 3. List of arguments/parameters 4. Terminating semicolon

The general form is:

return_type function_name(argument list);

This is very similar to the function header line except the terminating semicolon. For example:

int add(int a, int b); 4.4 Function Call: A function call is specified by the function name followed by a list of arguments, if any, enclosed in parentheses and terminated by a semicolon. Example: sum(x, y) // do not return any value z=sum(x, y) // will return value to z Actual and Formal Arguments: Passing of values between the main program and the function takes place through arguments. The arguments listed in the function calling statement are referred to as actual arguments. They are the actual value passed to a function to compute a value or to perform a task. Consider a function call statement with actual arguments as given below.

add(x, y);

Actual arguments The arguments used in the function declaration are referred as formal arguments. They are simply formal variables that accept or receive the values supplied by the calling program. Consider a function declaration with formal arguments as given below.

void add(int a, int b)

Formal arguments

Note that the number of actual and formal arguments and their data type should match. Difference between actual and formal arguments

Actual arguments Formal arguments 1. Actual argument is specified in function call. It is specified on function definition. 2. It is also called real arguments or variables. It is also called dummy or parametric

arguments or variables.

Page 62: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 62

3. Data type should not be used with actual arguments.

Data type must be used with formal arguments.

4. Actual arguments replace the formal arguments.

Formal arguments do not replace the actual arguments.

5. Example: Consider the following function call void main() { int a, y; --------- --------- add(x, y); // actual arguments --------- --------- }

Example: Consider the following function declaration void add(int a, int b) // formal arguments { int c; c=a+b; printf(“sum=%d”,c); }

Rules to Call a Function: The following rules are used to call a function in a C program.

1. A function has statement block which is called by the main() or any other function. 2. When the data type in a function declaration is omitted, the function will return a value of

the type integer. 3. The data type of the formal argument may be declared in the next line which follows the

function declaration statement. Consider the following example big(a, b) int a, b; { if(a>b) return(a); else return(b); } Note that the data type of the function is not mentioned. So it returns an integer value to the calling program.

4. A function can return a value at any stage of its execution by using more than one return statement.

5. A function can also be called by another function. 6. The return statement is omitted if it does not return a value directly to the calling program. 7. Argument list (actual and formal) listed can be omitted, but not the parentheses ( ) following

the function name. 4.5 Category of Functions: A function depending on whether arguments are presents or not and whether a value is returned or not, may belong to one of the following categories.

Category 1: Functions with no arguments and no return values

Page 63: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 63

Category 2: Functions with arguments and no return values

Category 3: Functions with no arguments and return values

Category 4: Functions with arguments and return value

4.6 Variable Length Argument Lists: The printf function accepts any number of parameters. Like printf function we can also create a user-defined function which accepts any number of arguments. To do this certain macros available in the header file stdarg.h can be used. Let us write a function that accepts a string followed by any number of strings and integers. The last parameter will be NULL. For example, if this function is named print_string_ints, then we must be able to call it with a statement like

print_strings_ints(“start”,”one”,1,”two”,2,null); The above call must result in the following output: start one 1 two 2 i.e. the first parameter is output, and the string-integer pairs are output line by line till the NULL parameter is encountered. Also the function must be allowed to accept any number of string-integer pairs. Only, the last parameter must be NULL. To achieve this, the function prototype must be as follows:

void print_string_ints( const char *start, …) The three dots (…) above constitute the ellipsis operator. It allows the function to accept any number of parameters. These parameters, however, are not known to the function by name. So, how does the function access them? This is where the macros from stdarg.h come into picture.

Page 64: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 64

Example:

#include<stdio.h> #include<conio.h> #include<stdarg.h> void print_strings_ints(const char *start,...) { va_list arg_list; int i; char *s; printf("%s\n",start); va_start(arg_list,start); while(s) { s=va_arg(arg_list,char *); i=va_arg(arg_list,int); if(s) printf("%s %d\n",s,i); } va_end(va_list); } void main() { clrscr(); print_strings_ints("First call","Hello",1,"world",2,NULL); print_strings_ints("Second call","Good",10,"Morning",20,"to all",30,NULL); getch(); }

Output:

First call Hello 1 world 2 Second call Good 10 Morning 20 to all 30

The function print_strings_ints declares a variable called arg_list, which is of type va_list. The type va_list is defined in stdarg.h, and is an array used in obtaining the arguments that come in place of the ellipsis (…). The macro va_start initializes the va_list variable declared (which, in our case is arg_list). The macro va_start is called in the above example with the statement

va_start(arg_list,start); The first parameter is the name of the va_list variable that has been declared. The second one is the name of the first parameter accepted by the function. The macro va_arg is the one which actually extracts the argument values. It accepts two parameters: va_list which is initialized with the va_start function, and the type of the argument needed. In the above example, the first call to va_arg is:

s=va_arg(arg_list,char *); It instructs va_arg that an argument of type char * is expected. The next va_arg statement expects an int. The function assumes that atleast one string-integer pair follows the initial string.

Page 65: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 65

There are some restrictions while using functions with variable number of arguments. The first parameter must be present, since its name has to be passed to va_start. Then, the type of the argument must be known while executing it using the va_arg macro. While calling the function, if the type of the variable passed does not match the type expected in the function, the results are unpredictable. The macro va_end performs clean-up operations. It releases any memory that might have been allocated when va_start was called.

Another function that is useful with a variable number of arguments is vprintf. To illustrate, let us develop a function that outputs an error and exits. Normally, we would write the function such that it accepts a string and outputs it. But this function will accept the arguments which printf accepts, so that more detailed error messages can be output. An illustration of this function is shown below.

void error(const char *fmt, …) { va_list, arg_list; va_start(arg_list, fmt); vprintf(fmt, arg_list); va_end(arg_list); exit(0); }

An example of using the function is given below. This piece of code prompts the user to input an integer greater than 0, failing which it outputs an error message and exits.

printf(“Input an integer greater than 0: “); scanf(“%d”,&i); if(i<0) error(“The integer i is %d. its value must be greater than 0.\n”,i);

Note that the function error is called just like the function printf. 4.7 Recursion: A function calling itself again and again to compute a value is referred to recursive function or recursion. Normally a function is called by the main program or by some other function but in recursion the same function is called by itself repeatedly. A very simple example of recursion is presented below: main() { printf(“This is an example of recursion\n”); main(); } When executed, this program will produce an output something like this: This is an example of recursion This is an example of recursion This is an example of recursion -------------------------------------- -------------------------------------- Execution is terminated abruptly; otherwise the execution will continue indefinitely. Another useful example of recursion is the evaluation of factorials of a given number. The recursive definition for factorial of a number n is:

The factorial function is:

n!= n(n-1)(n-2)……1

Page 66: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 66

For example 4!=4×3×2×1=24

A function to evaluate factorial of n is as follows: factorial(n) int n; { int fact; if(n==1) return(1); else fact=n*factorial(n-1); return(fact); }

Let us see how recursion works. Assume n=3. Since the value of n is not 1, the statement fact=n*factorial(n-1);

will be executed with n=3. That is fact=3*factorial(2);

will be evaluated. The expression on the right-hand side includes a call to factorial with n=2. This call will return the following:

fact=2*factorial(1); Once again, factorial is called with n=1. This time, the function returns 1. The sequence of operations can be summarized as follows:

fact= 3*factorial(2) =3*2* factorial(1) =3*3*1 =6

Note: When we write recursive function, we must have an if statement somewhere to force the function to return without recursive call being executed. Otherwise the function will never return. 4.7.1 Basic Requirements for Recursion: For implementing and designing the good recursive program we must make certain assumptions as follows:

(i) Base case. Base case is the terminating condition for the problem. While designing any recursive algorithm we must chose a proper terminating condition for a problem.

(ii) If condition. If condition in the recursive algorithm defines the terminating condition. (iii) Every time a new recursive call is made a new memory space is allocated to each

automatic variable used by recursive routine. (iv) Each time recursive call is there the duplicated values of the local variables of a recursive

call are pushed onto the stack within its respective call and all these values are available to the respective function. Call when it is popped out from the stack.

(v) Recursive case. Else part of the recursive definition calls the functions recursively. In the following example n==0 is the base case.

int factorial(int n) { if(n==0) return 1; else return n*factorial(n-1); }

Page 67: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 67

4.7.2 Types of Recursion: Recursion is of two types depending on whether a function calls itself from within itself, or whether two functions call one another mutually. The former called direct recursion and the later is called indirect recursion. Thus two types of recursions are:

1. Direct recursion 2. Indirect recursion

Both types of recursions are diagrammatically shown below:

int abc() { -------; abc(); }

int abc() { -------; -------; xyz(); } int xyz() { abc(); -------; }

(a) Direct recursion (b) Indirect recursion

Recursion may be further categorized as: 1. Linear recursion 2. Binary recursion 3. Multiple recursion

1. Linear Recursion: Linear recursion begins by testing for a set of base cases there should be

at least one. Every possible chain of recursive calls must eventually reach a base case, and the handling of each base case should not use recursion.

Example:

#include<stdio.h> int factorial(int); void main() { int no,f; printf("Enter Number "); scanf("%d",&no); f=factorial(no); printf("Factorial of %d is %d",no,f); } int factorial(int n) { int fact; if(n==0) return(1); else fact=n*factorial(n-1); return(fact); }

Output:

Enter Number 5 Factorial of 5 is 120

Page 68: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 68

2. Binary Recursion: Binary recursion occurs whenever there are two recursive calls for each non base case.

Example:

#include<stdio.h> int fibnum(int); void main() { int pos,n; printf("Enter the position of element you want from fibinacci series:"); scanf("%d",&pos); n=fibnum(pos); printf("The required fibonancci number is %d",n); } int fibnum(int p) { if(p==1||p==0) return p; else return(fibnum(p-1)+fibnum(p-2)); }

Output:

Enter the position of element you want from fibinacci series:7 The required fibonancci number is 13

3. Multiple Recursion: In multiple recursion we make not just one or two but many recursive calls.

4.7.3 Use of Recursion:

1. Recursive functions are written with less number of statements compared function. 2. Recursion is effective where terms are generated successively to compute a value. 3. Recursion is useful for branching processes. Recursion helps to create short code that would

otherwise be impossible. 4.7.4 Disadvantages of Recursion:

1. It consumes more storage space because the recursive calls along with automatic variables are stored on the stack.

2. The computer may run out of memory if the recursive calls are not checked. 3. It is not more efficient in terms of speed and execution time. 4. If proper precautions are not taken, recursion may result non-terminating iterations. 5. Recursion is not advocated when the problem can be through iteration. Recursion may be

treated as a software tool to be applied carefully and selectively. Difference between Iteration and Recursion

Iteration Recursion 1. It is a process of executing a statement or a

set of statements repeatedly, until some specific condition is satisfied.

Recursion is the technique of defining anything in terms of itself.

2. Iteration involves four clear cut steps There must be an exclusive if statement inside

Page 69: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 69

initialization, condition, execution and updation.

the recursive function, specifying stopping condition.

3. Any recursive problem can be solved iteratively.

Not all problems have recursive solution.

4. Iterative counterpart of a program is more efficient in terms of memory utilization and execution speed.

Recursion is generally a worse option to go for simple problems, or problems not recursive in nature.

4.8 Block Scope of Variables

1. Variable can be defined in the block. 2. The blocks are marked using { and } braces. 3. The scope of the variable is in the block where it is declared. 4. Variable defined in the outer block can be used in the inner block. 5. The nearest definition has more precedence.

Example:

#include <stdio.h> void main() { int i = 10; { int i = 0; for( i=0;i<2;i++) { printf("Value of i is %d\n",i); } } printf("Value of i is %d\n",i); }

Output:

Value of i is 0 Value of i is 1 Value of i is 10

Inner variable shadows outer variable

#include <stdio.h> void main(void) { int count = 0; do { int count = 0; ++count; printf("\nCount = %d ", count); } while( ++count <= 5 ); printf("\nCount = %d\n", count); }

Output:

Count = 1 Count = 1 Count = 1

Page 70: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 70

Count = 1 Count = 1 Count = 1 Count = 6

4.9 Local or Internal Variables:

1. Variables declared inside the body of the function or main program are referred as local variables.

2. These variables are active in the block in which they are declared.

Example:

#include <stdio.h> void test() { int count=0; // local variable printf("\nTest Count = %d ", ++count); } void main() { int count = 0; // local variable for( ; count < 5; count++) { test(); } }

Output:

Test Count = 1 Test Count = 1 Test Count = 1 Test Count = 1 Test Count = 1

4.10 Global or External Variables:

1. Variables declared outside the body of the main program are referred as global variables. 2. These variables are commonly available for the main program and functions and are active

throughout C program.

Example:

#include <stdio.h> int count = 0; //global variable void test() { printf("\nTest Count = %d ", ++count); } void main() { int count = 0; //local variable for( ; count < 5; count++) { test(); } }

Output:

Page 71: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 71

Test Count = 1 Test Count = 2 Test Count = 3 Test Count = 4 Test Count = 5

Local variable shadows global variable.

#include <stdio.h> int i =0; //Global variable void main() { int i ; // local variable void f1(void) ; i =0; printf("Value of i in main %d\n",i); f1(); printf("Value of i after call%d\n",i); } void f1(void) { int i=0; i = 50; }

Output:

Value of i in main 0 Value of i after call 0

4.11 Storage Classes in C: Variables used in a C program are stored in RAM or CPU memory register. There are four storage classes into which the variables are declared.

1. auto storage class 2. static storage class 3. extern storage class 4. register storage class

Depending on the type of storage class, the scope and behavior of the variables vary in a C program. 1. auto or Automatic Storage Class: Variables declared in this class are stored in RAM. This is the default storage class and the keyword auto is used to declare variables. Auto variable are active in a block in which they are declared. Note that a block means the statements inside the braces {}.

When a block in a C program is executed, the variables inside the block are created automatically and are found active. These variables are destroyed automatically and become inactive when the execution transferred to another block or function in the same program. Note that the keyword auto to declare these variables is optional.

Example:

#include<stdio.h> void main() { void sample(); auto int m=40; { auto int m=50; printf(“Value of m in inner block is %d”,m);

Page 72: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 72

} sample(); printf(“\nValue of m in outer block is %d”,m); } void sample() { auto int m=65; printf(“\nValue of m in function block is %d”,m); }

Output:

Value of m in inner block is 50 Value of m in function block is 65 Value of m in outer block is 40

Note that variable m is declared in three blocks, and in the respective blocks it is active. When this program is executed, the value of m in the respective blocks are printed as shown above. 2. static Storage Class: Variables declared in this class are also stored in the RAM. The keyword static is used to declare these variables. Similar to auto variables, the static variables are also active in the block in which they are declared, and they retain the latest value. The static variables are commonly used along with functions.

Example:

#include<stdio.h> void main() { void sample(); printf(“First function call:”); sample(); printf(“\nSecond function call:”); sample(); } void sample() { static int m=5,n=10; m=m+10; n=n+10; printf(“\nValue of m=%d and n=%d”,m,n); }

Output:

First function call: Value of m=15 and n=20 Second function call: Value of m=25 and n=30

Note that the static variable in a function are initialized only once during the compilation. Thereafter the existing value of the variables is active; further, if it is declared as an auto variable, its value will be initialized in every function call during the runtime. 3. extern Storage Class: When a program spans across different files and we want to have a global variable access ible to all functions in these files, the keyword extern should be used before the data type name in the declaration in all the files where it is expect one. The linker requires the only one of

Page 73: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 73

these files have the definition of the identifier. Global variable definitions can occur in one file only. Variables declared in this class are stored in RAM.

Example: (1) Subfile.c

extern int m; void sample() { m++; }

(2) Mainfile.c

#include<stdio.h> #include<conio.h> #include"Subfile.C" void sample(); int m; void main() { clrscr(); m=10; printf("Before function calling m=%d",m); sample(); printf("\nAfter function calling m=%d",m); getch(); }

Output:

Before function calling m=10 After function calling m=11

Observe that the integer variable m has been declared in the file Subfile.c as extern int m; Upon encountering the above statement, the compiler knows that an integer m exists. It goes ahead to the procedure the object file. In the file Mainfile.c, the actual definition of m occur with statement int m; The linker is then invoked to link two object files together. When the compiler produces the object file of Subfile.c, it does not know the exact location of the variable m. So, it includes the information in the locations in the object file where the global variable is accessed. In the object file Mainfile.c, the compiler will store this information.

When the linker links these two object files together, it knows the location of m from the object file of Mainfile.c. It uses this information to complete the object file of Subfile.c, where the compiler had encounded the information about the locations where m is accessed in Subfile.c. 4. register Storage Class: Variables declared using this class are stored in the CPU memory register. The keyword register is used to declare these variables. Only a few variables which are frequently used in the program are declared using this class to improve the program execution speed.

The behavior of register variables is similar to that of auto variables except that their storage locations are different. In case of non-availability of CPU memory register, these variables are stored in RAM as auto variables.

Page 74: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 74

Example:

#include<stdio.h> void main() { register int m=5; printf(“Value of m=%d”,m); }

Output:

Value of m=5

Note: The register variables of smaller size data types like short int, int or char are used. Addresses of register variables cannot be used for any type of processing in a program. 4.12 Structure: Unlike array structure is a collection of data items which can be of different type. Thus a structure may contain integer elements, floating-point elements and character elements. The individual structure elements are referred to as member. Declaration of Structure: The general form of structure declaration is:

struct tag_name { data_type member _name; data_type member _name; ----------------------- ----------------------- }structure_variable;

The structure declaration starts with the structure header that consists of the keyword struct followed by a tag name. The individual members of the structure are inclosed within curly braces. The closing brace is followed by a semicolon. Example: Suppose we want to store the database of student having roll number, name and height. The structure declaration for this will be as: struct student { int rno; char name[10]; float height; }; Initialization of Structure: The members of a structure variable can be assigned initial values in much the same manner as the element of an array. These initial values must appear in the same order in which they will be assigned to the individual structure members inclosed in braces and separated by commas. The general form of structure initialization is:

struct tag_name structure_variable ={value1, value2, ……, valuen};

Here struct is keyword and it is optional tag_name is any valid identifier structure_variable is any valid structure variable. Example: A variable of the structure student can be initialized during its declaration as follows:

Page 75: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 75

student boy={140, “Naveen”, 167.9}; 4.12.1 Dot (.) Operator: Dot (.) or period operator is used to access a data member in a structure variable or an array element. It has the following form:

structure_variable.data_member;

It is to be noted that the dot operator separates the structure variable or array and the data member. Example: x.roll_no s[i].roll_no x.name s[i].name 4.12.2 sizeof() of a Structure: sizeof() of a structure is equal to the total number of bytes occupied in RAM by various data member in the structure. Consider the following example.

struct student { int roll_no; char name[15]; };

The size of this structure is equal to 17 bytes (2 bytes for int + 15 bytes for char). The sizeof() function is written as follows to print the size of the structure.

printf(“%d”,sizeof(struct student)); Imagine the following how the details of a structure are stored.

roll_no

name

4.12.3 Assigning Value of a Structure Variable to another Structure Variable: All values available in a structure variable can be assigned to another structure variable of the same type if all data members in the structures are of the same data type. Example:

struct student { int roll_no; char name[15]; }; struct students={140,“Naveen”},x; x=s;

Now the values of the structure variable s are assigned to x. 4.12.4 Arrays within a Structure: Besides ordinary data type such as char, int, float, a member of a structure can be an array data type also. Example:

struct student { int roll_no; char name[15]; };

Initialization: Like initialization of any variable, we can also initialize the array type data member as follows:

struct students={140,“Naveen”};

Page 76: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 76

4.12.5 Structure as a Function Argument: A structure may be passed to the function as an argument which will be received by a formal argument in the function of the same type of the structure. Data members in the structure are accessed in the function to return a value to the calling program through a return statement.

Example:

#include<stdio.h> struct measure { int feet; int inch; }; struct measure add(struct measure,struct measure); void main() { struct measure m1,m2,m3; printf("Enter First Measure Feet and Inch "); scanf("%d%d",&m1.feet,&m1.inch); printf("Enter Second Measure Feet and Inch "); scanf("%d%d",&m2.feet,&m2.inch); m3=add(m1,m2); printf("Result %d Feet - %d inch",m3.feet,m3.inch); } struct measure add(struct measure x,struct measure y) { struct measure z; z.feet=x.feet+y.feet; z.inch=x.inch+y.inch; if(z.inch>=12) { z.feet+=1; z.inch-=12; } return(z); }

Output:

Enter First Measure Feet and Inch 12 8 Enter Second Measure Feet and Inch 10 7 Result 23 Feet - 3 inch

4.12.6 Structure within Structures/ Nested Structures: If a structure contains another structure data type as its member then it is considered as structure within structure or nested structure. It is declared in two ways as shown below. Method I: In this method, one structure is written inside another structure. struct student { int roll_no; char name[15]; struct address { char street_name[15]; char city[15]; long int pin_code; }res_addrs; }x,s[10];

Page 77: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 77

Method II: In this method, structures are written separately. The tag_name of one structure is used inside another structure. struct address { char street_name[15]; char city[15]; long int pin_code; }; struct student { int roll_no; char name[15]; address res_addrs; //structure within structure }x,s[10]; Since the address of a student has many details, it is declared as a separate structure and is used within the student structure. Access the data members of the inner structure using with two dot operators as shown in the following example.

x.res_addrs.street_name s[i]. res_addrs.street_name 4.12.7 Self Referential Structures: A self referential structure is one which contains a pointer to its own type. This is illustrated by the following example. The structure student has a pointer next, which can point to another student structure. struct student { Int rollno; Float marks; Int subject; Struct student *next; }; In above example, ptr is a pointer to structure variable of the type student.

Difference between Array and Structure

Arrays Structure 1. An array is a collection of related data items

of same type. Structure can have elements of different types.

2. Array is homogeneous. Structure is heterogeneous. 3. There is no keyword to identify array. Keyword struct is used for declaring structure. 4. Components of an array are referred to by its

position or subscript. Components of a structure has unique name.

5. Subscript or index is used for accessing and manipulating their elements.

Dot operator (.) is used for accessing and manipulating their members.

4.13 Unions: Union is very similar to structure. A union also consists of data members of different types but only one data member is active at a time. Union is useful in cases where the user selects any one data member for the application. Declaration of Union: The general form of union declaration is:

Page 78: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 78

union tag_name { data_type member _name; data_type member _name; ----------------------- ----------------------- }union_variable;

The union declaration starts with the union header that consists of the keyword union followed by a tag name. The individual members of the union are inclosed within curly braces. The closing brace is followed by a semicolon. Example: Suppose we want to store the database of student having roll number, name and height. The union declaration for this will be as: union student { int rno; char name[10]; float height; }; Initialization of Union: The initialization of the data members in a union are similar to the methods used in structure, except that only one data member can be assigned value at a time. Example: A variable of the union student can be initialized as follows:

student boy.name=“Naveen”; 4.13.1 sizeof() of an Union: The size of an union is equal to the number of bytes occupied in RAM by the largest data member in the union. Consider the following example.

union student { int roll_no; char name[15]; };

The size of this union is equal to 15 bytes because the largest data member name occupies 15 bytes in RAM. The sizeof() function is written as follows to print the size of the union.

printf(“%d”,sizeof(union student); Imagine the following how the details of a union are stored.

name

roll_no

15 bytes

Difference between Structure and Union

Structure Union 1. The keyword strut is used to declare the

structure. The keyword union is used to declare the union.

2. All data members in a structure are active at time.

Only one data member is active at a time.

3. All members of structure have unique memory space.

All members of union Share the same storage area.

Page 79: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 79

4. It is useful to declare a compound data type to group data members related to a person or item.

It is useful to certain cases where the user will select any one data member in the group of data members.

5. It is commonly used in most of the applications.

It is not commonly used.

4.14 typedef Declaration: typedef refers to definition of data types which can be used by the users to declare their own data definition names. For example, int may be declared as integer, float may be declared as real, a structure may be given another name and so on.

(i) typedef int integer (ii) typedef float real; (iii) typedef struct

{ int roll_no; char name[15]; }student;

Using these new data definitions, variables are declared as follows. integer a, b, c, big; real x, y, z; student s1, s2, s[10]; As usual, values to these variables are assigned as shown below. a=5; x=2.54; s1.roll_no=140; s[i].name=”naveen”; typedef is useful to assign a new name to the data type or structure. It does not have any other advantage and is not commonly used in programming. 4.15 enum Data Type: An enumeration is a user defined type with values ranging over a finite set of identifiers called enumeration constant. For example, days in week may be declared as enumerated data type as follows. enum days{SUN,MON,TUE,WED,THU,FRI,SAT}; where enum is the keyword for enumerated declaration. days is the name of enumerated data type. SUN,MON,…..,SAT are the values in the enumerated list. Using this data type, variables are declared as follows. enum days holiday,salary_day; The variables declared here may be assigned any one of the values given in the enumerated list. holiday=SUN; salary_day=SAT; It is to be noted that only the values which are given in the enumerated list are accepted. For example, the following assignments are not accepted. holiday=SUNDAY; holiday=”SUNDAY”; salary_day=SATURDAY; It is also possible to assign integer value to the identifiers in the enumerated list. C will consider the first data in enum list as 0, second as 1, and so on, if it has not been assigned the value. enum days{SUN=1,MON=2,TUE=3,WED=4,THU=5,FRI=6,SAT=7}; When the value of one identifier is specified in this manner, the value of the next element is the next higher integer. For example, if the definition of day is

Page 80: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 80

enum days{SUN=1,MON,TUE,WED,THU,FRI,SAT=99}; then the statement day=SUN will assign the value 1 to day, day=MON will assign the value 2 to day, day=TUE will assign the value 3 to day and day=SAT will assign the value 99 to day. The variables of enumerated data type may be assigned as follows: holiday=1; salary_day=7; Enumerations are a convenient way to associate constant integers with meaningful names. They have the advantage of generating values automatically. The enum data type is not commonly used in programming and it may not be supported by some of the C compilers. Note:

1. Names in different enums must be distinct. The following example is invalid. enum emotion {happy,hot,cool}; enum weather{hot,cold,wet};

It is not difficult to see why the above declarations are invalid because, the name hot has the value 1 in enum emotion and the value 0 in weather.

2. Values need not be distinct in the same enumeration. For example, the following declaration is perfectly valid.

enum weather{hot,warm=0,cold,wet}; The names hot and warm can be interchangeably used, since both represent the value 0.

Example:

#include<stdio.h> #include<conio.h> void main() { enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday}; enum Days Day; int n; clrscr(); printf("Enter the day of the week (0 to 6): "); scanf("%d",&n); Day = n; if(Day == Sunday || Day == Saturday) printf("Hurray it is the weekend\n"); else printf("Curses still at work\n"); getch(); }

Output:

Enter the day of the week (0 to 6): 5 Curses still at work

4.16 Bit Field: In C language, the user can decide the number of bits in memory (RAM) to be allotted to a variable. It overcomes the prescribed number of bytes allocated to a variable by the compilers.

In some of the cases, a variable can have either 0 or 1, but if it is declared as int which occupies 16 bits in RAM. In order to overcome this 16 bit default allocation and to allow just one bit, the variable may be defined as a size 1 bit as shown below:

unsigned int sex:1;

Page 81: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 81

The bit field definition is very useful when a structure has more data members which normally refer small values. Consider the following data members in a student structure.

struct student { int roll_no; char name[15]; int sex; struct date { int day; int month; int year; }jdate; int mark; };

The size of this structure is 32 bytes, which is equal to 216 bits, which may be reduced by considering the exact range of values for the data members as given below.

data member sex may be declared with 1 bit which is either 0 or 1 day with 5 bits for the range 1 to 32 month with 4 bits for the range 1 to 12 year with 7 bits for the range 1 to 99 mark with 7 bits for the range 0 to 100

struct student { int roll_no; char name[15]; unsigned int sex:1; struct date { int day:5; int month:4; int year:7; }jdate; int mark:7; };

Now the size of the structure is 20 bytes, which is equal to 160 bits, which leads to saving of 7 bytes (56 bits). Suppose we store the details of 100 students then we save about 700 bytes of memory space in RAM in the storage device. Uses of Bit Fields: The following are the uses of bit fields.

1. The storage space required to store the details in a structure is economically used by using the bit fields.

2. The saving of storage space is considerably high when a large quantity of such data is stored.

Page 82: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 82

Unit-5 Pointer Data type and its Application

5.1 Pointer: A pointer is variable that points to or reference a memory location in which data is stored. Each memory cell in the computer has an address that can be used to access that location so a pointer variable points to a memory location. We can access and choose the contents of this memory location via the pointer. 5.1.1 Accessing the Address of a Variable: The actual location of a variable in the memory is system dependent and therefore the address of a variable is not known to us immediately. How can we then determine the address of a variable? This can be done with the help of the operator and available in C. The operator & preceding a variable returns the address of the variable associated with it. For example the statement

p=&quantity; would assign the address 5000 to the variable p. The & can be remembered as ‘address of’. 5.1.2 Declaration of Pointers: In C, every variable must declare for its type. Since pointer variable contain addresses that belong to a separate data type. The declaration of the pointer variable takes the following form:

data_type *ptr;

This tells the compiler three things about the variable ptr 1. The asterisk (*) tells the variable ptr is a pointer variable. 2. ptr needs a memory location. 3. ptr points to a variable of type data_type.

For example int *p; declares the variable p as a pointer variable that points to an integer data type. Note: The type int refers to the data type of the variable being pointed to by p and not the type of the value of the pointer. 5.1.3 Assigning a Variable Through its Pointer: One a pointer has been assigned the address of a variable the value of the variable is accessed by using unary operator asterisk (*), usually known as indirection operator. Consider the following statements: int quantity, *p, n; quantity=179; p=&quantity; n=*p; The first line declares quantity and n as integer variables and p as a pointer variable pointing to an integer. The second line assigns the value 179 to quantity and the third line assigns the address of quantity to the pointer variable p. The fourth line contains the indirection operator *. When the operator * is placed before a pointer variable in an expression, the pointer returns the value of the variable of which the pointer value is the address. The value of n would be 179. The two statements p=&quantity; n=*p; are equivalent to n=*&quantity; which in turns equivalent to n=quantity;

Page 83: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 83

Note: In C, the assignment of pointers and address is always done symbolically, by means of symbolic names. We can not access the value stored at the address 5368 by writing *5368. It will not work. 5.1.4 Expression Using Pointer: An expression may contain pointers which are referred to values. Hence, the pointer used is preceded by the * symbol. Consider the following examples.

(a) s = *aptr + bptr; The expression can also be written as s = (*aptr) + (*bptr);

(b) *p = *xp * *yp; The result will stored in a pointer.

(c) *sum = *sum + 25; The expression can also be written as *sum += 25;

(d) int m = 15, *mptr = &m; *mptr++ or *mptr++ can be used to increment the value referred by the pointer mptr by 1 (i.e 16)

(e) *p = *xp / *yp; Note that there is a blank space between / and *. The following is wrong *p = *xp /*yp; The symbol /* is considered as the begining of a comment and therefore the statement fails.

5.2 Pointer Arithmetic: An integer operand can be used with a pointer to move it to a point/ refer to some other address in the memory. Consider an int type pointer as follows.

65494 int *mptr ; mptr

Assume that it is allotted the memory address 65494. Increments its value by 1 as follows. mpt++; or ++mptr;

mptr = mptr + 1; or mptr += 1; Now the pointer will refer to the next location in memory with the address 65496. C language automatically adds the size of the int type (2 bytes) to move the pointer to the next memory location as follows. mptr = mptr + 1; = 65494 + 1 × sizeof(int); = 65494 + 1 × 2; = 65496 Similarly any integer can be added or subtracted to move the pointer to any location in RAM. But the resultant address is dependent on the size of the data type of the pointer. The step in which the pointer increased or reduce is called scale factor. Scale factor is nothing but the size of the data type used in a computer. We know that in a PC, the size of float is 4, char is 1, double is 8 and so on. Consider another example float *xp; (assume its address is 63498) xp = xp + 5; will move the pointer to the address 63518 which is obtained as follows. = 63498 + 5 × sizeof(float); = 63498 + 5 × 4; = 634518

Page 84: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 84

5.2.1 Subtraction of Pointers: When two pointers are subtracted, the resultant is of a type called size_t. This type is normally equivalent to the unsigned integer type. The result is in units of the data type to be pointed by the pointer variable. For example, consider the following piece of code:

short int *p, *q; float *f, *g; q=p+1; g=f+1; printf(“%d\n”,g-f); printf(“%d\n”,q-p);

Both the above printf statements output 1. Even through the numerical value of the pointers differ by 4 (in the first case) or by 2 (in the second case), this difference is divided by the size of the type being pointed to. To get the difference in units of bytes, typecast the pointers being subtracted into char pointers. For example, the expression (char *)g - (char *)f will gives 4. Note: The arithmetic operators available for use with pointers are:

1. Unary operators: ++ (increment) and – – (decrement) 2. Binary operators: + (addition) and – (subtraction)

Example: void main() { int a,b,*p,*q; p=-q; // illegal use of pointer p<<=1; // illegal use of pointer p=p-b; // valid p=p-q; // nonportable pointer conversion p=(int *) (p-q); // valid p=p-q-a; // nonportable pointer conversion p=(int *) (p-q)-a;// valid p=p+a; // valid p=p+q+a; // illegal pointer operation p=p+q; // illegal pointer operation p=p*q; // illegal pointer operation p=p*a; // illegal pointer operation p=p/q; // illegal pointer operation p=a/q; // illegal pointer operation }

5.3 Pointers with Arrays: Values in an array can be accessed efficiently using pointers. Normally the first element (for example address of x[0]) address of an array is assigned to the pointer. Then the pointer will be moved to other element in the array using pointer address arithmetic. The first element address of the array is called base address. Consider the following example

float x[5]={2.52,4.38,3.5,4.25,3.85}; float *xptr;

Assume that these values are stored in memory in the following addresses.

Page 85: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 85

Note that each element occupies 4 bytes in float type and the first address of each memory location is considered.

Assign the first element address to the pointer as follows: xptr=x; or xptr=&x[0];

Now the pointer refers to the address of the first element x[0] which is 6548. The pointer will be moved to the next location as follows

xptr++; Now the pointer refers to the address of the second element x[1] which is 6552. The pointer can be moved to any location in the similar manner using the pointer address arithmetic. Reading/Writing Values in an Array Using Pointer: To read the values in an array, the base address of the array is assigned to the pointer and is then incremented in steps of 1 (note that the increase in memory address depends on data type) to point the next memory location. Consider the following example.

int x[10]; for(i=0;i<10;i++) scanf(“%d”,(x+i));

When this loop executed, the user has to enter 10 values one by one. Note that in scanf() the base address of the array x with the subscripts i is used to refer and store the values in the array in different memory locations. To print the values of an array, a similar loop is used, and the indirection operator * is used to access the value in that memory location. Consider the following example.

for(i=0;i<10;i++) printf(“%d\n”,*(x+i));

Note: We know that on mentioning the name of the array, its give the base address of array. Thus by saying *x, gives the element of the 0th location. We easily say x and *(x+0) both gives the same value. Similarly *(x+1) refers the first element of the array. In fact this is what the C compiler internally does. When we say x[i], the C compiler internally converts it *(x+i). This means that all the following are same

x[i] *(x+i) *(i+x) i[x] Different Ways to Access One-Dimensional Array Using Pointer: Method 1:

#include<stdio.h> void main() { int i, a[10], *ptr; printf("Enter 10 Numbers\n"); ptr=a; for(i=0;i<10;i++) { scanf("%d",ptr); ptr++; // or ptr=ptr+1; or ptr+=1; } ptr=a; printf("Entered Elements Are:\n"); for(i=0;i<10;i++) { printf("%d\n",*ptr); ptr++; // or ptr=ptr+1; or ptr+=1;

Page 86: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 86

} }

Method 2

#include<stdio.h> void main() { int i, a[10], *ptr; printf("Enter 10 Numbers\n"); ptr=a; for(i=0;i<10;i++) scanf("%d",(ptr+i)); // or scanf("%d",(i+ptr)); ptr=a; printf("Entered Elements Are:\n"); for(i=0;i<10;i++) printf("%d\n",*(ptr+i)); // or printf("%d\n",*(i+ptr)); }

5.4 Pointer and Two Dimensional Array: We also refer the element of two dimensional array by pointer, it can be treat as a part of the array, each row of a two dimensional array can be treat as a one dimensional array. This is very important factor when we want to access array of two dimensional array using pointer. Consider the following example.

24 3 10 4 21 6

101 103 105 107 109 111

As setting up a one-dimensional array of 3 elements, each of which is one dimensional array of 2 elements long. We refer to an element of a one-dimensional array by using single subscript. Similarly If we can imagine x to be one-dimensional array then we can refer to its 0th element as x[0] and so on. So the statement printf(“%d”,x[0]) print the 0th element of the x, 0th element is a one-dimensional array. We know that just mentioning a one-dimensional array gives the base address. Hence the printf would print the base address of the 0th one-dimensional array, similarly x[1] print the address of 1st one-dimensional array.

#include<stdio.h> void main() { int x[3][2]={{24,3},{10,4},{21,6}}; int i; for(i=0;i<3;i++) printf("Address of %d row is %u\n",i,x[i]); } Output:

Address of 0 row is 101 Address of 1 row is 105 Address of 2 row is 109

Once the two-dimensional array is declared, there onwards x is treated as pointer to 0th element of the two-dimensional array. Hence the expression (x+0) gives the base address of the 0th element of 2-D array. Normally the expression *(x+0) should give the 0th element. But the 0th element of the 2-D array is 1-D array and on mentioning 1-D array we get its base address. Hence according to the figure

Page 87: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 87

are 101. Similarly we can interpret the meaning of x[1] (which is nothing but *(x+1)) x gives the address of the 0th element, hence x+1 would give the address of the 1st element and *(x+1) would give the 1st element. Since element is nothing but a 1-D array, and on mentioning the 1-D array we get its base address, *(x+1) gives the base address of the 1st 1-D array. In general the expression x[i] or *(x+i) would give the base address of the ith 1-D array. Now, we have been able to reach individual row. What remains is to be able to refer to the elements of a row. Suppose we want to refer to the element x[1][1] using pointer. We know that x[1] would give the address 105, the address of the 1st one-dimensional array. Obviously (105+1) would give the address 107. And the value at this address can be obtained by using the expression *(x[1]+1). But we know that x[i] is same as *(x+i). Similarly *(x[1]+1) is same as *(*(x+1)+1). Thus the following expression refer to the same statement

x[1][1] *(x[1]+1) *(*(x+1)+1)

Different Ways to Access Two-Dimensional Array Using Pointer: Method 1

#include<stdio.h> void main() { int mat[3][3],i,j,*p; printf("Enter elements of 3*3 atrix\n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) scanf("%d",(*(mat+i)+j)); } printf("Entered matrix is:\n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) printf("%d\t",*(*(mat+i)+j)); printf("\n"); } }

Method 2

#include<stdio.h> void main() { int mat[3][3],i,j,*p; p=&mat[0][0]; printf("Enter elements of 3*3 matrix\n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) { scanf("%d",p); p++; } } p=&mat[0][0]; printf("Entered matrix is:\n"); for(i=0;i<3;i++)

Page 88: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 88

{ for(j=0;j<3;j++) { printf("%d\t",*p); p++; } printf("\n"); } }

Method 3

#include<stdio.h> void main() { int mat[3][3],i,j,*p; p=&mat[0][0]; printf("Enter elements of 3*3 matrix\n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) scanf("%d",(p+i*3+j)); } printf("Entered matrix is:\n"); for(i=0;i<3;i++) { for(j=0;j<3;j++) printf("%d\t",*(p+i*3+j)); printf("\n"); } }

5.5 Pointer and Three Dimensional Array: A three dimensional array can be thought of an array of the two dimensional arrays. Each element of a three dimensional array is accessed using three subscripts, one for each dimension. For example, a three dimensional array with dimensions (2, 3, 2) is stored as shown in figure.

As usual, the array name points to the base address of the three dimensional array. The array name with a single subscript i contains the address of the ith two dimensional array. Hence arr[i] is the address of the ith two-dimensional array. The expression arr[i][j] refer to the base address of the jth row of the ith two dimensional array. Similarly the expression arr[i][j][k] is the kth element in the jth row of the ith two-dimensional array. The following example illustrates these concepts. Note that the expression *(*(*(arr+i)+j)+k) is the same as arr[i][j][k].

Page 89: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 89

#include<stdio.h> #include<conio.h> void main() { static int arr[2][3][2]={{{2,1},{3,6},{5,3}},{{0,9},{2,3},{5,8}}}; int i,j,k; clrscr(); printf("%d\n",arr); printf("%d\n",*arr); printf("%d\n",**arr); printf("%d\n",***arr); printf("%d\n",arr+1); printf("%d\n",*arr+1); printf("%d\n",**arr+1); printf("%d\n",***arr+1); for(i=0;i<2;i++) { for(j=0;j<3;j++) { for(k=0;k<2;k++) printf("%d\t",*(*(*(arr+i)+j)+k)); printf("\n"); } printf("\n"); } getch(); }

The array arr will be stored in memory as shown in figure. In the above program, the name arr is the base address of the three-dimensional array. The expression *arr is the base address of the 0th two-dimensional array, **arr is the 0th row of the 0th column and 0th row of the 0th two-dimensional array. The expression arr+1 is the base address of the 1st two-dimensional array, *arr+1 is the base address of the 1st row in the 0th two-dimensional array, **arr+1 gives the address of the 1st element in the 0th row and 0th column of the 0th two-dimensional array. The expression ***arr+1 adds 1 to the value obtained from the 0th element in the 0th row of the 0th two-dimensional array (which is 2), giving 3. The expression within the for loop prints the contents of the three-dimensional array in the order in which they are stored in memory. The output of the above program is as follows:

100 100 100 2 106 104 102 3 2 1 3 6 5 3 0 9 2 3 5 8

Page 90: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 90

5.6 Array of Pointer: We can also use an array as a pointer. Since a pointer variable containing the address an array of pointer is a collection of address.

a b c d e 24

3

10

4

14

101 501 601 801 901

x 101 501 601 801 901

311 313 315 317 319

#include<stdio.h> void main() { int a=24,b=3,c=10,d=4,e=14,i; int *x[5]; x[0]=&a; x[1]=&b; x[2]=&c; x[3]=&d; x[4]=&e; for(i=0;i<5;i++) printf("%d ",*(x[i])); }

Output:

24 3 10 4 14

5.7 Pointers with Strings: A string contains a sequence of characters which are used in memory continuously like array which can be accessed by a pointer of the type char. Consider the following example to declare and initialize a string and a pointer. char st[10]=”Good Luck”; char *sptr; The string is stored in memory as shown below:

st G o O d L u c k \0

4041 4042 4043 4044 4045 4046 4047 4048 4049 4050

The base address of the string is assigned to the pointer as follows sptr=st; Now the pointer *sptr refers to the character ‘G’. Increase the value of the pointer as shown below to refer to the other characters in the string. sptr++ to refer the next character ’o’

sptr=st; sptr+3 to refer the character ‘D’ (st+3) which also refers ‘D’ Note that st is the name of the string variable which refers to the base address of the string. In C, a constant character string always represents a pointer to that string. And therefore the following statements are valid:

char *name; name=”Delhi”;

These statements will declare name as a pointer to character and assign to name the constant character string “Delhi”. We must remember that this type of assignment does not apply to character arrays. The statement like char name[20];

Page 91: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 91

name=”Delhi”; do not work.

#include<stdio.h> #include<conio.h> void main() { char str[]="Delhi",*p; int i; clrscr(); p=str; printf("First method\n"); for(i=0;*(p+i)!='\0';i++) printf("%c",*(p+i)); printf("\nSecond method\n"); i=0; while(*(str+i)!='\0') { printf("%c",*(str+i)); i++; } getch(); }

5.8 Two-Dimensional Array of Characters: The two-dimensional array of characters is an array of strings. The elements of the array of strings are accessed in a manner similar to two-dimensional arrays of other data types. The name of the array points to the base address i.e. the first character of the first string. Two subscripts are used to access the characters of the string. The expressions *(arrayname +i) and arrayname[i] point to the first character of the ith string and the expression *(arrayname+i)+j points to the jth character of the ith string in the array. The following example illustrates the above concepts.

#include<stdio.h> #include<conio.h> void main() { char pet[2][5]={"Lion","Cat"}; int i,j; clrscr(); for(i=0;i<2;i++) { printf("%d\n",(pet+i)+j); j=0; while(*(*(pet+i)+j)!='\0') { printf("%c",*(*(pet+i)+j)); j++; } printf("\n"); } getch(); }

The string represented in figure (b) is stored in the memory shown in figure (a).

Page 92: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 92

In this case, irrespective of the size of the strings, 5 bytes of memory are allocated for each string. Hence, there is wastage of memory that cannot be used for any other purpose. The output of the program is:

801 Lion 806 Cat

5.9 Array of Pointers to Strings: An array of pointers to strings is an array whose elements are pointers to the base address of the string. An array of pointers to strings is declared and initialized in the following manner.

static char *pets[]={“Lion”,”Cat”}; Here, pets[0] is a pointer to the base address of the string Lion, pet[1] is the pointer to string Cat and so on. Advantages: Unlike the two-dimensional array of characters (array of strings), the strings do not have a fixed memory size for storage. The string occupy only as many bytes as required hence, there is no wastage of space. The strings are stored in memory in the manner shown in figure.

Note that the strings need not be stored in consecutive memory locations. The individual characters within the string are accessed as usual using the indirection operator. The expression pets[i]+j points to the jth character of the ith string. More Examples on Pointer and Strings:

Page 93: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 93

First:

#include<stdio.h> void main() { static char st[]="Hello"; int i; for(i=0;st[i];i++) printf("%c %c %c %c\n", st[i],*(st+i),i[st],*(i+st)); }

This example shows that the expression st[i], *(st+i), i[st] and *(i+st) are all same and represents the content

H H H H H e e e e e l l l l l l l l l l o o o o o

Second:

#include<stdio.h> void main() { static char st[]="Good Morning"; printf("%s",st+3); }

In the above program, the expression st+3 points to the 3rd element of the string st. By using %s in the printf statement, the entire string starting from the 3rd element gets printed. The output of the above program is:

d Morning

Third:

#include<stdio.h> #include<string.h> void main() { char *str[5]={"Akhilesh","Vikas","Dharam","Naveen","Rahul"},*t; int i,n,j,k; for(i=3;i>0;i--) { for(j=0;j<=i;j++) { k=strcmp(str[j],str[j+1]); if(k>0) { t=str[j]; str[j]=str[j+1]; str[j+1]=t; } } } for(i=0;i<5;i++) puts(str[i]);

Page 94: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 94

}

Output:

Akhilesh Dharam Naveen Rahul Vikas

Note: 1. When we are using the array of pointer to string we can initialize the string at the place where

we are declaring the array, but we can not get the string from keyboard using scanf(). 2. In above program name are sorted by interchanging the corresponding pointers.

Fourth:

#include<stdio.h> void main() { static char *s[]={"Red","Blue","Yellow"}; static char **ptr[]={s,s+1,s+2}; char ***p=ptr; printf("%s\n",**++p); printf("%s\n",*--*++p+4); printf("%s",*p[-2]+9); }

In this example, s is declared an array of pointers whose elements are the base address of the three strings. Another array of pointers, ptr is declared and assigned the address of the element of the array s. The pointer p is then assigned to the base address of the array ptr. Let the array and pointer variable be stored in memory in the manner as shown in figure. Assume that all the pointers occupy 2 bytes in the memory. The argument passed to the first printf statement is **++p. This expression has two indirection (*) operators and a++ operator. The ++ operator evaluates first and increments p to 502. The second * is evaluates now, and it gets the value stored in the location 502, which is 802. Finally, the first * fetches the value in location 802, which is 104. The first printf statement prints Blue. The argument passed to the second printf statement is *--*++p+4 keeping in the mind that the value of p is now 502, and the unary operator evaluate right to left, the expression *--*++p evaluates first, giving 104. The + operator now adds 4 to this, yielding 108. Since the location 108 contains the null character, nothing is printed by the second printf statement.

The next expression *p[-2]+9 can be written as *(*p-2)+9. The current value stored in p is 504 and therefore, (p-2) results in 500 and the data contained is 800. A value of 9 is added to the address stored in 800 resulting in 109. The last printf statement prints the string at address 109. The output of above program is:

Blue Yellow

Page 95: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 95

Figure Pointer to array of pointers to array of pointers

5.10 Pointers to Functions: Functions have address just like data items. A function’s address is the starting address of the machine language code of the function stored in memory. For example, it is possible to write a function that accepts the address of another function as an argument and executes it. This approach may look unnecessary as the first function can directly call the second function without obtaining its address, but it is possible to pass addresses of different functions at different times thus making the function more flexible and abstract. 5.10.1 Address of a Function: The address of a function can be obtained by only specifying the name of the function without the trailing parentheses. For example, let the function be defined as test(). Now the test is the address of the function. Hence to pass the address of a function, it is sufficient to pass the name of the function. The declaration of a pointer to a function requires the function’s return type and the function’s argument list to be specified along with the pointer variable. The general syntax for declaring a pointer to a function is as follows.

Return type(*pointer variable)(function’s argument list);

Example: int test(double); /* Function prototype */ int test1(double); /* Function prototype */ int (*ptr)(double); /* Pointer to function with prototype of test */ Here ptr is a pointer variable pointing to the function that returns an integer value, and takes a data item of type double as its argument. The pointer ptr can point either to the function test or test1. The expression *ptr replace the function name in the declaration. The address of the functions can be assigned to pointer variables, just like assigning addresses of variables and other data type to the corresponding pointer variables. In pointer to function assignments, the complete function type must match exactly the pointer type and argument list. The following example illustrates the concept mentioned.

Page 96: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 96

#include<stdio.h> void fun1(int i, float f) // Function Definition { printf("%i %f\n",i,f); } void fun2(char *s) // Function Definition { printf("%s\n",s); } void main() { void (*p) (int,float); // Function Declaration void (*q) (char *); // Function Declaration int i=5; float f=5.375; char s[]="String"; p=fun1; q=fun2; //p=fun2; Incorrect Assignment, Error p(i,f); //Function Call q(s); //Function Call }

5.10.2 Invoking a Function by using Pointer: In the pointer declaration to functions, the pointer variable along with the symbol * plays the role of the function name. Hence, while invoking functions by using pointers, the function name is replaced by the pointer variable. The following example illustrates this concept.

#include<stdio.h> unsigned int fact(int m) { unsigned int i,f; for(i=m,f=1;i>1;f*=i--); return f; } void main() { unsigned int (*ptr) (int); unsigned int n,factorial; ptr=fact; printf("Enter the Number Whose Factorial is to be Found "); scanf("%u",&n); factorial=(*ptr) (n); /* is the same as factorial=ptr(n) */ printf("Factorial of %u is %u\n",n,factorial); }

5.10.3 Passing Function Address to Another Functions: The address of a function can be passed as an argument to other functions either by a function name or a pointer that hold the address of the function. The following example illustrates these concepts. It input a set of integers and outputs the largest and smallest of them.

#include<stdio.h> int large(int *b,int m) { int big,i; big=b[0]; for(i=1;i<m;i++)

Page 97: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 97

if (b[i]>big) big=b[i]; return big; } int small( int *b, int m) { int sml,i; sml=b[0]; for( i=1;i<m;i++) if(b[i]<sml) sml=b[i]; return sml; } void select( int *b1, int m1, int (*q)(int *d1,int m2)) { int ans; ans=q(b1,m1); printf("%i",ans); } void main() { int n,i,a[20],(*ptr)(int *d,int); printf("Enter The Number of Integers:\n"); scanf("%d",&n); printf("Enter The Set of Integers"); for(i=0;i<n;i++) scanf("%i",a+i); ptr=large; printf("\nThe Largest Integer is "); select(a,n,ptr); printf("\nThe Smallest Integer is "); select(a,n,small); }

5.10.4 Passing Address to Functions: The method of passing address to function is called call by reference. In C a function can be called by the call in program in two ways.

1. Call by value 2. Call by reference

1. Call by Value: When a function is called by the calling program, the values to the arguments in the function are supplied by the calling program. The values supplied can be used inside the function. Any alteration to the value inside the function is not accepted in the calling program but the change is locally available in the function. This method is referred as calling a function by value.

Example:

#include<stdio.h> void add10(int x,int y); void main() { int a=10,b=40; printf("Before Calling a=%d b=%d",a,b); add10(a,b); printf("\nAfter Calling a=%d b=%d",a,b); } void add10(int x,int y) { x=x+10;

Page 98: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 98

y=y+10; printf("\nInside Function a=%d b=%d",x,y); }

Output:

Before Calling a=10 b=40 Inside Function a=20 b=50 After Calling a=10 b=40

Note that the variables a and b are referred by x and y in the function. Also note that the increase in their values is available only inside the function and not in the main program (calling program). Call by Reference: A function can be declared with pointers as its arguments. Such functions are called by the calling program with the address of a variable as argument from it. The addresses of the variables are substituted to the pointers and any alteration to its value inside the function is automatically carried out in that location. The change is indirectly made and is accepted by the calling program. This method is referred as calling a function by reference.

Example:

#include<stdio.h> void add10(int x,int y); void main() { int a=10,b=40; printf("\nBefore Calling a=%d b=%d",a,b); add10(&a,&b); printf("\nAfter Calling a=%d b=%d",a,b); } void add10(int *x,int *y) { *x=*x+10; *y=*y+10; printf("Inside Function a=%d b=%d",*x,*y); }

Output:

Before Calling a=10 b=40 Inside Function a=20 b=50 After Calling a=20 b=50

Note that the increase in values of the arguments a and b is available in the main program also. Difference between Call by value and Call by reference

Call by value Call by reference 1. This is the usual method to call a function in

which only the value of the variable is passed as an argument.

In this method, the address of the variable is passed as an argument.

2. Any alteration in the value of the argument passed is local to the function and is not accepted in the calling program.

Any alteration in the value of the argument passed in accepted in the calling program (since alteration is made indirectly in the memory location using the pointer)

3. Memory location occupied by formal and actual arguments is different.

Memory location occupied by formal and actual arguments is same and there is a saving of memory location.

Page 99: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 99

4. Since a new location is created, this method is slow.

Since the existing memory location is used through its address, this method is fast.

5. There is no possibility of wrong data manipulation since the arguments are directly used in an expression.

There is possibility of wrong data manipulation since the addresses are used in an expression. A good skill of programming is required here.

Note: If we define an array in a function with auto class, we cannot pass the address of that array back to the main() for subsequent work. 5.10.5 Function Returning Pointers: The function return an int, a float, a double or any other data type, it is also possible to return a pointer.

data type *function-name(argument list);

The above statement functions return an address of specific type of data, which is collected in the pointer variable.

#include<stdio.h> int *fun(); void main() { int *x; x=fun(); printf("%d",*x); } int *fun() { int y=24; return(&y); }

5.11 Pointers and Structures: We know that the name of an array stands for the address of its 0th element. The same thing is true for the names of array of structure variables. Suppose product is an array variable of struct type. The name product represents the address of its 0th element. Consider the following declaration:

struct inventory { char name[30]; int number; float price; }product[2],*ptr;

This statement declares product as an array of two elements, each of type struct inventory and ptr as a pointer to data objects of the type struct inventory.

ptr=product; would assign the address of the 0th element of product to ptr. That is, the pointer ptr will now point to product[0]. Its members can be accessed using the following notation. ptr->name

ptr->number ptr->price

The symbol -> is called the arrow operator and is made up of a minus sign (-) and a greater than sign (>). Note ptr-> is simply another way to writing product[0].

Page 100: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 100

When the pointer ptr is incremented by 1, it is made to point to the next record i.e. product[1]. The following for statements will print the values of members of all the elements of product array. for(ptr=product;ptr<product+2;ptr++) printf(“%s %d %f\n”,ptr->name, ptr->number,ptr->price); we could also use the notation (*ptr).number to access the member number. The parentheses around *ptr are necessary because the memory operator “.” has a higher precedence than the operator *.

#include<stdio.h> struct invent { char * name[20]; int number; float price; }; void main() { struct invent product[3],*ptr; printf("Input\n\n"); for(ptr=product;ptr<product+3;ptr++) scanf("%s%d%f",ptr->name,&ptr->number,&ptr->price); printf("\nOutput\n\n"); ptr=product; while(ptr<product+3) { printf("%s\t%d\t%f\t",ptr->name,&ptr->number,&ptr->price); ptr++; } }

While using structure pointers, we should take case of the precedence of operator. The operator -> and ‘.’ and () and [] enjoy highest priority among the operators. They bind very tightly with their operands. For example, given the definition struct { int count; float *p; }*ptr; then the statement ++ptr->count increments count, not ptr. However (++ptr)->count; increments ptr first, and then links count. The statement ptr++->count; is legal and increments ptr after accessing count. The following statements also behave in the similar fashion.

*ptr->p Fetches whatever p points to. *ptr->p++ Increments p after accessing whatever it points to. (*ptr->p)++ Increments whatever p points to. *ptr++->p Increments ptr after accessing whatever it points to.

Page 101: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 101

5.12 Pointer to Pointer: Suppose if we want to store the address of one pointer variable so we use a variable, which itself pointer (pointer to pointer). Pointer to pointer offers flexibility in handling arrays, passing pointer variables to functions. The general format for declaring a pointer to pointer is:

data_type **ptrvar;

which uses two asterisks (**) symbols placed beside the other. Thus the declaration implies that the variable ptrvar is a pointer to a pointer pointing to a data object of the type data type.

i J k

24

1726

1804 1726 1804 2186

In the above figure the variable k contains the address of j so k declares as a double pointer.

#include<stdio.h> void main() { int i=24, *j, **k; j=&i; k=&j; printf("Address of i=%d\n",&i); printf("Value of j=%d\n",j); printf("Address of j=%d\n",&j); printf("Value of k=%d\n",k); printf("Address of k=%d\n",&k); printf("Value of j=%d\n",*k); printf("Value of i=%d\n",*j); printf("Value of i=%d\n",**k); }

Output:

Address of i=1726 Value of j=1726 Address of j=1504 Value of k=1504 Address of k=2186 Value of j=1726 Value of i=24 Value of i=24

5.13 void Pointers: Pointers defined to be of a specific data type cannot hold the address of, say, an integer variable to a pointer of type float as illustrated below: float *fptr; int i; fptr=&i; This statement results in error during compilation. An expression to this restriction is a general purpose pointer type called the void pointer. The format for declaring a void pointer is as follows: void *vptr; This declaration uses the C reserved word void for specifying the type of the pointer. Pointers declared in this manner do not have any type associated with them and can contain the address of any type of variable (int, float, char, double etc). The following are some valid C statements: void *vptr;

Page 102: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 102

int *iptr; int i;

char c; float f; double d; vptr=&i; vptr=&c; vptr=&f; vptr=&d; iptr=&i;

Pointers to void cannot be directly dereferenced like other pointer variables by using, the indirection operator *. Prior to dereferencing a pointer to void, it must be suitably typecast to the required data type. A void pointer may be typecast by preceding its name with a relevant data type followed by an asterisk, both of which are enclosed within a pair of parentheses.

Example:

#include<stdio.h> void main() { int i=100; float f=200.5; void *vptr; vptr=&i; printf(“i=%d”,*((int *)vptr)); vptr=&f; printf(“f=%f”,*((float *)vptr)); }

The expression *((float *)vptr) is explained below. When a function is designed to do similar operations on different data types void pointers can be used to pass parameters to the function.

Note: Arithmetic operations on void pointers are not permitted unless the void pointer is appropriately typecasted but assignment can be done. 5.14 NULL: NULL has been defined in <stdio.h> as follows:

#define NULL 0 Hence during processing NULL will be replaced by 0.

sizeof(NULL)=sizeof(0)=2 5.15 NULL Pointer: A null pointer is a special pointer that is known as not to point anywhere. The most straightforward way to “get” a null pointer in our program is by using the predefined constant NULL which is defined in several standard header files, including <stdio.h>, <stdlib.h>, and <string.h>. int *ptr=0; It is also possible to refer to the null pointer by using a constant 0.

Page 103: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 103

int *ptr=0; Difference between void pointer and null pointer: A null pointer has the value 0. void pointer is a generic pointer introduced by ANSI. Before ANSI, char pointer are used as generic pointer. Generic pointer can hold the address of any data type. Difference between null pointer and uninitialized pointer: Usually a pointer is initialized to NULL. This is to tell that it is still does not have valid address. Uninitialized pointer can contain any value which we call garbage. 5.16 Pointer to Constant Objects: Consider the following declaration: const int *pi; The statement declares pi a pointer to a constant integer. Let pi be initialized by the statements int i[20]; pi=i; That is, *pi refers to the integer i[0]. Due to the declaration of pi, statements such as *pi=10; or even pi[10]=20; are not valid. Such statements result in compile time errors. But pi itself can be changed. Statement such as

pi++; are perfectly valid. These types of pointers are useful in character pointers, when pointers are to be passed to a function for printing. For example, suppose we are writing a function to print a character string. It is a good practice to code it as follows:

void print(const char *str) { printf(str); }

The function accepts a pointer of type const char * (pointer to constant character). The string being pointed to cannot be changed. This is a safety measure, since it prevents accidental modification of the string passed to the function. In the function, the pointer str itself can be changed, for example, by the statement str++; But this does not affect the calling procedure, since the pointer itself is passed by value. 5.17 Constant Pointers: The declaration int *const pi=i; declares a constant to an integer (assume that i is an integer array). In this case, statements such as *pi=10; are perfectly valid, but others which modify the pointer, such as pi++; are invalid, and result in compile time errors. A pointer declaration, such as const int *const pi=i; will disallow any modification to pi or the integer which pi as pointing to (assume that i is an integer array). 5.18 Pointer Constants: The name of an array holds the starting address of the array. Hence if arr[3] is an array of any datatype then the name of the array arr is the address of the 0th element of the array, and arr+i is the ith element of the array. If arr is a pointer, then arr+i can be replaced by

Page 104: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 104

incrementing arr, i times by using the incrementing operator i.e. performing the operation arr++, i times. But if arr is an array, using the increment operator with it (the name of the array) is incorrect as the starting address of the array has been placed in the code directly by the compiler, thus making the array name a constant. The array name does not have any storage location allocated unlike a pointer increment operation on the address of the array is like performing the incrementing operation 5++, which is meaning less. Through, it is not possible to use the increment operation on any array variable, we can assign these address to a pointer variable and then increment the pointer variable. The following example illustrates these concepts.

#include<stdio.h> void main() { static int a[3]={2,5,9}; int i,*ptr; ptr=a; for(i=0;i<3;i++) { /* printf("%d"), *(a++)); is incorrect */ printf("%d ",ptr++); } }

5.19 Use of Pointer: Uses of pointers are:

1. Accessing array element 2. Passing argument to functions by reference 3. Passing arrays and strings to functions 4. Creating data structures such as linked lists, trees, graphs, and so on 5. Obtaining memory from the system dynamically

5.20 Advantage of Pointer:

1. Pointers reduce the length and complexity of the program. 2. They increase the execution speed. 3. Pointers are more efficient in holding the data tables. 4. The use of pointer array to a character string results in saving of data storage space in

memory. 5. A pointer enables us to access a variable that is defined outside the function.

5.21 File: A file is a collection of related information defined by its creator. Such information is stored on the memory device in the form of a data file. Thus, ‘data file’, allows us to store information permanently, and to access and alter that information whenever necessary. Files are two types:

1. Stream-oriented (or standard) data files 2. System-oriented (or low level) data files 1. Stream-Oriented: These are of two types:

a) Text Files: Consisting of consecutive characters. These characters can be interpreted as individual data items, or as components of strings and numbers.

b) Unformatted Files: It organizes data into blocks containing contiguous bytes of information. These blocks represent more complex data structures, such as arrays and structures.

Page 105: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 105

2. System-Oriented: These are more closely related to the computer’s operating system than stream-oriented data files. They are somewhat more complicated to work with.

Sequential and random Files: Depending on the method of accessing the data stored, files can be classified as:

1. Sequential Files 2. Random Files

In sequential files, information/data is stored sequentially one by one. The data is read in the same order in which they are stored. But in random files, information/data can be read randomly. Normally a key data is used to identify the required record in random file accessing. For example, student roll number can be used as a key field in a student data file. 5.22 Buffer Area: Before working with a stream-oriented data files, the first step is to create temporary storage of information, called buffer area, it is also called file pointer. Syntax: The buffer area is established by writing:

FILE *fp;

where, FILE (uppercase letter required) is a special structure type that establishes the buffer area, and fp is a pointer variable that indicates the beginning of the buffer area. The structure type FILE is defined within a system include file, typically stdio.h. The pointer fp is often referred to as a stream pointer or simply a stream. Example: Consider the following example:

#include<stdio.h> void main() { FILE *fileptr; ……………… ……………… }

5.23 Opening a File (fopen): A data file must be opened before it can be created or processed, by library function fopen(). Syntax:

fp=fopen(file-name, file-type);

where, file-name and file-type (mode) are strings that represents the name of the data file and the manner in which the data file will be utilized. File Opening Modes: The file-type (mode) must be one of the strings shown: “r”: Read-only mode “w”: Write-only mode “a”: Append mode “r+”: For both read + write mode “w+”: For both write + read mode “a+”: For both reading and appending mode Example: Following programs attempts to open an existing data file named sample.dat for both reading and writing:

#include<stdio.h> #define NULL 0

Page 106: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 106

void main() { FILE *fileptr; fileptr=fopen(“sample.dat,”r+”); if(fileptr==NULL) printf(“Error: Unsuccessful to open”); else { ………… ………… fclose(fileptr); } }

Note: (i) If a file is opened in “w” or “w+” mode, the contents will be erased automatically. But

the “w+” mode will facilitate reading newly entered data by moving the pointer to the previous data in the same file. When a file is created in “w” or “w+” mode, the file pointer is always set at the beginning of the file.

(ii) When a file is opened in “r” or “r+” mode, the pointer is always set at the beginning of the file.

(iii) Whenever fopen() is unsuccessful it returns NULL type pointer, which is used to generate an error message.

5.24 Closing a File (fclose): It is always good programming practice to close a file after it is used. Syntax:

fclose(fp);

Example: Refer the example i.e. the statement fclose(fileptr); 5.25 EOF: It is a constant defined in the header stdio.h, it indicated ‘End of File’ and is activated when pressing two buttons ctrl along with z. 5.26 feof(): This is used to locate the end of a file while reading data. Syntax:

feof(fp);

This function will return a 0 when the file contains data and return a non-zero integer when the end of a file is reached. Example: FILE *fileptr; if(feof(fileptr)==0) printf(“\nData available in the file”); else printf(“\nEnd of file is reached”); 5.27 rewind(): rewind() is used to move the file pointer to the beginning of a file. Syntax:

rewind(fp);

Example:

Page 107: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 107

rewind(fileptr); 5.28 The getc and putc Functions: The simplest file I/O functions are getc and putc. These are analogous to getchar and putchar functions and handle one character at a time.

(i) getc(): getc() is used to read a character in a file. Syntax:

charvar=getc(fp);

Example: FILE *fileptr; char c; c=getc(fileptr) Note that the character read from the file is assigned to the char variable c.

(ii) putc(): putc() is used to write a character to a file. Syntax:

putc(charvar,fp); Example: FILE *fileptr; char c; putc(c,fileptr);

Program:

#include<stdio.h> #include<conio.h> void main() { FILE *fp; char ch; clrscr(); fp=fopen("FIRST.TXT","w"); if(fp!=NULL) { printf("Enter a Line of Text:\n"); while((ch=getche())!='\r') { putc(ch,fp); } fclose(fp); fp=fopen("FIRST.TXT","r"); if(fp!=NULL) { printf("\nFile Contents:\n"); while(1) { ch=getc(fp); if(ch==EOF) break; printf("%c",ch); } } else { printf("File Can't Open"); } fclose(fp); }

Page 108: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 108

else { printf("File Can't Create"); } getch(); }

5.29 The getw and putw Functions: The getw and putw are integer-oriented functions. They are similar to the getc and putc function and are used to read and write integer values. These functions would be useful when we deal with only integer data.

(i) getw(): getw() is used to read an integer. Syntax:

intvar=getw(fp);

Example: FILE *fileptr; int n; n=getw(fileptr);

(ii) putw(): putw() is used to write an integer data to a file. Syntax:

putw(intvar,fp); Example: FILE *fileptr; int n; putw(n,fileptr);

Program:

#include<stdio.h> #include<conio.h> void main() { int i,no; FILE *fp; clrscr(); fp=fopen("THIRD","w+"); if(fp!=NULL) { printf("Enter 5 Numbers:\n"); for(i=1;i<=5;i++) { scanf("%d",&no); putw(no,fp); } rewind(fp); printf("\nFile Contents:\n"); while(1) { no=getw(fp); if(feof(fp)) break; else printf("%d\n",no); } fclose(fp);

Page 109: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 109

} getch(); }

5.30 The fprintf and fscanf Functions: Many data items consists of complex data structures, such as structures that contain various combinations of numeric and character information such data files can be processed using the library functions fscanf and fprintf, these are formatted I/O functions.

(i) fprintf(): fprintf() is used to write data to a file. It is similar to the printf()except that fprintf() is used to write data to the disk. Syntax:

fprintf(fp,”format string”,list);

where, fp is a file pointer, formatstring contains output specifications for the items in the list. The list may include variables, constants, and string. Example: fprintf(fileptr,%s%s%f,name,age,7.5); Here name is an array of characters and age is an integer variable.

(ii) fscanf(): fscanf() is used to read data from a file. It is similar to scanf() except that fscanf() is used to read data from the disk. Syntax:

fscanf(fp,”format string”,list); Example: fscanf(fileptr,%s%d”,item,&quantity);

Program:

#include<stdio.h> #include<conio.h> void main() { int i,rno; char name[15]; FILE *fp; clrscr(); fp=fopen("SECOND.DAT","w+"); if(fp!=NULL) { printf("Enter Roll No. and Name of 5 Students:\n"); for(i=0;i<5;i++) { scanf("%d%s",&rno,name); fprintf(fp,"%d %s\n",rno,name); } rewind(fp); printf("\nFile Records Are:\n"); while(!feof(fp)) { fscanf(fp,"%d %s\n",&rno,name); printf("%3d %-15s\n",rno,name); } fclose(fp); } getch();

Page 110: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 110

}

5.31 Random File Accessing: In random file accessing any required record can be read at random. Records in a file can be skipped by specifying the bytes occupied by those records. Consider a structure (record) of students with the data members as specified below.

struct student { int rno; char sname[20]; int total; }s;

The size of this structure is 24 bytes. This can also be obtained using the following expression inside the sizeof() function sizeof(s). Consider a file “Student.dat” with a few records of the above structure.

Note that the random files are also declared and accessed using file pointers. 5.31.1 The fseek and ftell Functions: These functions are used to move and locate the position of file pointer.

(i) fseek(): fseek() is used to move the file pointer to any position in a file from a given reference position. Syntax:

fseek(fp,n,ref-pos);

where fp refers to file pointer n refers to the number of bytes to be skipped ref-pos refers to the reference position from which n number of bytes are to be skipped Following are the symbols for reference positions.

Value Symbol Reference 0 SEEK_SET From the beginning of a file 1 SEEK_CUR From the current position of the file 2 SEEK_END From the end of a file.

Page 111: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 111

Example: (a) fseek(fileptr,sizeof(s),SEEK_SET);

will first set the file pointer to the first record and then move the file pointer n number of bytes forward.

(b) fseek(fileptr, -n, SEEK_CUR); will move the file pointer n number of bytes backward. If n is equal to the size of the structure, then the file pointer is set to the previous record in the file.

(ii) ftell(): ftell() is used to locate the current position of the file pointer. Syntax:

n=ftell(fp);

where fp refers to the file pointer n refers to the byte number of the current position Note that the byte numbers starts from 0 and is incremented in steps of 1. Example: p=ftell(fileptr); Note that p will be assigned to the current position. Assume ‘p’ may be assigned a value 126 which represents the 126th byte in the file.

5.31.2 The fread and fwrite Functions: These functions are used read and write structure and array to a file.

(i) fread(): fread() is used to read a structure from a file. Note that the values of the data members in the structure are read together. Syntax:

fread(&s,m,n,fp);

where s refers to the structure variable m refers to the size of structure n refers to the number of structures to be read from a file. Usually it is assigned 1 fp refers to the file pointer Example: fread(&student,sizeof(student),1,fileptr);

(ii) fwrite(): fwrite() is used to write a structure to a file. The values of data members in the structure are written together. Syntax:

fwrite(&s,m,n,fp);

where s refers to the structure variable m refers to the size of the structure n refers to the number of structures to be written to a file. Usually it is assigned 1 fp refers to the file pointer Example: fwrite(&student,sizeof(student),1,fileptr);

Page 112: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 112

Program:

#include<stdio.h> #include<conio.h> void main() { int i,rno; char name[15]; FILE *fp; clrscr(); fp=fopen("SECOND.DAT","w+"); if(fp!=NULL) { printf("Enter Roll No. and Name of 5 Students:\n"); for(i=0;i<5;i++) { scanf("%d%s",&rno,name); fprintf(fp,"%d %s\n",rno,name); } rewind(fp); printf("\nFile Records Are:\n"); while(!feof(fp)) { fscanf(fp,"%d %s\n",&rno,name); printf("%3d %-15s\n",rno,name); } fclose(fp); } getch(); }

5.32.3 The remove and rename Functions: These functions are used to remove and rename a file.

(i) remove(): remove() is used to erase or remove a file from the disk. Syntax:

remove(“filename”);

where filename refers to the name of the file to be removed. Example: remove(“Student.dat”);

(ii) rename(): rename() is used to rename an existing file. Syntax:

rename(“old filename”,”new filename”);

Example: rename(“Student.dat”,”Stdrec.dat”);

Make sure that files are closed before remove and rename functions will be used. 5.33 Errors during File Processing: When an error is encountered during file processing, the program execution will be terminated and error messages will be displayed. Following measures may be adopted to identify or avoid errors during file processing.

(i) ferror function can be used to detect any error during file accessing. This function will return a zero when there is no error, otherwise it will return a non-zero number. FILE *fileptr; if(ferror(fileptr)==0)

Page 113: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 113

printf(“\nThe file is available for processing”); else printf(“\nError in accessing thefile!!!”);

(ii) To verify whether a file exists in the disk, the following definitions will help. if(fileptr==NULL) printf(“\nNo content or file does not exist”);

(iii) When data in a file may be exhausted, end of file condition will be encountered. Use the following definition to display end of file condition. if(feof(fileptr)==EOF) printf(“\nEnd of file is reached”); Note that EOF is a macro which specifies the end of file condition.

Entering an invalid file name or trying to write data to a write protected disk are some of the other reasons for errors during file processing. 5.34 Command Line Arguments: What is a command line argument? It is a parameter supplied to a program when the program is invoked. This parameter may represent a filename the program should process. For example, if we want to execute a program to copy the contents of a file named A to another one named B, then we may use a command line like C:\> Filecopy A B Filecopy is the filename where the executable code of the program is stored. This eliminates the need of the program to request the user to enter the filenames during execution. How do these parameters get into the program? We know that every C program should have one main function and that it marks the beginning of the program. But it can also take arguments like other functions. main() can take two arguments called argc and argv and the information contained in the command line is passed on to the program through these arguments, when main() is called up by the system. The variable argc is an argument counter that counts the number of arguments on the command line. The argv is an argument vector and represents an array of character pointers that points to the command line arguments. The size of this array is equal to the value of argc. For the command line given above, argc is three and argv is an array of three pointers to strings as shown below.

argv[0] Filecopy argv[1] A argv[2] B

In order to access the command line arguments, we must declare the main()as its parameters as follows:

void main(int argc, char *argv[]) { ……………… ……………… }

The keyword void is optional. It is not necessary that we should always use the variable names argc and argv. In place of these any other variable names can also be used. The first parameter in the command line is always program name and therefore argv[0] always represents the program name.

Example:

#include<stdio.h>

Page 114: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 114

#include<conio.h> void main(int argc,char *argv[]) { int i; printf("Total Number of Arguments=%d\n",argc); printf("Arguments Are:\n"); for(i=0;i<argc;i++) printf("%s\n",argv[i]); getch(); }

Output:

C:\TURBOC3\SOURCE\T.EXE Total Number of Arguments=4 Arguments Are: C:\TURBOC3\SOURCE\T.EXE 1 2 3

5.35 C Preprocessor: The C source code may include instructions for the compiler, which are executed at the beginning of the compilation process. These instructions are known as preprocessor commands or directives. Rules for Defining a Preprocessor:

(i) All preprocessor directives must begin with the sharp sign (#). (ii) They must start in the first column and on most C++ compiler there can be no space

between sign and directive. (iii) The preprocessor directive is not terminated by semicolon. (iv) Only one preprocessor directive can occur in a line.

Example: Some commonly used preprocessor directives are: #include, #define, #undef, #if, #else, #error etc. These directives can be divided into three categories:

1. Macro substitution directives 2. File inclusion directives 3. Conditional compilation directives

1. Macro Substitution Directives: Macro substitution is a process where an identifier is

replaced by a predefined string composed of one or more tokens. The preprocessor accomplishes this task under the direction of #define statement. This statement, usually known as a macro definition (or simply a macro) takes the following form:

#define identifier string

If this statement is included in the program at the beginning, then the preprocessor replaces every occurrence of the identifier in the source code by the string. There are different forms of macro substitution. The most common forms are:

a) Simple Macro Substitution: Simple string replacement is commonly used to define constants. Examples of definition of constant are:

#define PI 3.141592

Page 115: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 115

#define FALSE 0 #define SIZE sizeof(int)*4 #define TEST if(x>y)

Notice that we have written all macros (identifiers) in capitals. It is a convention to write all macros in capitals to identify them as symbolic constant. A definition, such as #define M 5 will replace all occurrences of M with 5, starting from the line of definition to the end of the program. However, a macro inside a string does not get replaced. Consider the following two lines: total=M*value; printf(“M=%d\n”,M); These two lines would be changed during preprocessing as follows: total=5*value; printf(“M=%d\n”,5); Notice that the string “M=%d\n” is left unchanged. Whenever we use expressions for replacement, care should be taken to prevent an unexpected order of evaluation. Consider the evaluation of the equation ratio=D/A; where D and A are macros defined as follows: #define D 45-22 #define A 78+32 The result of the preprocessor’s substitution for D and A is: ratio=45-22/78+32; This is certainly different from the expected expression (45-22)/(78+32) Correct result can be obtained by using parentheses around the strings as shown below: #define D (45-22) #define A (78+32) It is a wise practice to use parentheses for expressions used in macro definitions.

b) Argumented Macro Substitution: The preprocessor permits us to define more complex and more useful form of replacements. It takes the form:

#define identifier(f1, f2,….,fn) string

Notice that there is no space between the macro identifier and the left parentheses. The identifiers f1, f2,……, fn are the normal macro arguments that are analogous to the formal arguments in a function definition. There is a basic difference between the simple replacement and replacement of macros with arguments. When a macro is called, the preprocessor substitutes the string, replacing the formal parameters with the actual parameters. Here, the string behaves like a template. A simple example of a macro with arguments is #define CUBE(x) (x*x*x) If the following statement appears later in the program volume=CUBE(side); then the preprocessor would expand this statement to: volume=(side*side*side);

Page 116: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 116

Consider the following statement: volume=CUBE(a+b); This would expand to: volume=(a+b * a+b * a+b); which would obviously not produce the correct results. This is because the preprocessor performs a blind text substitution of the argument a+b in place of x. this shortcoming can be corrected by using parentheses for each occurrence of a formal argument in the string. Example #define CUBE(x) ((x) * (x) * (x)) This would result in correct expansion of CUBE(a+b) as shown below: volume=((a+b) * (a+b) * (a+b)) Remember to use parentheses for each occurrence of a formal argument, as well as the whole string.

c) Nested Macro Substitution: We can also use one macro in the definition of another macro. This is, macro definitions may be nested. For example, consider the macro definitions:

#define SQUARE(x) ((x) * (x)) #define CUBE(x) (SQUARE(x) * (x)) #define SIXTH(x) (CUBE(x) * CUBE(x))

The preprocessor expands each #define macro, until no more macros appear in the text. For example, the last definition is first expanded into ((SQUARE(x) * (x)) * (SQUARE(x) * (x))) Since SQUARE(x) is still a macro it is further expanded into ((((x) * (x)) * (x)) * (((x) * (x)) * (x))) which is finally evaluated as x6.

2. File Inclusion Directives: A file inclusion directive is commonly used to include the contents of standard header files in a C program and any previously written program in a new program. This enables the user to use the functions and macros defined in the program. Even bigger programs stored in different files can be included in a new program as a header file. It has the following general form.

#include <filename> or

#include “filename” Example: #include <stdio.h> #include <string.h> When the file name is given inside angle brackets, the computer will search the file only in the specified list of directories available in the storage device (hard disk). #include “SAMPLE.C” #include “EMPLOY.C” When the file name is given inside double quotes, the computer will search the file in the directory where the C programs are stored and in the specified list of other directories.

3. Conditional Compilation directives: The conditional compilation directives, as their name implies, permits us to compile selective portion of the program. This process of selective compilation is known as conditional compilation and is widely used by commercial software

Page 117: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 117

houses that provide and maintain many customized version of one program. The following are the preprocessor conditional commands: #if, #else, #endif, #ifdef, #ifndef etc.

1) #if Directive: If the constant expression following #if is true, the code between it and #endif will be executed otherwise the code is ignored. The #endif is used to mark the end of a #if or #else of #ifdef block. Syntax:

#if constant_expression statement sequence #endif

Example: #include<stdio.h> #define sum 100 void main() { #if(sum==100) printf(“Hello”); #endif }

Output: Hello

2) #else Directive: The #else directive works the same way as else statement. It provides an alternative to the #if directive. Syntax:

#if constant statement 1 #else Statement 2 #endif

3) #elif Directive: The #elif directive means else if and is used to establish an if-

else-if ladder for compilation option. Syntax:

#if exp1 statement 1 #elif exp2 statement 2 ……………… ……………… #else statement n #endif

4) #ifdef and #ifndef Directives: The directive #ifdef means if defined.

Syntax: #ifdef macro_name statement sequence #endif

Page 118: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 118

If the macro_name has been previously defined in #define statement, the statement sequence between the #ifdef and #endif is compiled. The directive #ifndef means if not defined. Syntax:

#ifndef macro_name statement sequence #endif

If the macro_name is currently not defined by #define statement, the statement sequence between the #ifndef and #endif is compiled.

5) #undef Directive: The #undef directive is used to remove the previous definition of the macro_name that follow it. Syntax:

#undef macro_name Example:

#define MAX 20 #define LINE 10 ……………… ……………… #undef MAX

6) #pragma Directive: The #pragma is an implementation oriented directive that allows us to specify various instructions to be given to the compiler. Syntax:

#pragma name

Where name is the name of the pragma we want. For example #pragma loop_opt(on) causes loop optimization to be performed. It is ignored, if the compiler does not recognize it.

7) #error Directive: The #error directive is used to produce diagnostic messages during debugging. Syntax:

#error error message

When the #error directive is encountered, it displays the error message and terminates processing. Example: #if !defined(FILE_G) #error NO GRAPHIC FACILITY #endif

8) Stringizing operator (#): ANSI C provides an operator # called stringizing operator to be used in the definition of macro functions. This operator allows a formal argument within a macro definition to be converted to a string.

Page 119: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 119

Example: #define(sum(xy) printf(#xy “=%f\n”,xy); void main() { ……… ……… sum(a+b); ……… }

The preprocessor will convert the line sum(a+b) into

printf(“a+b” “=%f\n”, a+b); which is equivalent to

printf(“a+b=%f\n”, a+b); Note that the ANSI standard also stipulates that adjacent strings will be concatenated.

9) Token Parsing Operator (##): The token parsing operator #defined by ANSI standard enables us to combine two tokens within a macro definition to form a single token. For example:

#define combile(s1,s2) s1 ## s2 void main() { ……… ……… printf(“%f”,combine(total,sales)); ……… }

The preprocessor transforms the statement printf(“%f”,combine(total,sales)); into the statement printf(“%f”,totalsales); Consider another macro definition: #define print(i) printf(“a”#i ”=%f”,a##i) This will convert the statement print(5); into the statement printf(“a5=%f”,a5);

5.36 Dynamic Memory Allocation: Dynamic memory allocation refers to the method of allocating a block of memory and releasing it when the memory is not required at the time of running the program. A block of memory can be used to store values of simple or subscripted variables, and a block of memory can be accessed using a pointer. Following are the functions used in dynamic memory allocation, and these functions are available in the header file <alloc.h> or <stdlib.h>. 1. malloc() Function: malloc() function is used to allocate a single block of memory to store values of specific data type. It also assigns the address of the first byte of the allocated space to a pointer. It has the following form.

ptr=(type *)malloc(size);

where ptr refers to pointer variable

Page 120: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 120

type refers to the data type to be stored in memory size refers to number of bytes to be allotted

Consider the following examples to allocate 100 bytes. int *p; p=(int *)malloc(100); p=(int *)malloc(50*sizeof(int))

The allotted space can be used to store 50 int type values, and the block of memory can be accessed by the pointer p of the same type.

Example:

#include<stdio.h> #include<stdlib.h> void main() { int *p,n,i; printf("How many elements?: "); scanf("%d",&n); if(!(p=(int *)malloc(n*sizeof(int)))) { printf("No memory"); exit(1); } printf("Enter the elements:\n"); for(i=0;i<n;i++) scanf("%d",p+i); printf("Entered elements are:\n"); for(i=0;i<n;i++) printf("%d\n",*(p+i)); free(p); }

2. calloc () Function: calloc() function is used to allocate memory in multiple blocks of same size during the program execution. The space allotted is used to store values of an array or structure. This function assigns the address of the byte of the allotted space to a pointer. It also assigns 0 as the initial value for all bytes in the block of memory. It has the following form.

ptr=(type *)calloc(n,m)

where ptr refers to pointer variable type refers to the data type to be stored in memory n refers to number of blocks to be allotted m refers to number of bytes in each block of memory Consider the following example to allocate 50 blocks of 4 byte each. The total size of space allotted is 200 bytes. float *p; p=(float *)calloc(50,4); p=(float *)calloc(50,sizeof(float)); The allotted space may be used to store 50 float type values and are accessed by the pointer p of the same type. Note that a NULL pointer is returned when there is insufficient space in memory.

Example:

#include<stdio.h> #include<stdlib.h>

Page 121: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 121

void main() { int n,i,*p; printf("How many values? "); scanf("%d",&n); p=(int *)calloc(n,2); printf("Enter all values\n"); for(i=0;i<n;i++) scanf("%d",(p+i)); printf("\nThe reversed list is\n"); for(i=n-1;i>=0;i--) printf("%d\n",*(p+i)); free(p); }

3. realloc() Function: realloc() function is used to modify or reallocate the memory space which is previously allotted. This facilitates to increase or reduce the allotted space at a later stage in program. It is just a reallocation of memory and the first byte address of the newly allotted space is assigned to the pointer. It has the following form.

ptr=realloc(ptr,size);

where ptr refers to pointer variable of existing and new block size refers to number of bytes to be allotted newly

Consider the following example to modify or reallocate the existing block of memory space. int *p;

p=(int *)malloc(100); ……………………… ……………………… p=realloc(p,400);

The previously allotted space of 100 bytes to the pointer p is modified as 400 bytes at a later stage of the program.

Example:

#include<stdio.h> #include<stdlib.h> void main() { int *p,n,m,i; char ch; printf("How many elements?: "); scanf("%d",&n); if(!(p=(int *)malloc(n*sizeof(int)))) { printf("No memory"); exit(1); } printf("Enter the elements:\n"); for(i=0;i<n;i++) scanf("%d",p+i); printf("Entered elements are:\n"); for(i=0;i<n;i++) printf("%d\n",*(p+i)); printf("Do you want to enter more elements[y/n]: "); fflush(stdin); scanf("%c",&ch);

Page 122: C NOTES

Problem Solving and Logic Building using C

Prepared by Mr. K. G. Page 122

if(ch=='y'||ch=='Y') { printf("How many elements?: "); scanf("%d",&m); if(!(p=(int *)realloc(p,m*sizeof(int)))) { printf("No memory"); exit(1); } printf("Enter the elements:\n"); for(i=0;i<m;i++) scanf("%d",p+i); printf("Entered elements are:\n"); for(i=0;i<m;i++) printf("%d\n",*(p+i)); } free(p); }

4. free() Function: free() function is used to release the memory space which is allotted using malloc() or calloc() or realloc() function. It has the following form.

free(ptr);

where ptr is the pointer which refers to the allotted space in memory. Example: free(p); When this function is executed, the allocated blocks of memory are released. It is recommended practice to release the memory just before the termination of the program execution.