Mastering C [2 ed.]
 9332901279, 9789332901278

Table of contents :
Title
Contents
1 INTRODUCTION
2 VARIABLES AND EXPRESSIONS
3 BASIC INPUT-OUTPUT
4 CONTROL STRUCTURES
5 FUNCTIONS
6 SCOPE AND EXTENT
7 ARRAYS AND STRINGS
8 POINTERS
9 STRUCTURES AND UNIONS
10 FILES
11 DYNAMIC MEMORY ALLOCATION
12 DATA STRUCTURES
13 UNIX OPERATING SYSTEM
14 C LIBRARY FUNCTIONS
15 CONTROLLING COMPLEXITY
16 QUICK REFERENCE
17 ANSWERS TO EXERCISES
18 SOLUTIONS
APPENDIX
BIBLIOGRAPHY
INDEX

Citation preview

C

MASTERING Second Edition

About the Authors K R VENUGOPAL is presently serving as Principal UVCE and Professor of Computer Science and Engineering. He was the Chairman, Department of Electronics, Computer Science and Information Technology, and Principal (Evening College) at University Visvesvaraya College of Engineering, Bangalore University, Bangalore, India during 2000–2004. He has degrees in Electronics, Economics, Law, Journalism, Business Finance, Communication, Industrial Relations, Public Relations and Computer Science. He obtained ME (CSE) from Department of Computer Science and Automation at the Indian Institute of Science, Bangalore. He has obtained PhD in Economics from Bangalore University and PhD in Computer Science from IIT, Madras. He has authored and edited 51 books in Computer Science and Engineering and Economics. His areas of interest include Optical Networks, Ad Hoc Networks, Data Mining and Digital Signal Processing. He has published more than 400 papers in refereed International Journals and Conferences. Besides these, being a prolific inventor, Dr Venugopal has filed 80 patents. SUDEEP R PRASAD is presently serving as a Lead Architect, Philips Innovation Campus, Bangalore, India. He obtained his degree in Computer Science and Engineering from University Visvesvaraya College of Engineering, Bangalore University, Bangalore, India. He develops products in the Healthcare domain. His interests include Software Engineering, Failure Analysis Techniques and Serviceability.

C

MASTERING Second Edition

K R Venugopal Principal and Professor Department of Computer Science and Engineering University Visvesvaraya College of Engineering Bangalore University, Bangalore Sudeep R Prasad Lead Architect Philips Innovation Campus, Bangalore

McGraw Hill Education (India) Private Limited NEW DELHI McGraw Hill Education Of�ices

New Delhi New York St Louis San Francisco Auckland Bogotá Caracas Kuala Lumpur Lisbon London Madrid Mexico City Milan Montreal San Juan Santiago  Singapore Sydney Tokyo Toronto

Published by McGraw Hill Education (India) Private Limited, P-24, Green Park Extension, New Delhi 110 016. Mastering C, 2e Copyright © 2015, 2007, by McGraw Hill Education (India) Private Limited. No part of this publication may be reproduced or distributed in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise or stored in a database or retrieval system without the prior written permission of the publishers. The program listings (if any) may be entered, stored and executed in a computer system, but they may not be reproduced for publication. This edition can be exported from India only by the publishers, McGraw Hill Education (India) Private Limited. Print Edition: ISBN (13): 978-93-329-0127-8 ISBN (10): 93-329-0127-9 E-Book Edition: ISBN (13): 978-93-329-0128-5 ISBN (10): 93-329-0128-7 Managing Director: Kaushik Bellani Head—Products (Higher Education & Professional): Vibha Mahajan Asso. Sponsoring Editor: Smruti Snigdha Manager—Production Systems: Satinder S Baveja Sr. Production Manager: P L Pandita Sr. Graphic Designer—Cover: Meenu Raghav Sr. Publishing Manager: Shalini Jha Asst. Product Manager: Tina Jajoriya General Manager—Production: Rajender P Ghansela Manager—Production: Reji Kumar Information contained in this work has been obtained by McGraw Hill Education (India), from sources believed to be reliable. However, neither McGraw Hill Education (India) nor its authors guarantee the accuracy or completeness of any information published herein, and neither McGraw Hill Education (India) nor its authors shall be responsible for any errors, omissions, or damages arising out of use of this information. This work is published with the understanding that McGraw Hill Education (India) and its authors are supplying information but are not attempting to render engineering or other professional services. If such services are required, the assistance of an appropriate professional should be sought. Typeset at Script Makers, 19, A1-B, DDA Market, Paschim Vihar, New Delhi 110 063 and printed at Cover Designer: Cover printed at: Visit us at: www.mheducation.co.in

Dedicated to Karthyayini V Tejaswi V

Contents Foreword Preface

xiii xv

1. Introduction 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 1.19 1.20 1.21

Computers 1 Classification of Computers 3 Numbers 3 System Software 7 Software Life Cycle 7 Algorithms 8 Algorithm Examples 8 Flowcharts 10 Pseudocode 12 Recursive Algorithms 13 Structured Programming 14 Hello World 14 Compilers 16 Operating Systems 17 Running C Programs 17 Linker 18 Preprocessor 19 Case Sensitiveness 19 Statement Separation 19 Standard Input and Output Devices Popular Features of C 20 Exercises 21

1

20

2. Variables and Expressions 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16

Introduction 23 Character Set 23 Identifiers and Keywords 24 Variables 24 Displaying Variables 25 Reading Variables 27 Characters and Character Strings 28 Qualifiers 30 typedef Statement 32 Promotion and Typecasting 32 Value-initialized Variables 34 Constants 34 const Qualifier 38 Operators and Expressions 40 Operator Precedence and Associativity Programming Examples 53 Exercises 55

23

51

viii

Contents

3. Basic Input-Output 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13

4. Control Structures 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14

85

Introduction 85 if Statement 85 if-else Statement 88 Multi-way Decisions 92 Compound Statements 93 Loops 94 for Loop 95 while Loop 99 do-while Loop 101 break Statement 104 switch Statement 105 continue Statement 111 goto Statement 112 Programming Examples 113 Exercises 122

5. Functions 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12

65

Introduction 65 Single Character Input-Output 65 String Input and Output 66 General Output 66 General Input 70 Types of Characters in Format Strings 72 scanf Width Specifier 74 Search Sets 74 Assignment Suppression Character 75 Format Specifiers for scanf 77 Input Fields for scanf 78 When scanf Stops Scanning 78 Programming Examples 79 Exercises 80

Introduction 136 Function main 136 Where are Functions Useful? 137 Functions Accepting More than One Parameter 144 User Defined and Library Functions 145 Concepts Associated with Functions (Review) 145 Function Parameters 149 Return Values 151 Recursion 156 Comparison of Iteration and Recursion 160 Variable Length Argument Lists 160 Programming Examples 162 Exercises 171

136

Contents

6. Scope and Extent

ix

179

6.1 Introduction 179 6.2 Scope 180 6.3 Extent 184 Exercises 191

7. Arrays and Strings 7.1 7.2 7.3 7.4 7.5 7.6 7.7

197

Introduction 197 How Arrays are Useful? 197 Multidimensional Arrays 203 Strings 211 Arrays of Strings 212 Functions in string.h 213 Programming Examples 215 Exercises 223

8. Pointers 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 8.10 8.11 8.12 8.13 8.14 8.15 8.16 8.17 8.18 8.19 8.20 8.21 8.22 8.23 8.24 8.25 8.26

231

Introduction 231 Definition and Uses of Pointers 232 Address Operator & 232 Pointer Variables 234 Dereferencing Pointers 237 void Pointers 240 Pointer Arithmetic 241 Pointers to Pointers 244 Pointers and Arrays 245 Passing Arrays to Functions 247 Pointers and Functions 250 Accessing Arrays Inside Functions 252 Pointers and Two-dimensional Arrays 254 Pointers and Three-dimensional Arrays 255 Array of Pointers 257 Pointer Constants 258 Pointers and Strings 260 Pointers in Standard String Library Functions 261 Two-dimensional Array of Characters 265 Array of Pointers to Strings 266 More String Library functions 268 Pointers to Functions 274 More Examples on Pointer Definitions 277 Pointers to Constant Objects 278 Constant Pointers 278 Programming Examples 279 Exercises 282

9. Structures and Unions 9.1 Introduction 292 9.2 Declaring and Using Structures 9.3 Structure Initialization 296

292 295

x

Contents

9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 9.12 9.13 9.14 9.15 9.16 9.17

Structure within Structure 296 Operations on Structures 297 Array of Structures 298 Array within Structure 300 Creating User Defined Data Types 300 Pointers to Structures 303 Pointers within Structures 304 Structures and Functions 306 Unions 324 Differences between Structures and Unions Operations on A union 327 Scope of A union 327 Bit Fields in Structures 328 Programming Examples 328 Exercises 329

325

10. Files 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 10.10 10.11 10.12

337 Introduction 337 End of File 340 File-handling Functions 341 File Types 344 Unbuffered and Buffered Files 346 Error Handling 349 More on File Handling Functions 351 Low Level File I\O 354 Redirection and Piping 355 Command Line Arguments 359 Directory Functions 359 Programming Examples 361 Exercises 364

11. Dynamic Memory Allocation 11.1 11.2 11.3 11.4 11.5

Introduction 370 Library Functions for Dynamic Memory Allocation Dynamic Multi-dimensional Arrays 375 Self-Referential Structures 379 Programming Examples 386 Exercises 397

12. Data Structures 12.1 12.2 12.3 12.4 12.5 12.6

Arrays 402 Linked Lists 410 Stacks 424 Queues 435 Trees 455 Graphs 478 Exercises 488

370 371

402

Contents

13. UNIX Operating System 13.1 13.2 13.3 13.4 13.5 13.6 13.7 13.8 13.9 13.10 13.11

xi

491

Introduction 491 File System and Associated UNIX Commands 491 File System Commands 492 Programming Interface to File System 496 Redirection with dup and dup2 System Calls 504 System Calls for Process Control 505 IPC: Communication between Processes 507 Pipes 508 Message Passing 509 Shared Memory 511 Semaphores 513 Exercises 514

14. C Library Functions

518

14.1 Introduction 518 14.2 Library Functions 519 Exercises 551

15. Controlling Complexity 15.1 15.2 15.3 15.4

16. Quick Reference 16.1 16.2 16.3 16.4 16.5 16.6 16.7 16.8 16.9 16.10

554

Introduction 554 make Utility 556 Automating the Automation 557 Structured Programming 557 Exercises 558

559

C Keywords 559 L-values and R-values 559 Type Conversions 560 Storage Class 560 Type Specifiers 560 limits.h and float.h 561 Input-Output Specifiers 561 Preprocessing 565 Trigraph Sequences 568 ASCII Table 569 Exercises 573

17. Answer to Exercises

578

18. Solutions

611

Appendix: Interview Questions

688

Bibliography

692

Index

694

Foreword The study of Computer Science has gained tremendous importance alI over the world. Though the growth has been phenomenal in developed countries; the non-availability of computer books at reasonable prices is viewed as a major hurdle in the developing countries towards achieving a level of advancement in some areas of computer technology akin to the developed countries. Hence, it is all the more desirable to encourage indigenous writers who possess good knowledge of computers to publish their works so that quality books are available to the readers at affordable prices. This book, in particular, is well compiled and the authors have spent a great deal of effort and time in writing it. Two aspects of the book impressed me; the first relates to the language used which is simple and supplemented by well-drawn illustrations. The second aspect is that the book has a number of well designed and tested examples to suit the beginners. It has excellent set of exercises and solutions are provided at the end of the book. The earlier books of Venugopal, Mastering C++ and Microprocessor x86 Programming have been well received by the students and teachers of several Universities. The book consists of 18 chapters including a chapter on Data Structures. A separate chapter on UNIX is designed to highlight the features of C in the UNIX environment. I am sure that this book will be of immense help to students of engineering, graduate degree and diploma courses. I strongly recommend it to all those who seriously intend to pursue the art of programming with C.

Dr N R Shetty Former President, Indian Society for Technical Education (ISTE), New Delhi, Former Vice Chancellor, Bangalore University, Bangalore, India

Preface About the Book The programming languages have become increasingly important with the advancement of computer technology. It is essential to write efficient programs in order to handle a large amount of data. Efficient high-level languages like C in conjunction with powerful computers have helped in solving large and complex problems in reasonable time.

Who Can Use this Book? Mastering C is targetted at the students of science and engineering, particularly the undergraduate students of computer science and those who are interested in learning programming with C. Numerous programming exercises have been designed to enable students tackle and solve problems efficiently. The programs in this book have been tested for correctness and efficiency and is a good source of developing programming skills for students who wish to become ace programmers.

Salient Features of the Book ∑ Lucid explanation of basic features and syntax of the C language ∑ In-depth coverage of file manipulations, data structures, searching and sorting ∑ Numerous programming examples on advanced data structures using C-linked lists, stacks, queues, sparse matrices, trees and graphs ∑ Dedicated chapter on C in the Unix environment ∑ Enhanced pedagogical features ∑ 237 solved problems and programs ∑ 403 programming exercises ∑ 625 review exercises ∑ 124 illustrations ∑ 40 IT interview questions

New to this Edition ∑ Appendix on frequently asked questions in IT interviews ∑ 20 new and refreshed solved problems

Chapter Organization This book consists of 18 chapters. These chapters present the features and syntax of C. A lucid explanation of the fundamental concepts of C is given which is very useful for beginners. Numerous programming examples on advanced data structures using C including linked lists, stacks, queues, sparse matrices, trees and graphs have been illustrated. A detailed coverage of file manipulation, searching and sorting has been presented. A special chapter on Unix has been provided to explain in depth the programming environment of C in the Unix operating system. Chapter 1 gives a brief introduction to the world of computers and programming. Chapter 2 discusses C fundamentals. It includes the use of upper and lower case alphabets, digits 0-9 and special characters like the blank, comma, semi-colon, etc. Identifiers are names of constants, variables and functions. Standard identifiers are those that have a predefined meaning. For example, int is a standard identifier which refers to the integer data type. The data types supported by C are simple data, string data, structured data and

xvi

Preface

pointer data. Simple data types include char, int, float, double and their variants. The structured data types comprise arrays and files. Constants are those quantities whose value remains constant throughout the execution of the program. These can be declared using the reserved word const. For example, the constant epsilon with a fixed value of 3.512 can be defined as follows: const float epsilon = 3.512; Variables are identifiers whose value can change in the course of execution of a program. Each variable has to be declared and the data type of the variable has to be specified. A typical variable declaration is shown below. int sum; Expressions are made up of operands and are connected by operators. Expressions are either numerical or boolean. Operands can be variables, constants or numbers. The value of an expression is obtained on its evaluation. A numerical expression has a numerical value whereas, a boolean expression has a truth value either true or false. Statements are the executable entities in a program. There are two types of statements, simple and structured. Simple statements include the assignment statement and function statement. Structured statements include the compound statement, repetitive statements and conditional statements. Chapter 3 deals with the input and output statements of C, i.e., scanf and printf. The scanf statement is used to accept input from the input device. printf is used to display output on the output device. getchar reads a character from the standard input device while putchar writes a character to the standard output device. Control structures are used to change the flow of control in a program. They are explained in Chapter 4. The three types of control statements are Conditional Control Transfer, Repetitive, and Unconditional Control Transfer. Conditional Control Transfer statements enable control transfer to different statements depending on a condition. The if-then, if-then-else and case statements belong to this category. Repetitive statements are used to execute a segment of a program repeatedly. This segment is called a loop. The loop can be executed a fixed number of times as in the for loop or a variable number of times till a condition is satisfied as in the while-do loops. The Unconditional Control Transfer statement is the goto statement. As the name suggests, the execution of the goto statement results in unconditional transfer of control to the target statement. Chapter 5 deals with functions, the concepts of user defined functions, library functions and recursive functions are illustrated here. Functions are subprograms used to segregate the different tasks of a program, thus making it easier to understand. The process of invoking a subprogram is referred to as calling. Functions may or may not return a value to the caller. Values are passed to the subprogram by means of arguments supplied in the call to it. The subprogram has parameters corresponding to the arguments. A copy of the argument is passed to the subprogram. An address of the argument is passed when the subprogram needs to alter it. The subprograms can also be called recursively. Chapter 6 illustrates the concepts and use of variables, its scope and extent. Scope is the region of source code in which the declaration of an identifier is recognized. Extent is the time during which a variable retains its state. Chapter 7 deals with arrays and strings. An array is a contiguous sequence of elements of the same data type stored in a linear order. It is a structured data type. The items of an array are called the array elements and every element has a unique index. Single-dimensional arrays are made up of a single list of elements and are called vectors. Two-dimensional arrays are organized into rows and columns and are called matrices. Arrays with three or more dimensions are called multi-dimensional arrays. A string is a collection of characters. The natural representation of a string is a vector of type char. Each character is an element of the vector. Chapter 8 explains the concepts of pointers. The various operations on pointers and the data structures constructed using them are discussed. A singly linked list is a linear data structure that is made up of nodes linked one after the other. Each node stores information and a link to the next node in the list. Chapter 9 explains the structured data type. It is composed of elements of different data types. A structure could contain structure. If so, it is said to contain a nested structure. Arrays of structures, structure pointers and the union data type are illustrated in this chapter.

Preface xvii

Chapter 10 deals with files and their manipulation. Files are data structures stored in secondary storage. Error handling in files are also discussed. Chapter 11 illustrates the concepts and library function of dynamic memory allocation, for self-referential structure. The efficiency of a program is limited by the data structures that are used to store the information required by it. The basic data types are used to create advanced data structures to enable effective storage of information. Some of these data structures are discussed in Chapter 12. The doubly linked list is similar to the singly linked list except that it has an additional pointer pointing to the previous element in the list. The circularly linked list is also like the singly linked list except that, the last element in the list is connected back to the first element in the list. The queue is a linear FIFO (First In First Out) structure where elements are inserted from one end and removed from the other. The element inserted first is taken out first. The stack is another linear data structure in which the data items are entered and removed in a LIFO (Last In First Out) manner. The entry and exit of elements are from the same end. In the linked list each element has one successor. If an element is allowed to have more than one successor, the data structure obtained is non-linear and is called a tree. In the binary tree, each node has a maximum of two successors. The general tree has any number of successor nodes. Chapter 13 explores the C language for programming in the UNIX operating system. File system and associated Unix commands are explained here. System calls for Inter Process Communication, Process Control are illustrated in this chapter. Library functions are listed in Chapter 14 while tips to structured programming is discussed in Chapter 15. Chapter 16 gives a quick references to C-keywords, type comm, L-values and R-values, storage class, Type specifies, limit.h and float.h, Input-output specifiers, preprogramming, Trigraph sequences and ASCII table. Solution to selected Exercises and programming examples are provided at the end of this book.

Acknowledgements We owe a debt of gratitude to Prof. K. Venkatagiri Gowda, Shri. M.C. Jayadeva, Prof. S. Lakshmana Reddy, Prof. N.R. Shetty, Prof. K. Mallikarjuna Chetty, Prof. H.N. Shivashankar, Prof. P. Sreenivasa Kumar, Prof. Kamala Krithivasan, Prof. C. Sivarama Murthy, Prof. T. Basavaraju, Prof. M. Channa Reddy, Prof. B. Narayanappa, Prof N.Srinivasan, Prof. M. Venkatachalappa, Prof. K.N. Krishnamurthy, for encouraging us to bring out this book in the present form. We sincerely thank Sri. K.P. Jayarama Reddy, T.G. Girikumar, P. Palani, M.G. Muniyappa, for their support in the preparation of this book. We thank Prof. N.R. Shetty, President, ISTE and Former Vice Chancellor, Bangalore University, Bangalore for his foreword to this book. We are grateful to Prof. G. Krishna, Prof. M. A.L. Thathachar, Prof. N. Viswanadham, Prof. D.K. Subramanian, Prof. L.M. Patnaik, from the Department of Computer Science and Automation, Indian Institute of Science, Bangalore for their suggestions and guidance in bringing out this book. We express our gratitude to Sri. K. Narahari, Sri. P. Ananda Rao, Sri. N. Nagabhusan, Sri. Prabhakar Bhat, Prof. K.V. Acharya, Sri. Khajampadi Subramanya Bhat, Sri. V. Nagaraj, Sri. Dinesh Kamath, Sri. D.M. Ravindra, Sri. Jagadesh Karanath, Sri. N. Thippeswamy, Sri. H.K. Mohan Kumar, Sri. Sudhir, Sri. V. Manjunath, Sri. N. Dinesh Hegde, Sri. Nagendra Prasad, Sri. Sripad, Sri. K. Thyagaraj, Smt. Savithri V, Smt. Karthyayini V and Smt. Rukmini T. our well wishers for inspiring us to write this book. We thank Prof. Rama Prasad, Mrs. Radha R. Prasad, Roopashree Sudeep, Veena R. Prasad, Surabhi Prasad and Sunidhi Prasad for their support and encouragement.. We thank Prof. P. Deepa Shenoy, Sri. K.B. Raja, Sri. T.R. Ramamohan, Sri. K. Suresh Babu, Sri. K.G. Srinivas, Smt. Vibha Lakshmikanatha, Smt. D.N. Sujatha, Sri. K. Girish, Smt. J. Triveni, Smt SuraiyyaTaranum, Smt S.H. Manjula, Sri. G.S. Badrinath, Sri. Chandrakant Naikodi, Sri. B. Aravinda, Radhika M.V., M. Vaidehi for their suggestions and support in bringing out this book. We are indebted to Tejaswi Venugopal, T. Shiva Prakash, T. Krishna Prasad and Lakshmi Priya K for their help.

xviii

Preface

We would like to thank the following reviewers for providing their valuable suggestions: Pragya Jain N K Kamila S Kannimuthu T V Gopal A Sharada

Indian Institute of Technology Delhi, New Delhi C V Raman College of Engineering, Bhubaneswar Sri Krishna College of Engineering and Technology, Coimbatore Anna University, Chennai G.Narayanamma Inst.of Tech & Science, Shaikpet, Hyderabad

The authors appreciate the suggestions from the readers and users of this book. Kindly communicate the errors if any to the following email address: [email protected]. K R VENUGOPAL SUDEEP R PRASAD

Publisher’s Note McGraw Hill Education (India) invites suggestions and comments from you, all of which can be sent to [email protected] (kindly mention the title, author name and the Book ISBN in the subject line). Piracy-related issues may also be reported.

1 INTRODUCTION

The ability of mankind to think is one of the factors that distinguishes it from other forms of life and has allowed mankind to expand its horizons. Man's limitations form the bedrock from which he innovates and discovers how to rise far above them. It was on one such voyage of discovery that Computing, and with it, Computer Science was found. Man is a creature who can understand and deduce relationships. Mundane, repetitive tasks, especially those of a mathematical nature, are tiresome to him. To circumvent this problem, an untiring and accurate computer was designed. The story of the development of computing is by itself a triumph of the human spirit. However, a computer by itself is not enough. It is also vitally important to be able to communicate with it. Programming is a process of writing instructions in a language that can be understood by the computer so that a desired task can be performed. The computer can understand only machine language and programming in machine language is tedious. High level languages which can be understood by programmers are available to simplify the job of programming. These languages are also machine independent. However, translators are required for these languages because programs written in high-level languages must be converted into the machine language of the computer before they can be executed. C is one such high level language and has become popular due to its proximity to the English language. Programs in C are easy to modify and are useful for teaching the art of structured programming.

one is said to be programmable because it can be instructed to perform tasks within its capacity. A list of instructions can be submitted to the computer in the form of a program. A task is performed by executing the corresponding program. A collection of related programs is referred to as the software. The physical circuitry and components are known as hardware Input Unit The input unit is the device used to enter data and instructions into the computer. The data mouse, joystick, touch pad, etc. Arithmetic Logic Unit (ALU) arithmetic operations include addition, subtraction, multiplication and division. Numerical data in the form of integers Logical operations include the Boolean functions such as AND, OR and NOT. These operations are used during conditional branching.

2

Mastering C CPU

CU

ALU

Input Unit

Main Memory

Output Unit

Secondary Storage

control

program instruction

data

3. Control Unit The control unit coordinates the activities of the various components of a computer. The arithmetic in Microprocessors Memory is constructed out of semi-conducting material and stores information in binary form. Binary information bits called a byte addresses. The memory of a computer can be divided into distinct parts as explained below. Registers processing. These internal high speed registers are used in arithmetic and logic operations for holding

Multi-level caches A cache is a small high speed memory that contains frequently used data. It is used to remove the bottleneck of accessing large, slow memory, while programs generally tend to access data in small regions at a time. There is a trade-off between latency and size – large memories usually have more latency, so they are slower. Hence, multi-level caches have a small, fast

is determined by the processor architecture. Main memory Main memory stores the data and instructions required by the microprocessor. The Random Access Memory access main memory locations. While main memory is fast, it is volatile; the contents stored will be lost when the power supply is cut off.

Introduction

3

Cost Registers L1 Cache

Registers Main Memory

L 2 Cache

Cache

Main Memory Secondary Memory (a)

Secondary Memory Speed (b)

Secondary Memory All the data and programs required by the computer cannot be stored in the main memory because it is small in size and volatile. Secondary memory is needed to store data which is not currently required by the microprocessor. Secondary memory is slower but less expensive than main memory. It is also non-volatile and larger in size. The microprocessor can access the various types access the secondary memory directly. Therefore, data from the secondary memory has to be brought to the main memory so that the processor can use it. Memory management techniques are required to transfer information between the main memory and secondary memory, and this function is performed

make it feasible to have them in large numbers. Similarly, secondary memory is the least expensive but is very slow. The hierarchy, therefore, achieves optimal performance at reasonable costs as the amount of memory of each type that is commonly used is proportional to the size of its rectangle in Output Unit Just as input devices are used to supply the computer with data, there should be some means for the computer to communicate with the user. The information generated by the computer is displayed using an output device such as a screen, a speaker or a printer.

The quest for computing aids to make our lives easier and work simpler, is not new. The abacus was invented Napier invented a device for computing logarithms of natural numbers. It was called Napier’s bones and enabled multiplication to be done easily. Blaise Pascal invented the adding machine Charles Babbage designed the difference engine analytical engine Herman Hollerith built a tabulating machine the birth of binary computers that could be programmed using punched paper tapes. Giant strides in digital computers were made during the second world war, where they were used to run programs that decrypted enemy

such as Pascal and C. Now, the advent of a huge variety of connected hardware like mobile handheld devices has application programmers using languages such as Java and scripting languages for web-based applications. Yet, the C remains the language of choice for system programming, as explained further in this chapter

Computer programs involve number crunching operations. A programmer need not know the details of how numbers are stored in the computer’s memory to write such programs. However, a good understanding of the

4

Mastering C

internal representation of data items within the computer is important. This knowledge helps in the development

the computer. These results could be explained if the internal representation of the number within a computer is known. In the decimal number system base or radix 0

and so on. The decimal system is not suited for representation of numbers in a computer because the computer is composed of switches that have only two states; on and off whereas the decimal system requires ten symbols or states. Hence the most suitable number system is the binary number system which has two symbols ‘0’ on and off states of semiconductor devices. Numbers can be converted from one representation to another easily. The decimal value of a binary number 3

=

+0

+

0

+

The above equation shows the weights of each bit being used to compute the decimal equivalent of a binary number. The conversion of a decimal number to a binary number involves repeated division of the decimal number

2 24

0

2 12

0

2 13

1

2 6

0

2 6

0

2 3

1

2 3

1

1

1

(24)10 = (11000)2 (a)

(13)10 = (1101)2 (b)

bottom to top The internal representation of an integer is exact. When the binary form of an integer is converted to the decimal form, the value is exactly equal to it. However, this need not be true with decimal fractions, also called A real number is converted to binary form by separately converting the whole part and the fractional parts of the number. The whole part of the number is converted as discussed above. The fractional part of a number subtracted from it and written alongside, otherwise 0 is written. This process is continued with the result until

Introduction

5

the remainder is zero. It is not possible to have an exact representation of some numbers. This is because the binary digits will keep recurring and zero will never be obtained. The binary form is obtained by reading the . Subtracted

Remainder

0.25 * 2 = 0.50

0

0.50

0.50 * 2 = 1.00

1

0.00

(0.25)10 = (0.01)2

Subtracted

Remainder

0

0.6

0.3 * 2 = 0.6 0.6 * 2 = 1.2

1

0.2

0.2 * 2 = 0.2

0

0.4

0.4 * 2 = 0.8

0

0.8

0.8 * 2 = 1.6

1

0.6

0.6 * 2 = 1.2

1

0.2

0.2 * 2 = 0.4

0

0.4

0.4 * 2 = 0.8

0

0.8

0.8 * 2 = 1.6

1

0.6

0.6 * 2 = 1.2

1

0.2



















(0.3)10 = (0.0100110011..)2

do not have an exact binary representation. Consequently, real numbers should not be used to index arrays and should not be compared for equality.

a variable x be assigned a value 0.3. The internal representation of 0.3 is shown in the previous section. x actually is, x = (0.01001100)2 x = 0 21 + 1 22 + 0 23 + 0 24 + 1 25 + 1 26 + 0 27 + 0 28

6

Mastering C

x = 0 + 0.25 + 0 + 0 + 0.0325 + 0.01625 + 0 + 0 x = (0.29875)10 If the comparison (x * 10) = 3.0 is done, we expect the answer to be true but the computer will evaluate x*10 to be 2.9875 which is not equal to 3.0.

used widely. The representation of any number within the computer is done by using an integral multiple of bytes sign, exponent and mantissa.

The exponent is positive for large numbers and negative for small numbers. To express signed exponents, the representation uses a special format called the excess format. Here, the smallest negative exponent is exponent values are biased bit numbers and the excess-1023 0

1

S Sign Bit 0 S Sign Bit

8

excess-127

9

31

EXPONENT

MANTISSA

8

23

1

11 12 EXPONENT 11

63 MANTISSA 52

The mantissa is always stored in the normalized

hidden bit which is not stored. The actual value

N = ( 1)S 1.M 2E 127 Zero is represented using an all-zero exponent all-zero mantissa denormalized form for extremely small numbers. Such numbers cannot be represented in the usual way because if they are normalized, their exponent values become so small that it cannot be represented in the exponent be 0. Very large values like that obtained after division by a value that is almost zero is represented by using the maximum exponent value possible and an all zero mantissa representation NaN is used. NaN implies Not a Number. if E = 255 and M 0 then N = NaN. if E = 255 and M = 0 then N = ( 1)S INFINITY if 0 < E < 255 then N = ( 1)S 2E 127 1.M if E = 0 and M 0 then N = ( 1)S 2E 126 0.M if E = 0 and M = 0 then N = ( 1)S 0

Introduction

7

System Software assists in the functioning of a computer system and includes the operating system, assembler, interpreter, compiler, linker and loader. The operating system is the interface between user applications and system hardware. The operating management, protection and security. The assembler is a translator that converts assembly language code into machine language. The interpreter converts source language instructions into executable code in a stepby-step manner. An instruction converted by the interpreter is executed and then the next instruction is taken up for processing. A compiler converts the source language program into executable code. The difference between a compiler and an interpreter is that the compiler converts the entire program at once whereas the interpreter does so in parts. The compiler output is either an assembly program to be run through the assembler or it is in the form of directly executable object code as an object module and then loaded for execution when needed, or it can be loaded directly for immediate execution. A linker performs the important task of linking together several object modules. The need for a linker arises when a particular program is made up of several object modules. The original source program may be in any as a single program. This task is performed by the linker. The linker has to resolve external references made by the processor. The task of loading the linked object modules is performed by the loader. There are two types of loaders Absolute loaders and Relocating loaders. Absolute loaders other hand, load the object code into memory locations which are decided at load time. The relocating loaders are preferred as they permit the executable to be loaded in any location in memory. However, they require additional information to be stored in the object module. This is obvious, since the information regarding the relative addresses of the memory locations being accessed in the module has to be stored within it. Compilers can compile into an ‘intermediate language’ to enable the program to be run on varying hardware. intermediate language, which is interpreted to run the program. This way, these instructions can be executed on various processors without needing to recompile the program. Hence, these languages are popular in the development of applications meant for mobile devices.

Software Engineering is a streamlined approach to the design and maintenance of computer programs using tools that help manage their size and complexity.

Problem statement The problem statement should be clear and unambiguous. If the statement is not precise and clear, the design and implementation will be erroneous. Problem analysis and design The problem is decomposed into smaller pieces to reduce the complexity the problem is developed based on the analysis. The algorithm may be expressed as a or in the form of pseudocode the relationship among the variables. 3. Analysis of the algorithm The algorithm should be analyzed to check if it performs the desired actions using a reasonable amount of time, and memory.

8

Mastering C

4. Coding This step involves coding the algorithm using an appropriate language to form a program. The choice of a programming language depends on several factors. Some of them are the availability of efficient translators, programming constructs required by the algorithm, portability constraints, proficiency of the programmer in the language, etc.  Note  Portability refers to the ease with which a program can be executed on a machine other than the one for which it was originally designed. 5. Documentation Documentation is essential to make the program easy to understand. It informs the reader about the working of the program, the mode of interaction and the purpose of variables used. A person who reads the program should be able to understand and modify the program using the documentation. 6. Testing The program should be tested thoroughly using all possible types of input. Testing detects inconsistencies (if any) in the program. 7. Maintenance The program may require changes depending on its application. The changes and updates required are performed during maintenance.

1.6 ALGORITHMS The word algorithm comes from the name of a Persian mathematician, Abu Ja’far Mohamed ibn Musa al Khowarizmi (825 A.D). The algorithm has come to refer to a method, that can be used by a computer for the solution of a problem. This makes the algorithm different from words such as process, technique or method.

Definition An algorithm is well defined, finite set of computational instructions that accomplishes a particular task, which may or may not take inputs and produces some value or a set of values as output. In addition all algorithms must satisfy the following criteria: (i) (ii) (iii) (iv) (v)

Zero or more quantities are externally supplied: Input At least one quantity is produced: Output Each instruction is clear and unambiguous: Definiteness The algorithm terminates after a finite number of steps: Finiteness For every input instance, it halts with the correct output: Correct

Criteria 1 and 2 require that an algorithm produce one or more outputs and take zero or more inputs that are externally supplied. According to criteria 3, each operation must be definite, i.e., there should not be any uncertainity in the instruction. The word finiteness means that the program should terminate after a finite number of operations and the time for termination should be reasonably short. Criteria 5 requires the instruction to be analyzed by a person using pen/pencil and paper in a finite amount of time: effective operation. Performing arithmetic operations on small numbers is an example of effective, but arithmetic on real numbers is not. One can view an algorithm as a tool for solving a well-specified problem. This problem specifies the desired relationship between input and output. The algorithm is described as a specific computational procedure, for achieving this input/output relationship.

1.7 ALGORITHM EXAMPLES The algorithm to compute the largest of three numbers is listed in Example 1.2 as follows.

 Example 1.2  Algorithm: Largest This algorithm computes the largest of three numbers. The variables used are: x, y, z : type integer big : storing the value of the largest number, type integer

Introduction

Step 1: Step 2:

Step 3:

9

[Input the three integers] read x, y, z [Compute the largest of three numbers] big = x; if (y > big) big = y if (z > big) big = z [Write the largest number] write (big)

Step 4: exit Algorithm: Quadratic Roots root1 and root2, of a quadratic equation ax + bx + c = 0, given the a equals 0, then a quadratic equation cannot be formed, so computation

a, b, c

a, b, c root1, root2

: :

type integer storing the value of the roots, type real

Step 1: read(a,b,c) Step 2:

[If a = 0, terminate computation] if(a = 0) then write ('Not a quadratic equation') exit endif

Step 3:

[Compute the discriminant] D b 2 4 a c

Step 4:

[Test for value of discriminant and compute the roots] if (D 0) then write('Roots are imaginary') repart b/(2 a) impart sqrt(abs(D)) / (2 a) write('root1=', repart, '+j', impart) write('root2=', repart, ' j', impart) exit else if D > 0 then write('roots are real and unequal') root1 ( b+sqrt(D))/(2 a) root1 ( b sqrt(D))/(2 a) write('root1=', root1) write('root2=', root2)

10

Mastering C

exit else write('roots are real and equal') root1 b/(2 a) write('root1=', root1) write('root2=', root1) endif Step 5: Exit

Flow of control Start or Stop

Input of output

Computation

Decision

Loop

Connection

Subroutine

Secondary storage

n n is the integer variable denoting the number of values considered for computing the average. Count is another integer variable denoting the number of values that are processed at any instant. The number is a integer variable for storing the values.

Introduction start False

If n < = 0 True sum = 0 count = 0

while count < n

read number

sum = sum + number count = count + 1

average = sum/n

write average

stop

Algorithm: Average This algorithm computes the average of n n, number, count integer sum integer Step 1: [Input the number of data items] read n Step 2: [Continue processing if n is positive] if n > 2

0000 0000 0000 0011

drop off 2*2=4. a

1 -3 to a a = -3; a

0000 0000 0000 0011 1111 1111 1111 1100 1111 1111 1111 1101 c = a >> 2; a c 1111 1111 1111 1111

1s

48

Mastering C

0000 0000 0000 0001 In the case of unsigned

0. Note

Bitwise complement operator

(~) i &

AND

i = i & 0xfff0;

i = (i >> 4) > n) & 1; printf( "The bit is %d", bit ); }

Variables and Expressions

The statement, bit = (i >> n) & 1; i n

49

i

>> has a greater precedence than &

>> operator is

>>

=

as +, -, *

=

+=

The statement a += 5 -=

/=

*=

|=

a.

a+= b-c

b-c

a. &= ^=

>>= j) (:)

j

Input two integers: 5 -1 The larger of the two is 5 ?



i>j)

i

j is -1. ?



(:)

i

i and j int i, j; i = (j = 3, j + 2); two the second is j+2 j

j=3 and 3 is assigned to

j+2

5 i

5.

The operator sizeof member selection operator

–>)

&

int a = 10, b = 15, c = 3, d; d = a + b * c; b c

d = (a + b) * c; a to b

a and the sum is assigned to d.

c and assign the product to d

d = a - b - c; b is subtracted from a. Then the second minus is c

52

Mastering C

associates d = a = c; c is assigned to a = c

a

a d,

comma operator

sum = (++a) - (--a); ++a and --a ++a

Category

sum

Operator () [] -> :: . ! ~ + ++ -& * sizeof

Member access Multiplication

Relational

Operation Function call

Precedence

Associativity LÆR

C indirect component selector C direct component selector RÆL

Address Indirection

.* ->*

LÆR

* / %

LÆR

+ -

LÆR

>

LÆR


=

Less than

LÆR

Contd.)

Variables and Expressions

Category

Operator == !=

Operation

Precedence

Associativity LÆR

&

LÆR

^

LÆR

|

LÆR

&&

LÆR

||

LÆR

Conditional

?:

RÆL

Assignment

= *= /= %= += –= &= ^= |= =

Comma

,

RÆL Assign product

Assign sum Assign difference

Assign left shift Assign right shift LÆR

/* interest.c: Calculation of simple interest and compound interest */ #include #include /* For the function pow */ void main() {

printf( "Principal: " ); scanf( "%f", &p ); printf( "Rate: " ); scanf( "%f", &r ); printf( "Time: " ); scanf( "%f", &t ); printf( "Compoundings per year: " ); scanf( "%f", &ncmp_year ); simple = p * t * r / 100; /* Calculate the amount resulting from compound interest. */ cmp_amount = p * pow( 1 + r/(ncmp_year*100), ncmp_year * t ); /* Compute the compound interest from the amount and principal */ compound = cmp_amount - p; printf( "The simple interest is: %f\n", simple ); printf( "The compound interest is: %f\n", compound ); }

53

54

Mastering C

Run: Principal: 1000 Rate: 10 Time: 2 Compoundings per year: 4 The simple interest is: 200.000000 The compound interest is: 218.402954 instead of pow

pow from the math.h

, since it uses the function ) operator. The function pow is used for

pow of the second, and returns

pow is called thus

pow( 1 + r/(ncmp_year*100), ncmp_year * t ) ncmp_year * t output that are passed to printf

p o w is 1 + r / ( n c m p _ y e a r * 1 0 0 ) . The second number is printf

/* temper. c: Conversion of centigrade to fahrenheit and vice-versa */ #include void main() { printf( "Enter temperature in celsius: " ); scanf( "%f", &c ); f = 1.8 * c + 32; printf( "Equivalent fahrenheit = %f\n", f ); printf( "\nEnter temperature in fahrenheit: " ); scanf( "%f", &f ); c = (f - 32) / 1.8; printf( "Equivalent celsius = %f\n", c ); } Run1: Enter temperature in celsius: 10 Equivalent fahrenheit = 50.000000 Run2: Enter temperature in fahrenheit: 50 Equivalent celcius = 10.000000

Variables and Expressions

/*deg2rad.c: Convert degrees to radians*/ #include void main( ) { printf(“Enter the degrees value ”); scanf(“%f”, °); rad=(deg*3.14)/180.00; printf(“\n%.2f degrees = %.2f radians”, deg,rad); } Run: Enter the degrees value 90 90.00 degrees = 1.57 radians

/*reverse.c: Read a positive number and reverse it*/ #include void main() { long n; printf(“Enter any number: ”); scanf(“%ld”,&n); if(n str2" ); A sample run is shown below: azcd abzzi str1 > str2 Again, note that the operators and strcmp.

cannot be used directly with strings. To compare strings, use

strcpy() The

function copies one string to another. The function accepts two strings as parameters and copies null character of the second string. As in the function strcat or equal to the second. For example the following code:

printf( "%s\n", str1 );

printf( "%s\n", str1 ); will output:

Arrays and Strings 215

The operator = cannot be used to assign one string to another. Use

for this purpose.

strlen() This function returns an integer which denotes the length of the string passed. The length of a string is the number of characters present in it, excluding the terminating null character. For example, printf( "%d\n", strlen(str) ); will output 5, since there are 5 characters in the string Hello. More on string library functions is given in the chapter on pointers.

grade.c: #include main() { int i,j,k,n,m;

printf ("Number of students ? scanf ("%d",&n);

");

{ printf ("\nEnter

3 scores of student-%d \n", i+1);

{ scanf ("%f",&a[i][j]); }

else } printf ("\n -------------------------------------------\n\n");

216

Mastering C

{ printf ("%d.",i+1); printf ("%8.2f",a[i][j]); printf ("\n"); printf ("\n -----------------------------------------\n\n"); } } Run: Number of students ? 5 Enter 3 scores of student-1 Enter

3 scores of student-2

Enter

3 scores of student-3

Enter

3 scores of student-4

Enter

3 scores of student-5

Sl.no

SCORES

1. 2. 3. 4. 5.

AVERAGE

83.33 55.57

B E A C

var.c: #include #include main() { int i,n;

printf ("Calculating standard deviation of a\n"); printf ("\nEnter size of the list :"); scanf ("%d",&n); printf ("\nEnter the %d items \n",n); { scanf ("%f",&x[i]);

Arrays and Strings 217

}

} Run: Calculating standard deviation of a Enter size of the list :7 Enter the 7 items

norm.c: #include #include main() { int i,j,m,n;

printf("Input row and column of A matrix:"); scanf("%d %d",&n,&m); printf("%d %d\n",n,m); printf("Input A-matrix\n");

scanf("%f",&a[i][j]);

{ int i,j;

218

Mastering C

} Run: Input row and column of A matrix: Input A-matrix

3 3

saddle.c: #include main() { printf (" Input the size of matrix:"); scanf ("%d %d",&n,&m); printf ("Enter the elements of the matrix \n");

scanf ("%d",&a[i][j]);

{

{ if(min > a[i][j]) {

} } {

Arrays and Strings 219

{

} }

else printf("No saddle point in row %d\n",i+1); } } Run: Input the size of matrix: 3 3 Enter the elements of the matrix 7 5 5 5 8 3 3

No saddle point in row 3

min-max.c: #include

void main() {

printf(“Enter ten numbers: ”); scanf(“%d”,&n[i]);

}

{ int i;

220

Mastering C

if(arr[i]>max) return(max); }

{ int i; if(arr[i] 12

-> 23

/* stacklink.c: implementation of stacks using linked lists */ #include struct list_element { int item; struct list_element *next; }; typedef struct list_element node; int menu() /* menu function */ { int choice; do { printf ("\n\nMain Menu: \n"); printf (" 1 - Push \n"); printf (" 2 - Pop \n");

428

Mastering C

printf (“ 3 - END \n”); printf (“Please enter your choice (1,2 or 3) scanf (“%d”,&choice); if (choice < 1 || choice > 3) printf (“\nInvalid choice - try again\n”);

:

”);

} while (choice < 1 || choice > 3 ); printf (“\n”); return (choice); } void display (node *record) /* display the linked list */ /* Argument points to the current node */ { if (record != NULL) { printf (“ -> %d ”,record->item); /* display the data item */ display (record->next); /* get the next data item */ } return; }

{ node *newrecord; /* pointer to new node */ int newitem; /* new data item */ printf ("New data item ? "); scanf ("%d",&newitem); /* allocate space for the new node */ newrecord = (node *) malloc(sizeof(node)); /* assign the new data item to newrecord->item */ newrecord->item = newitem; /* assign the current pointer to newrecord->next */ /*

new pointer becomes the beginning of the list */

} /*

delete one component from linked list return pointer to beginning of

{ node *temp; int target;

/* /*

printf (“STACK EMPTY \n”); else

temporary pointer */ data item to be deleted

*/

Data Structures 429

{

/* mark the node for deletion */ /*

free space of the target node */

printf ("\nSTACK after Popping : \n"); } } void main() { node *start; int key; int choice; start = NULL; do { choice = menu(); switch (choice) { case 1: /* Add one component */ start = push (start); printf ("\nSTACK after Pushing : \n"); display (start); continue; case 2: /* Delete one component */ start = pop (start); continue; default: /* Terminate computation */ printf ("End of computation \n"); } } while (choice != 3); } Run: Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) New data item ? 23 STACK after Pushing : -> 23

:

1

430

Mastering C

Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) New data item ? 12 STACK after Pushing : -> 12 -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) New data item ? 67 STACK after Pushing : -> 67 -> 12 -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) Element deleted is : 67 STACK after Popping : -> 12 -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) New data item ? 88 STACK after Pushing : -> 88 -> 12 -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) Element deleted is : 88 STACK after Popping : -> 12 -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) Element deleted is : 12

:

1

:

1

:

2

:

1

:

2

:

2

Data Structures 431

STACK after Popping : -> 23 Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) Element deleted is : 23 STACK after Popping : Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) STACK EMPTY Main Menu: 1 - Push 2 - Pop 3 - END Please enter your choice (1,2 or 3) End of computation

:

2

:

2

:

3

/* infix.c: #include #include void push( char stck[], int *sp, char ch ) { if (*sp == 100) else stck[++(*sp)] = ch; } char pop( char stck[], int *sp ) { if ((*sp) < 0) { return(0); } else return(stck[(*sp)—]); }

432

Mastering C

int alpha( char ch ) { return (((ch >= 'A') && (ch = 'a') && (ch = '0') && (ch 0) --sp; --bracket; break; break; default : if (alpha(last)||num(last)) { *error = 1; printerror(1,ifp+1); printerror(5,ifp+1); } if (alpha(ch)) else if (num(ch)) {

--ifp; } else printerror(4,ifp+1); } /* of switch */ ++ifp; i = ifp; } /* of do */

if (bracket) { *error = 1; printerror(3,ifp-1); } }

{ int i=0;

Data Structures 435

} void main() { int error,ans; error = 0;

if (!error) {

} } Run1: a+b ab+ Run2: a+b^(c+d)-e*f+g abcd+^+ef*-g+ Run3: ab^(-f(*g+/l Error_1_: Missing operator. Error_5_: Multiletter variable. Error_2_: Missing operand. Error_1_: Missing operator. Error_2_: Missing operand. Error_2_: Missing operand. Error_3_: Mismatched parentheses.

: : : : : : :

Column 2 Column 2 Column 5 Column 7 Column 8 Column 11 Column 12

436

Mastering C

front

rear

Four elements inserted

Empty queue Front = 1 Rear = 4

Front = 0 Rear = 0

(i)

20

18

56

(ii)

Two elements deleted Front = 3 Rear = 4

12

18

Two elements inserted Front = 3 Rear = 6

56

(iii)

18

56

88

(iv) All elements deleted Front = 0 Rear = 0

(v)

/* queuearray.c: program for implementing a queue using arrays */ #include #include #include

65

Data Structures 437

struct queue { int front,rear; int number; int arr[size]; }; /* Initializing the elements of a queue */ void initialise(struct queue* q) { q->front = 0; q->rear = -1; q->number = 0; } /* Declaring the functions as prototype */ int add_element(struct queue* q,int); int empty(struct queue* q); int full(struct queue* q); int remove_element(struct queue* q); void display(struct queue* q); /* Checking whether the queue is empty */ int empty(struct queue* q) { if(q->number==0) return true; return false; } /* Checking whether the queue is full */ int full(struct queue* q) { if(q->number == size) return true; return false; } /* Inserting an element into the queue */ int add_element(struct queue* q,int i) { if(full(q)) return false; if(q->rear == size - 1) q->rear = -1; q->arr[++q->rear] = i; q->number++; return true; } /* Removing an element from the queue */ int remove_element(struct queue* q)

438

Mastering C

{ int i; if(empty(q)) return -9999; i = q->arr[q->front++]; if(q->front == size) q->front = 0; q->number—; return i; } /* Displaying the elements of a queue */ void display(struct queue* q) { int i; if(empty(q)) { printf(“Queue is empty”); return; } printf(“\tThe elements of the queue are: ”); for(i = q->front;irear;i++) printf(“%d\t”,q->arr[i]); printf(“\n”); } /* Starting with the main() function */ void main() { int element,d; int choice; /* Allocating memory dynamically to queue type variable, q */ struct queue *q = (struct queue*)malloc(sizeof(struct queue)); initialise(q); while(1) { clrscr(); printf(“\n\t1. Insert an element: ”); printf(“\n\t2. Display all the elements of the queue”); printf(“\n\t3. Remove elements from queue”); printf(“\n\t4. Exit from the program”); printf(“\n\n\t Enter your choice: ”); scanf(“%d”,&choice); switch(choice) { case 1: { printf(“\tEnter an element to be inserted into the queue: ”); scanf(“%d”,&element);

Data Structures 439

add_element(q,element); break; } case 2: { display(q); getch(); break; } case 3: { if(!empty(q))/* Checking if the queue is not empty */ { d = remove_element(q); printf(“%d is removed from the queue\n”,d); getch(); } else { printf(“\tQueue is empty”); getch(); } break; } case 4: exit(0); default: printf(“\tReenter the choice”); getch(); break; } } } Run : 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 1 Enter the new element : 23 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 1

440

Mastering C

Enter the new element : 34 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 1 Enter the new element :45 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 3 23 is removed from Queue 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 3 Enter the new element : 34 is removed from Queue 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 1 Enter the new element : 45 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 2 The elements of the queue are 45 1. Insert an element: 2. Display all the elements of the queue 3. Remove elements from queue 4. Exit from the program Enter your choice: 4

Data Structures 441

front pointer

front pointer

start node (front pointer) 157

256 157

data fields

387 256

795 387

X 795

link fields

queue /* qlink.c: implementation of queue using linked list */ #include struct node { int info; struct node *next; }; void enqueue( struct node **front, struct node **rear, int i ) { struct node *new; new = (struct node *) malloc(sizeof(struct node)); new->next = NULL; new->info = i; if ((*front) == NULL) { (*front) = new; (*rear) = new; } else { (*rear)->next = new; (*rear) = new; }

442

Mastering C

} int del_queue( struct node **front ) { struct node *temp; int removed; if ((*front) != NULL) { temp = *front; (*front) = (*front)->next; removed = temp->info; free(temp); } return removed; } void display( struct node *front ) { printf("\nFront —> "); while (front != NULL) { printf("%d —> ",(*front).info); front = (*front).next; } printf("NULL\n"); } main() { struct node *front = NULL,*rear = NULL; do { printf("\n\nQueue operations : "); printf("\n 1) Insert"); printf("\n 2) Delete"); printf("\n 3) Quit\nEnter choice : "); scanf("%d",&choice); switch (choice) { case 1: printf("\nEnter the new element : "); scanf("%d",&choice); enqueue(&front,&rear,choice); break; case 2: if( front ) printf("The element removed is %d\n", del_queue(&front)); break;

Data Structures 443

case 3: } printf("\nThe queue is \n"); display(front); if (front == NULL) printf("\nThe queue is empty."); } printf("\n\n"); while (front != NULL) { rear = front->next; free(front); front = rear; } } Run: Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 1 Enter the new element : 23 The queue is Front —> 23 —> NULL Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 1 Enter the new element : 34 The queue is Front —> 23 —> 34 —> NULL Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 1 Enter the new element : 45 The queue is Front —> 23 —> 34 —> 45 —> Queue operations : 1) Insert 2) Delete 3) Quit

NULL

444

Mastering C

Enter choice : 2 The element removed is 23 The queue is Front —> 34 —> 45 —> Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 2 The element removed is 34 The queue is Front —> 45 —> NULL Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 2 The element removed is 45 The queue is Front —> NULL The queue is empty. Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 2 The queue is Front —> NULL The queue is empty. Queue operations : 1) Insert 2) Delete 3) Quit Enter choice : 3 The queue is Front —> NULL The queue is empty.

NULL

Front

21

84

73

74

Rear

Data Structures 445

rear

front

rear

front qu[0]

qu front

rear

/* cirqueue.c: program to implement a circular queue */ #include int qu[qsize]; int front,rear; void insert() { int item; if (rear == qsize) rear = 1; else rear++; if (front != rear) { printf("Enter item to be inserted\n"); scanf("%d",&item); qu[rear] = item; if (front == 0) front++; } else return; } int delete() { int item; if (front != 0) { item = qu[front]; if (front == rear) { front = rear = 0; return(item); } if (front == qsize) front = 1; else front++; return(item);

446

Mastering C

} else return; } void display() { int i; for (i=front; inext = 0; if( !que->front ) { que->front = new_node; } else { struct NODE *cur = que->front; while( cur->next ) cur = cur->next; cur->next = new_node; } } /* Function removes the node at the front of the queue pointed to by que. */ struct NODE* remove_node( struct QUEUE *que ) { struct NODE* removed_node = que->front; if( que->front ) que->front = que->front->next; return removed_node; } void priq_add( struct PRIQUE *priq, int priority, char data ) { struct NODE *new_node; if( priority >= priq->nqueues ) { printf( "Error: priority number given is invalid!\n" ); return; } new_node = (struct NODE*)malloc( sizeof( struct NODE ) ); new_node->data = data; add( priq->queues + priority, new_node ); } char priq_remove( struct PRIQUE *priq, int priority ) { struct NODE *removed; char removed_char; if( priority >= priq->nqueues ) { printf( "Error: priority number given is invalid!\n" ); return 0;

450

Mastering C

} removed = remove_node( (priq->queues) + priority ); if( !removed ) { if( priority < priq->nqueues - 1 ) return priq_remove( priq, priority + 1 ); else { /* Priority queue is empty */ return 0; } } else { char lower_elm; priq->queues[ priority ].nremovals++; if( priq->queues[ priority ].nremovals == priq->npromote ) { lower_elm = priq_remove( priq, priority + 1 ); if( lower_elm ) priq_add( priq, priority, lower_elm ); priq->queues[ priority ].nremovals = 0; } } removed_char = removed->data; free( removed ); return removed_char; } struct PRIQUE *create_priq( int nqueues, int npromote ) { struct PRIQUE *priq; priq = (struct PRIQUE*)calloc( sizeof( struct PRIQUE ), 1 ); priq->queues=(struct QUEUE*)calloc( sizeof( struct QUEUE ), nqueues ); priq->nqueues = nqueues; priq->npromote = npromote; return priq; } void cleanup( struct PRIQUE *priq ) { int i; for( i = 0; i < priq->nqueues; i++ ) { struct QUEUE *que = priq->queues + i; struct NODE *temp, *cur = que->front; while( cur )

Data Structures 451

{ temp = cur; cur = cur->next; free( temp ); } } free( priq->queues ); free( priq ); } int get_option() { int option = 1; do { printf( "1: Insert an element\n" ); printf( "2: Remove an element\n" ); printf( "3: Quit\n\n" ); printf( "Choose: " ); scanf( "%d", &option ); } while( option < 0 || option > 3 ); return option; } char get_data() { char data; printf( "Enter the data: " ); scanf( "%c", &data ); return data; } char get_priority() { int priority; printf( "Enter the priority: " ); scanf( "%d", &priority ); return priority; } void display_prique( struct PRIQUE *priq ) { int i; printf( "\nThe priority queue is...\n" ); for( i = 0; i < priq->nqueues; i++ ) { struct QUEUE *que = priq->queues + i; struct NODE *cur = que->front;

452

Mastering C

printf( "%d: ", i ); while( cur ) { printf( "%c", cur->data ); if( cur->next ) printf( "->" ); cur = cur->next; } printf( "\n" ); } printf( "\n" ); } void main() { struct PRIQUE *priq; char data; int nlevels, nremovals; int priority; printf( "No of priority levels: " ); scanf( "%d", &nlevels ); printf( "No of consecutive removals for priority promotion: " ); scanf( "%d", &nremovals ); priq = create_priq( nlevels, nremovals ); /*This loop is broken by the exit in the quit case.*/ while( 1 ) { switch( get_option() ) { case 1: data = get_data(); priority = get_priority(); priq_add( priq, priority, data ); break; case 2: priority = get_priority(); data = priq_remove( priq, priority ); printf( "%c was removed.\n", data ); break; case 3: cleanup( priq ); exit( 0 ); } display_prique( priq ); } } Run: No of priority levels: 4 No of consecutive removals for priority promotion: 3

Data Structures 453

1: Insert an element 2: Remove an element 3: Quit Choose: 1 Enter the data: q Enter the priority: 0 The priority queue is... 0: q 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 1 Enter the data: w Enter the priority: 0 The priority queue is... 0: q->w 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 1 Enter the data: e Enter the priority: 0 The priority queue is... 0: q->w->e 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 1 Enter the data: r Enter the priority: 0 The priority queue is... 0: q->w->e->r 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit

454

Mastering C

Choose: 1 Enter the data: z Enter the priority: 1 The priority queue is... 0: q->w->e->r 1: z 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 2 Enter the priority: 0 q was removed. The priority queue is... 0: w->e->r 1: z 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 2 Enter the priority: 0 w was removed. The priority queue is... 0: e->r 1: z 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 2 Enter the priority: 2 No elements to remove The priority queue is... 0: e->r 1: z 2: 3: 1: Insert an element 2: Remove an element 3: Quit

Data Structures 455

Choose: 2 Enter the priority: 0 e was removed. The priority queue is... 0: r->z 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 2 Enter the priority: 0 r was removed. The priority queue is... 0: z 1: 2: 3: 1: Insert an element 2: Remove an element 3: Quit Choose: 3

a

c

b

e

d

g

a

g h i e

j

h

i

f

j

456

Mastering C

Root Parent Child Siblings Ancestors Leaf Subtree Level Degree of a node Degree of tree Depth a

Root

Level 0

g

b

Parent (of c and d) Child(of b)

c

Sublings

h

d

e

f

j

Level 1

i

k

Level 2

Level 3

Leaf node

a a are b b are c

n

d e f j

g g are h e

k

n

i f

Data Structures 457 a

a

c

b

c

b

j

j

f

c

b

p

e

e

d

a

g

f

f

a

m m

l

e

d

l+1 d

d

b

d

i

c

j

d

d

k

d d

e

f

e

f

d b

i

n

n

n

n a b f

c b

f

458

Mastering C 0 a

2 c

1 b

g 4

3 f

7 h

j 9 10 k

8 i

e 6

5 d

13

12

11

a

b

c

f

g

d

e

h

i

j

k

0

1

2

3

4

5

6

7

8

9

10

∑ Pointer to left node: ∑ Pointer to right node: ∑ Variable of any data type:

Preorder

Postorder

Inorder

T ∑ ∑ ∑

node T left subtree T right subtree T

∑ ∑

left subtree node T

T T

l 14

l 11

12

13

14

Data Structures 459



right subtree

T

a

T ∑ ∑ ∑

left subtree T right subtree T node T

e

d

∑ ∑ ∑

abdhiecf jkg hidebjkfgca hdibeajfkcg

c

b

h

i

g

f

j

k

/* treeorder.c: program to sort a set of integers in ascending order,Inorder, Preorder and Postorder tree traversals */ #include /* structure of a tree node */ struct tree_element { int item; struct tree_element *left; struct tree_element *right; }; typedef struct tree_element node; /* Function to create a binary tree */ void create ( node *record, int n ) /* record points to the current node */ { /* Element, n is greater than current node element */ if (n > record->item) { /* If the right child of current node is empty, node with element n becomes it's right child */ if (record->right == NULL) { record->right = (node *) malloc(sizeof(node)); record = record->right; record->item = n; record->left = NULL; record->right = NULL; } else /* Else invoke function create with right child as current node */ create (record->right,n); }

460

Mastering C

/* Element, n is smaller than current node element */ else if (n < record->item) { /* If the left child of current node is empty, node with element n becomes it's left child */ if (record->left == NULL) { record->left = (node *) malloc(sizeof(node)); record = record->left; record->item = n; record->left = NULL; record->right = NULL; } else /* Else invoke function create with left child as current node create (record->left,n); } /* current node element is equal to element n */ else printf ("Number is a DUPLICATE \n"); return; } /* create */ /* Inorder traverse tree in order left-root-right recursively */ void inorder ( node *record ) /* record points to the current node */ { if (record != NULL) { inorder (record->left); printf("%d ",record->item); inorder (record->right); } return; } /* inorder */ /* Preorder tree traversal */ /* traverse tree in order root-left-right recursively */ void preorder ( node *record ) /* record points to the current node { if (record != NULL) { printf("%d ",record->item); preorder(record->left); preorder(record->right);

*/

*/

Data Structures 461

} return; } /* preorder */ /* Postorder tree traversal */ /* traverse tree in order left-right-root recursively */ void postorder ( node *record ) /* record points to the current node */ { if (record != NULL) { postorder(record->left); postorder(record->right); printf("%d ",record->item); } return; } /* postorder */ main() { node *tree; int num,choice; /* Functions invoked by main program */ void create(node*, int); void inorder(node*); void preorder(node*); void postorder(node*); /* Building a tree */ tree = (node *) malloc(sizeof(node)); printf ("Type numbers one per line \n"); printf ("Ctrl-d for EOF \n\n"); scanf ("%d",&num); printf ("%d\n",num); tree->item = num; tree->left = NULL; tree->right = NULL; while ((scanf ("%d",&num)) != EOF) { printf ("%d\n",num); create (tree,num); } do { printf ("\n\nTYPE OF TRAVERSAL ?\n”); printf ("1 - Inorder \n"); printf ("2 - Preorder \n"); printf ("3 - Postorder \n");

462

Mastering C

printf ("4 - STOP\n"); printf ("\nChoice [1-4] ?"); scanf ("%d",&choice); printf ("%d\n",choice); switch (choice) { case 1 :

case 2

:

case 3

:

printf ("\nINORDER taversal :\n"); inorder (tree); continue; printf ("\nPREORDER taversal :\n"); preorder (tree); continue; printf ("\nPOSTORDER taversal :\n"); postorder (tree); continue; printf ("BYE !\n");

default : } printf ("\n");

}

} while (choice != 4); /* main */

Run: Type numbers one per line Ctrl-d for EOF 4 1 10 9 3 6 4 Number is a DUPLICATE 8 5 2 TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?1 INORDER taversal : 1 2 3 4 5 6 8

9

10

Data Structures 463

TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?3 POSTORDER taversal : 2 3 1 5 8 6 9 10

4

TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?2 PREORDER taversal : 4 1 3 2 10 9 6

5

8

TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?4 BYE !

B

B

G

a

E

c

+

b

a

b

c

Expression : ((a + b) / c) * ((a E c) * b) Inorder traversal : a + b / c * a E c * b

464

Mastering C

a b c

ac b

/* bintree.c: program to construct a binary tree for a given arithmetic expression and evaluate the same */ # include # include # include

typedef struct node { int info; struct node *left, *right; }node; struct { char a[20]; int top; }s; node *root = NULL; char a[20],b[20]; node *maketree( int j ); void addnumber( node *p );

void eqvt(); void push( char j ); char pop(); char stop(); int empty(); int prcd( int op1, int op2 ); node *maketree( int j ) { node *q; q = (node *)malloc(sizeof(node)); q->right = NULL; q->left = NULL; q->info = j; return q; } /* recursive function to insert an void addnumber( node *p )

element into the tree

*/

Data Structures 465

{ if(p->right != NULL) addnumber(p->right); /* else if(!isdigit(p->info)) p->right = maketree(a[k]); /* addnumber(p->left);

search in the right subtree

if operand insert

/* search in the left subtree

else p->left = maketree(a[k]); return; } /* recursive function to evaluate the expression */ { char sym; if(isdigit(p->info)) return (p->info - '0'); opnd1 = eval(p->left); opnd2 = eval(p->right); sym = p->info; value = oper(sym,opnd1,opnd2); return value; } /* function to carry out

various operations

*/

{ switch(sym) { case '+' case '-' case '/' case '*' default

: : : : :

*/

return(op1+op2); return(op1-op2); return(op1/op2); return(op1*op2); printf("illegal operation \n"); exit(1);

} } void eqvt() { int j =0,i; char c; for(i=0;(c = b[i]) != '\0';++i) { if(isdigit(c))

*/

*/

466

Mastering C

a[j++] =c; else if(c == ' ' || c=='\t') continue; else { while(!empty() && prcd(stop(),c)) a[j++] = pop(); if(empty() || c!= ')') push(c); else c=pop(); } } while(!empty()) a[j++] = pop(); a[j] ='\0'; } void push( char j ) { s.a[++s.top] = j; return; } char pop() { return(s.a[s.top--]); } char stop() { return(s.a[s.top]); } int empty() { if(s.top == -1) return TRUE; return FALSE; } int prcd( int op1, int op2 ) /* precedence of operators { switch(op1) { case '+': case '-': if(op2 =='-' || op2=='+' || op2==')') return TRUE; return FALSE; case '*':

*/

Data Structures 467

case '/': if(op2 =='(') return FALSE; return TRUE; case '(': return FALSE; } } main() { node *maketree(); void addnumber(); s.top = -1; gets(b); k = strlen(a) -1; root = maketree(a[k]); --k; while(k >= 0) { addnumber(root); k--; } value = eval(root); printf(" \n the value is return;

/* initialize the root of the tree

/* add the expression into

:

the tree

*/

*/

%6f\n",value);

} Run 1: 2 + (3 * 2 ) / 6 the value is

:

3.000000

Run 2: 2 + 3 * 5 - 4 / 2 the value is :

x

data

15.000000

y x.data >

z y.data, z.data >= x.data

468

Mastering C

40 12 5 70 6 10 14 2 (a) Insert 40

Insert 12

Insert 5

Insert 70

Insert 6

40

40

40

40

40

(b) 12

12

12

12

70

70

(c) 5

5

5

(e)

(d)

6

(f) Insert 10

Insert 14

40

40

12

70

5

12

(g)

12

70

5

2

6

10

40

14

5

6

Insert 2

70

14

6

10

(h)

10

(i)

Data Structures 469

child sibling

a

a b

b

d

c

c f

e

g

h

i d

j

k

l

e

Child pointer g

Sibling pointer

f

(a)

h

j

i k l

(b)

order m

470

Mastering C

m

m

m

m

20

10

5

9

E

E

15

10

E

15

25

18

20

25

34

30

50

34

40

45

50

Red node

black height

Rotations

Black node

Recolorings

1 2

4

3

5

Data Structures 471

data structure can be maximized over a large number of operations if the locations of the data for previous requests were known. The search operation could be analyzed for its amortized time bound. Amortized time implies that the time per operation is averaged over a large number of operations, generally considering the worst case sequence. In splay trees, the information about the previous request is stored in an indirect manner. Every time a search is made, the data sought is brought to the root of the tree. The information about the previous search is preserved and the structure of the tree itself is changed to reflect the search. The splay tree uses the same structure as a binary search tree. When a node is accessed, it is moved to the top of the tree. If the node is accessed again, it can be reached with minimal searching. When a large number of operations are considered, the most frequently accessed nodes float to the top. With a different access pattern, other keys float to the top. The operation of bringing the required element to the root is accomplished by means of several splaying steps. The main aim is that during the tree re-structuring, the basic property of the binary search tree is maintained, i.e., to maintain the ordering of the nodes such that the inorder traversal of the tree gives the sorted order. Splaying is a process of bringing the desired node all the way to the root, where the movement is performed in a fixed, predefined way. The rules are as follows: Zig

a

b

1

5 Zag a

a

c

b

 Fig. 12.30  Zig and zag (Simple rotation)

1

1

5 7

b

c

d b

b

(a) Zig Zig (Contd.)

b

(b)

1

a

c

5

1

Zig

a

c

(a)

a c

5

b

Zig d

a

c

1

7

5

7

1

5

1. Zig: When the desired node is one level below the root and to its left, a single rotation (called zig) is performed as illustrated in Fig. 12.30(a). 2. Zag: When the desired node is one level below the root and to its right, a single-rotation like the zig but in the opposite direction is performed (Fig. 12.30(b)) 3. Zig-Zig: When the desired node is more than one level below the root it has a grandparent node in addition to the parent node. If the parent node is the left child of the grandparent and the desired node is also the left child of the parent, two rotations in the same direction are performed. This is called the Zig Zig and is shown in Fig. 12.31(a). 4. Zig-Zag: If the parent of the desired node is a left child and if the parent is a right child of its parent, two rotations are used - one in each direction to get the desired node to the top (as in Fig. 12.31(a)). 5. Zag-Zag: This splaying step is like the Zig Zig. It is applied when the desired node and the parent are right children. It is shown in Fig. 12.31(b).

5

c

d

472

Mastering C 5

7

Zag 7

a

Zag

5

b

1 b

a

1

c

1

7 d

c

d

5

d

c

a

b

(b) Zag Zag  Fig. 12.31  Two single rotation splaying steps  Note  A very important observation should be made at this point. A rotation in the clockwise direction has been called Zig and on in the anticlockwise direction has been called Zag. In Fig. 12.32(a), the desired node is moved up one level by using the anticlockwise rotation first. Then a clockwise rotation is used. It seems logical to call this splaying step a Zag-Zig rotation. But the step is named keeping in mind the fact that a node is usually splayed starting from the root. When performing top down splaying, the Zig step would be done first. That is why this step is called Zig Zag. 6. Zag-Zig: This step is illustrated in Fig. 12.32(b). It is used when the desired node is the left child of the parent and the parent is the right child of the grandparent. 5 d

7

Zag at

Zig at 1

7 a

1 b

1

5

d

5 b

a

7 c

7

5 d

c

c

a

b

(a) Zig Zag 5

7 a

7

d

1 b

5

Zig at

c

Zag at

1

5 1

a

5

b

a

7

c

(b) Zag Zig  Fig. 12.32  Double rotation splaying steps

d

7

b

c

d

Data Structures 473

15

19

10

25

12

5 7

6 (a) Original Tree 15 15

Zig Zag

7

Zig

19

10

19

7 5

15

5

25

12

25

10

5

19

10

6

7 12

6

25

12

6 (b) Series of steps to bring 7 to the root 25 7

7

Zag Zag

Zag 7

15

5

25

5

15

5 6

19

10

6

15 6

12

25

19

10

19

10

12 12 (c) Series of steps to bring 25 to the root

474

Mastering C

/* sortree.c: Program to sort a set of integers in ascending order */ /* Inorder, Preorder and Postorder tree traversals */ #include /* structure of a tree node */ struct tree_element { int item; struct tree_element *left; struct tree_element *right; }; typedef struct tree_element node; /* Function to create a binary tree */ void create ( node *record, int n ) /* record points to the current node */ { /* Element, n is greater than current node element */ if (n > record->item) { /* If the right child of current node is empty, node with element n becomes it’s right child */ if (record->right == NULL) { record->right = (node *) malloc(sizeof(node)); record = record->right; record->item = n; record->left = NULL; record->right = NULL; } else /* Else invoke function create with right child as current node */ create (record->right,n); } /* Element, n is smaller than current node element */ else if (n < record->item) { /* If the left child of current node is empty, node with element n becomes it’s left child */ if (record->left == NULL) { record->left = (node *) malloc(sizeof(node)); record = record->left; record->item = n;

Data Structures 475

record->left = NULL; record->right = NULL; } else /* Else invoke function create with left child as current node*/ create (record->left,n); } /* current node element is equal to element n */ else printf ("Number is a DUPLICATE \n"); return; } /* create */ /* Inorder tree traversal */ /* Traverse tree in order left-root-right recursively */ void inorder ( node *record ) /* record points to the current node */ { if (record != NULL) { inorder (record->left); printf("%d ",record->item); inorder (record->right); } return; } /* inorder */ /* Preorder traversal, traverse tree in order root-left-right recursively*/ void preorder ( node *record ) /* record points to the current node */ { if (record != NULL) { printf("%d ",record->item); preorder(record->left); preorder(record->right); } return; } /* preorder */ /*Postorder traversal,traverse tree in order left-right-root recursively */ void postorder ( node *record ) /* record points to the current node */ { if (record != NULL) { postorder(record->left); postorder(record->right); printf("%d ",record->item);

476

Mastering C

}

} return; /* postorder

*/

main() { node *tree; int num,choice; /* Functions invoked by main program */ void create(); void inorder(); void preorder(); void postorder(); /* Building a tree */ tree = (node *) malloc(sizeof(node)); printf ("Type numbers one per line \n"); printf ("Ctrl-d for EOF \n\n"); scanf ("%d",&num); tree->item = num; tree->left = NULL; tree->right = NULL; while ((scanf ("%d",&num)) != EOF) { create (tree,num); } do { printf ("\n\nTYPE OF TRAVERSAL ?\n”); printf ("1 - Inorder \n"); printf ("2 - Preorder \n"); printf ("3 - Postorder \n"); printf ("4 - STOP\n”); printf ("\nChoice [1-4] ?"); scanf ("%d",&choice); switch (choice) { case 1 : printf ("\nINORDER taversal :\n"); inorder (tree); continue; case 2 : printf ("\nPREORDER taversal :\n"); preorder (tree); continue; case 3 : printf ("\nPOSTORDER taversal :\n"); postorder (tree); continue; default : printf ("BYE !\n");

Data Structures 477

} printf ("\n");

}

} while (choice != 4); /* main */

Run: Type numbers one per line Ctrl-d for EOF 4 1 10 9 3 6 4 Number is a DUPLICATE 8 5 2 TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?1 INORDER taversal : 1 2 3 4 5 6 8

9

TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?3 POSTORDER taversal : 2 3 1 5 8 6 9 10 TYPE OF TRAVERSAL ? 1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?2 PREORDER taversal : 4 1 3 2 10 9 6 5 TYPE OF TRAVERSAL ?

10

4

8

478

Mastering C

1 - Inorder 2 - Preorder 3 - Postorder 4 - STOP Choice [1-4] ?4 BYE !

v e

v

e Graph G = (v, e)

p e8

e7 q

r

e6 e1

e3

e2

e4 t

s e5

V = (p, q, r, s, t) E = (e1, e2, e3, e4, e5, e6, e7, e8) e1 = (q, s) e2 = (r, t) e3 = (s, p) e4 = (t, p) e5 = (s, t) e6 = (r, q) e7 = (p, q) e8 = (p, r)

p q r s

t

Endpoints Adjacent vertices or neighbors Isolated vertices Degree of a vertex Closed edge

p q r s

t

p

v

v v

q

Data Structures 479

a

b

3

a 8

b

11 6

7 d

c

c

d

9

a

b

a

b

c

d

c

d

mxm

a

b

d

c a

b

c

d

1-D array containing vertices

a

b

c

d

a

0

1

0

1

b

0

0

0

1

c

1

0

0

0

d

0

0

1

0

2-D array containing matrix

m

480

Mastering C

4X4

struct graph { char v[max]; int ed[max][max]; } v

ed

Vertex list Edge list

Start

Vertex list

Edge list x

p p q q

x

r s t

x

r

(a)

s

x

t

x (b)

Data Structures 481

p

q

struct vertex { char info; struct vertex *nextptr; struct edge *edptr; }; struct edge { struct vertex *nodeptr; struct edge *nptr; };

n 0

n-1

Status ready waiting

v

a

processed

482

Mastering C a

a a a cdb

b

c

b b

d

cdf f

f

f cde

e

e e cd d d c c

c

abfedc

/* spandfs.c: program to form spanning tree using DFS # include

/* structure for the node in the adjacency list typedef struct node { int info; struct node *link; }node;

*/

*/

boolean values TRUE or FALSE depending on whether the node has been visited or not */ typedef struct table { int visit ; char data; node *nodeptr; }table; table *tab[SIZE]; /* function to create adjacency structure for the graph */

Data Structures 483

void create( int n ) { node *new, *temp; int i,j,item; printf("\n enter the elements of the matrix below\n"); for(i=0;ivisit = FALSE; tab[i]->data = 'A' + i; tab[i]->nodeptr = NULL; temp = NULL; for(j=0;jinfo =j; new->link = NULL; if (temp) temp->link = new; else tab[i]->nodeptr = new; temp = new; } } } } /* function for dfs */ void dfs_span( int u ) { node *cur; cur = tab[u]->nodeptr; while(cur) { if(tab[cur->info]->visit == FALSE) { /*Internally, everything is numbered from 0. but while displaying, we number the nodes from 1.*/ printf( "%d - %d\n", u + 1, cur->info + 1 ); tab[cur->info]->visit = TRUE; dfs_span(cur->info); } cur = cur->link;

484

Mastering C

} return; } main() { int n, start; printf("enter the number of nodes :"); scanf("%d",&n); create(n); printf( "Enter the starting node: " ); scanf( "%d", &start ); /*Internally, the nodes are numbered starting from 0.But we let the node, but it is actually node 0.*/ start--; tab[start]->visit = TRUE; printf( "\nThe dfs spanning tree is...\n" ); dfs_span(start); } Run: enter the number of nodes :5 enter the elements of the matrix below 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 1 1 0 1 0 0 1 1 0 Enter the starting node:2 The dfs spanning tree is... 2 - 1 1 - 3 3 - 4 4 - 5

Status is ready waiting

v

processed

v v

Data Structures 485 a

a b

c

a a a

d

a f

cdb c e

c dbe d d be b ef e f f

acdbef

/* spanbfs.c: # include

typedef struct node { int info; struct node *next; }node; typedef struct vertex { int visit; int no; int dist; node *link; } vertex; vertex *v[10]; node *rear = NULL, *front = NULL; int n; void create() {

b e f

486

Mastering C

int i,j,k; node *temp, *new; for(i=0;ivisit = FALSE; v[i]->no = i+1; v[i]->dist = 0; temp = NULL; for(j=0;jnext = NULL; if(temp == NULL) v[i]->link = new; else temp->next = new; temp = new; new->info = j+1; } } } } void qinsert( int num ) { node *temp; temp = (node *)malloc(sizeof(node)); temp->info = num; temp->next = NULL; if(rear == NULL) front = rear = temp; else { rear->next = temp; rear = temp; } return; } int qdelete() { node *temp; int k;

Data Structures 487

if(front == NULL) return -1; k = front->info; temp = front; front = front->next; free(temp); return k; }

of each structure visited.the search is carried out recursively. */ void bfs_span( int s ) { node *cur; int k; cur = v[s]->link; /*Iterate through all children of this node.*/ while(cur) { if(v[cur->info-1]->visit == FALSE) { printf( "%d - %d\n", s + 1, cur->info ); qinsert(cur->info); v[cur->info-1]->visit = TRUE; v[cur->info-1]->dist = v[s]->dist +1; } cur = cur->next; } s = qdelete(); if(s==-1) return; else bfs_span(s-1); } main() { int s; printf("\n enter scanf("%d",&n); printf("\n enter create(); printf("\n enter scanf("%d",&s); if( s < 1 || s >

the number of nodes :"); the adjacency matrix\n"); the start node: n )

");

488

Mastering C

{ printf("\n exit(1);

error : invalid source node \n");

} v[s-1]->visit = TRUE; printf( "\nThe bfs spanning tree is...\n" ); bfs_span(s-1); return; } Run: enter the number of nodes :5 enter the adjacency matrix 0 1 1 0 0 1 0 0 1 0 1 0 0 1 1 0 1 1 0 1 0 0 1 1 0 enter the start node:2 The bfs spanning tree is... 2 - 1 2 - 4 1 - 3 4 - 5

#include #include int main() { int i, arr[]; clrscr(); printf(“\n\tReading the elements of an array:\n”); for(i=0;is2[0]) that is e character, therefore it gives zero. But starting address of s2 is added by 4, which gives 4th character of evening string. - - - - - - - - 3.9 Error : Output of the program is Vidhana Soudha, 38745, Bangalore. Solution: The printf as: printf(“\n%s”,address); in printf, %d is taken as an escape sequence and not considered as part of string. As a result, garbage value is printed in place of %d. - - - - - - - - 3.10 Error : Extra parameter in call to gets. Solution: gets syntax does not allow for any format string. It should be gets(text) only. - - - - - - - - 3.11 Output: Yes,100 is a good score...OK Explanation: j is 100 so it results in logical TRUE, Parenthesis operator returns the last executed result so it returns Yes. Hence the result. - - - - - - - - -

Answers to Exercises 583

3.12 Output:

-1 ffff -256 ff00 Explanation: When variable m is left shifted by n bits it is multiplied by the result and will be m * 2n, Negative numbers are represented using 2 complement. - - - - - - - - 3.13 Output: 0 UVCE Explanation: (j=!j>8 && j j= ((!j)>8) && ( j ((!100)>8) && ( 100 ((!j)>8) && ( j ((0)>8) && ( 100 (0) && (0)). Hence the result. - - - - - - - - 3.14 Output:

1 -1 2 3 Explanation: Normally when printf prints negative value, it returns one greater than the positive value it prints. - - - - - - - - 3.15 Output: Let the user enter 30 then the system prints 1, after this task, the system waits for user to enter value, after entering value it displays “Null pointer Assignment”. Explanation: Usually scanf functions return the scanf(“%d”,&i) returns 1 and printf(“%d\ n”,scanf(“%d”,&i)) returns 2then the remaining expression becomes scanf(“%d”,2) which trends to NULL POINTER ASSIGNMENT. - - - - - - - - 3.16 Output: HI HELLO 6 Explanation: Here x will get 3 and printf (“HELLO\n”) will return 6 and it will not consider x value for printing. - - - - - - - - 3.17 Output: e.g., 0(i/p) 48(o/p)

Explanation: It will ask a character to enter and it will display corresponding character’s ASCII code. - - - - - - - - 3.18 Output: h3 Explanation: Here variable x is having 0 as its initial value and printf(“hi\b”) prints “hi” and 3 then pow(3,1)=>3 and “i”of “hi” is replaced by 3 therefore h3. - - - - - - - - 3.19 Output: 9i Explanation: Similarly in this case also the variable x is having 1 as its initial value and printf(“hi\r”) prints “hi” and returns 3 then pow(3,2)=>9 and “h” of “hi” is replaced by 9 therefore 9i. - - - - - - - - 3.20 Output: Prints nothing. Explanation: The compiler treats all semicolons as statements. Therefore no errors. - - - - - - - - 3.21 Output : PI = 3.140000 PI = 3.14 PI = 3 Explanation %f by default prints upto 6 precision., in second printf it is precision is limited to 2, in third printf precision is removed. Hence the output. - - - - - - - - 3.22 Output: Computer Computer Science! Explanation %s is 20. For each string 20 columns are set aside, and the strings are printed with blanks - - - - - - - - 3.23 Output: Computer Science Scienceer Explanation: The escape sequence ‘\n’, takes cursor to beginning of the next line. Escape sequence ‘\r’ so “Computer” gets overwritten with “Science” - - - - - - - - -

584

Mastering C

3.24 Output : ComScience Explanation : The escape sequence ‘\b’ stands for backspace, which takes the cursor to the previous character. So last 5 characters of Computer are removed. In second printf(), and “Science” is written. - - - - - - - - 3.25 Output: Computer Science Explanation: Escape sequence places the cursor to the next column which is a multiple of 5 inserting spaces. Hence the output. - - - - - - - - 3.26 Output: Enter a sentence Computer Science Computer Enter a sentence Computer Science Computer Science Explanation : The scanf() has a limitation that it can accept only one word and ignore whatever follows after function called gets(). It accepts whatever you type form the keyboard till the Enter key is hit. - - - - - - - - -

Chapter 4: Control Structures 4.1 Output: The user get the integer values from 1 to 10 on the output screen. Explanation: In the for loop, i++ statement increments the value of i by one and then the printf() function prints the incremented value of i. Solution: Replace f o r ( ; i < = 9 ; i + + ) with for(;i1 Then if (1) is true therefore y=0. - - - - - - - - 4.52 Output: FIRST FOURTH Explanation: In memory a’s value is stored little less than 0.7. - - - - - - - - 4.53 Output: Hello . . . Explanation: The ASCII value of A is less than a, therefore prints Hello… - - - - - - - - 4.54 Output: m and n are equal, m=12, n=12.500000 Explanation: Here m are n are never equal but in if(m=n) it takes the last element i.e., if(12.5) is true therefore this output prints. - - - - - - - - -

4.55 Output: Computer Science. University Visvesvaraya College of Engineering Explanation: Statements of default are executed and followed until break is encountered. Hence the output. - - - - - - - - 4.56 Output: Prints nothing Solution 4, and there is no default statements. - - - - - - - - 4.57 Output: What is the output of the program Explanation: switch can exist without case statements. - - - - - - - - 4.58 Solution: Statements out of case are not executed, but checked against syntax. - - - - - - - - 4.59 Output: 100 100 Solution : ternary operator returns the value. - - - - - - - - 4.60 Output: Computer Science Explanation: ternary operator returns the result. - - - - - - - - 4.61 Output: C++ Explanation: 0.7 is truncated to 0 before it is considered for comparison - - - - - - - - 4.62 Output: C Explanation: 0.7 is retained as typecasted to int. - - - - - - - - -

and not

4.63 Output: 0 121 0 1 -175 0 2 133 0 3 1235 0 4 3347 0 Explanation: Storage class of the array arr is automatic and Storage class of b[] is static. The default value of auto storage class variables any

Answers to Exercises 589

Solution class variables is 0. Hence the output - - - - - - - - 4.64 Output: No output Explanation: Observe for loop carefully. There is a semicolon at the end of it which implies that for loop is terminated, and braces after has no relation with the previous loop. Hence the output. - - - - - - - - 4.65 Output: 1.200000 16.000000 34.00000 4.500000 45.000000 Explanation

main function - - - - - - - - -

5.3 Error : message(); Declaration syntax error Solution: You do not need to type semicolon in the message() - - - - - - - - 5.4 Error : sqr = sqrvalue(&n); For any input output is same Solution: sqr = sqrvalue(n); - - - - - - - - 5.5 Error : return(k,l,m);

- - - - - - - - 4.66 Output: 16 15 14 13 12 Explanation: We can ignore dimension of the array at declaration if there are initialized simultaneously. - - - - - - - - 4.67 Output: Error message place in function main Explanation: The moment the compiler encounters (), it assumes a reference to a function, and arr is an array variable, array uses square braces and not parenthesis. Hence the error message. - - - - - - - - 4.68 Output: Error message: Lvalue required in function main Explanation: Since arr++ changes the address of the variable which is not permitted, C permits to change value in memory locations only. - - - - - - - - -

Chapter 5. Functions 5.1 Error : small(&a, &b); Too few parameters in call to function small Solution: small(a, b); - - - - - - - - 5.2 Error : int sub(int p, int r) return p - r; Expression syntax in function main

on the command prompt. Solution: int a; a = k+l+m; return(a); - - - - - - - - 5.6 Error : int add(int p, int r) { a = p + r; return(a); } add Solution: int add(int p, int r) { int a; a = p + r; return(a); } - - - - - - - - 5.7 Error : return(); Expression syntax in function add Solution: return a; - - - - - - - - 5.8 Error : Type mismatch in redeclaration of function mult Solution: int mult (int , int); - - - - - - - - -

590

Mastering C

5.9 Error : int fact(char); Type mismatch in redeclaration of function fact Solution: int fact(int); - - - - - - - - 5.10 Error : int fact (int k) { int i, factorial; if (k == 0) factorial = 1; factorial = fact(k-1)* k; return(factorial); } The output is not produced on the command prompt Solution: int fact (int k) { int i; if (k == 0) return 1; return fact(k-1) * k; } - - - - - - - - 5.11 Output: 10 - - - - - - - - 5.12 Output - - - - - - - - 5.13 Output: value is not 20 50 - - - - - - - - 5.14 Output: num2 10 num1 + 2 22 Explanation: num11 and num22 are local to swap function, so any changes on these variables are will not affect num1 and num2; - - - - - - - - 5.15 Output ‘here’ in function main Explanation: goto jumps within the scope of the function. - - - - - - - - 5.16 Output: Compiler error: Type mismatch in redeclaration of show.

Explanation: Default return type (i.e., int) is assumed of display, mismatch occurs since it is declared as void. Hence the error. The solutions are as follows: 1. declare void display() in main(). 3. declare extern void display () before the use of display(). - - - - - - - - 5.17 Output: Compiler error. Explanation: argv[1] & argv[2] are strings. They are passed to the function sum without converting it to integer values. Solution: sum(argv[1] – ‘0’ ,argv[2] – ‘0’); - - - - - - - - 5.18 Output: Size is 6 Explanation: Function name and the argument name can be the same. Firstly, the function ret_val() is called and then the expression is executed result is passed as argument. - - - - - - - - 5.19 Output: 2 Explanation: Arrays are passed to functions as pointers. So the argument is equivalent to char * array. The expression within the return becomes, sizeof(char *)/ sizeof(char). - - - - - - - - 5.20 Output: num1=8 num2=10 Explanation: This is one of the methods to swap two variables without using a third variable. - - - - - - - - 5.21 Output: 1 Explanation: x gives number of arguments given while invoking the command. - - - - - - - - 5.22 Output: error Explanation: Second argument data type is character array and variable name should be unique. Solution: char *x1[]. - - - - - - - - 5.23 Output: From Func uvce From Func uvce

Answers to Exercises 591

From Main Explanation: Data will not be printed from the main because it results in dangling pointer at p and returns value from f(); - - - - - - - - 5.24 Output: (feed i/p as 0) 12 0 48 Explanation: It is also similar to previous problem but it prints 12 and i/p’s ASCII value. - - - - - - - - 5.25 Output : x = 67 ,y = 67 Explanation: While calling fu(x,y), it sends x=67 and y=67(ASCII value of Y) to evaluate. Here x and y are in function fu(x,y) is integers by default. - - - - - - - - 5.26 Output: l = 3110 Explanation: From main() function fu(m,n) is called with m=50,n=60. In fu(m,n), y=m+n=>y=50+60=>y=110 z=m*n=>z=50*60=>z=3000 Then it returns 110, 3000, 3110 but it takes only the last element of the return statement. - - - - - - - - 5.27 Output: m = 4 Explanation: m=fu(m=fu(m=fu(m))); It is evaluat as follows : fu(m=1);=>m=2 fu(m=2);=>m=3 fu(m=3);=>m=4 --------5.28 Output: FIRST… SECOND… THIRD… Explanation: It executes all statements as normal execution. - - - - - - - - 5.29 Output: Error Solution: return statement cannot be used within conditional operators, because return cannot be used within return. - - - - - - - - -

5.30 Solution : Computer Computer Computer ... ... ... Explanation: There is no condition tag to stop the recursion. - - - - - - - - -

Chapter 6: Scope and Extent 6.1 Error : The variables, num1 and num2 are declared locally. Solution: The variables, num1 and num2 should be declared before using it - - - - - - - - 6.2 Error : The scope of the ‘sum’ variable is restricted to ‘main’ function only. Solution ‘sum’ in the ‘fun’ function locally or declare ‘sum’ globally. - - - - - - - - 6.3 Error : The scope of the variable, sqr is restricted to the inner block only. Solution: The variable, sqr, should be declared in the main block. - - - - - - - - 6.4 Error : The variable ‘b’ is declared in the inner block and is accessed in the outer block. Solution: Declare ‘b’ globally to remove the error. - - - - - - - - 6.5 Error : Every time the function ‘sum’ is called, the variable ‘add’ takes the 0 value. Solution: The value of the variable ‘add’ should be preserved and therefore, ‘add’ in the function ‘sum’ must be declared static, add = add * 10 + i. - - - - - - - - 6.6 Error : auto int i=0; Solution: The variable i in the function display() must be declared static. - - - - - - - - -

592

Mastering C

6.7 Error : long int a,b; Solution: The variables a and b in the inner block should be declared extern. - - - - - - - - 6.8 Error : extern int var; Solution: The keyword extern is not used when declaring a variable globally. The function that accesses the external variable uses the keyword extern to declare that variable external. - - - - - - - - 6.9 Error : extern int ext=10; Syntactical error. Correct syntax: extern int ext; ext=10;

incremented value is used because both refers to the same location. - - - - - - - - 6.16 Output: 0 0 0 Explanation: variable i is declared as static and it is decremented every time when main is invoked, Printf() is executed only after invoking main. - - - - - - - - 6.17 Output: 65524===100 65522===50 170 ===200 Explanation: Here we display the variable value with it’s address depending upon it’s scope. - - - - - - - - -

- - - - - - - - 6.10 Error : Solution: The scope of the register variable is local and not global. Remove the register keyword. - - - - - - - - -

6.18 Output: 91 Explanation: Here ::x takes global value of x. printf(“%d”,::x|x); =>printf(“%d”,90|1); =>91 - - - - - - - - -

6.11 Output: 10 - - - - - - - - -

6.19 Output:

6.12 Error : Redeclaration of variable Explanation: By default extern assumes the variable is of type int Solution: . This is the correct way of writing the previous program. - - - - - - - - 6.13 Output: 32767 Explanation: The value of num is decremented till it gets 32767 (by rotating the value). - - - - - - - - 6.14 Output: Compiler Error : ‘&’ on register variable Explanation: & (address of) operator cannot be applied on register variables. - - - - - - - - 6.15 Output: 121 Explanation: variable i is preincremented binary operator and is evaluated from left to right so

65524 65522 Explanation: Here we need to consider the scope of a variable i, because by changing the scope of variable, the storage location is changed. According to the scope - - - - - - - - 6.20 Output: 1 2 3 . . . . 99 100 1 2 3 . . . . 99 100 Explanation: Variables i and j, both act in local scope. - - - - - - - - -

Answers to Exercises 593

6.21 Output: f = 1.330000 g= 4.480000 Explanation: Normal execution. - - - - - - - - 6.22 Output: n = 3 m = 4 k = 5 Explanation: long is long int by default and short is int by default. - - - - - - - - 6.23 Output: i = 111 j = 222 k =333 i = 10 j = 20 k = 30 Explanation: First i,j,k in main() is executed and prints 10,20,30. After calling scope() the global value of i,j,k is printed. asdasd- - - - - - - - 6.24 Output : In main k and l are 11 22 Scope k and l are 111 222 In main k and l are 11 22 Explanation: Here auto and register variables act as local variables. It’s scope will be changed whenever the function is called unless reference is used. - - - - - - - - -

Chapter 7. Arrays and Strings 7.1 Error main() Solution: Arrays are declared using the square braces and by not using the round braces. (Correct Declaration is int arr[5];) Similarly to access the arrays, statements should be scanf(“%d”, &arr[i]); and printf(“%d\n”, arr[i]); - - - - - - - - 7.2 Errors: Constant expression required in function main. Size of array not known in function main Solution: We cannot initialize an array using a variable, i.e., the size of array should be known at the compile time. Declare the array as: int arr[5]; - - - - - - - - 7.3 Error : Size of array or structure not known in function. Solution: While declaring the 2-D array, it is necessary is optional. Here, declaration of array should be int dim[2][2]= {1,2,3,4}; - - - - - - - - -

7.4 Error : Program executes but the values displayed for the remaining array indices are garbage values. Solution: There is no bound checking in C. Loop should iterate from 0 to 4 only. - - - - - - - - 7.5 Error : Program compiles successfully but may give undesired values in the output. Solution: The valid indices are 0 to 49. - - - - - - - - 7.6 Output : No Solution: Strings are compared using the strcmp() function and by not using the “==” operator. - - - - - - - - 7.7 Error : Non-portable pointer assignment in function main Solution: Character constants are enclosed in single quotes and string constants are enclosed in double quotes. String constants act as a pointer to the actually string. Here, the line char ch=“a”; assigns the character variable ch to the address of a string constant. - - - - - - - - 7.8 Warning: Non portable pointer assignment in function main(). Solution: Declaration should be char str1[]= “Hello”; - - - - - - - - 7.9 Error : Invalid pointer addition in function main Solution: Error is in line: str3=str1+str2; We need to use the functions as: strcat(str1,str2); strcpy(str3,str1); - - - - - - - - 7.10 Error : Lvalue required in function main Solution: Use the strcpy function for assigning a string to another string: strcpy(str2,str1); - - - - - - - - 7.11 Output: 0 0 0 Explanation: When automatic variables are initialized partialy, remaining location are initialized to null; - - - - - - - - -

594

Mastering C

7.12 Output: Garbage Values Explanation: standard C does not show error, because it does not check the array boundary. - - - - - - - - 7.13 Output - - - - - - - - 7.14 Output: 2 5 5 Explanation sizeof, str1 is a character pointer so it gives you the size of the pointer variable. In second sizeof the variable str2 indicates the name of the array whose size is 5. The third sizeof is same as second one. - - - - - - - - 7.15 Output: UVCE 5 Explanation: Register variables are considered as integer data types. - - - - - - - - 7.16 Output: 8 Explanation: *arr and -*arr cancels out. The result is as simple as 5 + 3 = 8. - - - - - - - - 7.17 Output: Q - - - - - - - - 7.18 Output: Compiler error: Too many initializers Explanation: The array str is of size 4 but the string constant requires 5 bytes to get stored (including \0). - - - - - - - - 7.19 Output: Compiler error: Cannot increment a void pointer Explanation: Void pointers are generic pointers. No pointer arithmetic can be done on it. - - - - - - - - 7.20 Output:

11 5 11 10 Explanation: strlen searches for ‘\0’ as soon as it encounters ‘\0’ it stops counting. sizeof operator returns memory size of operand; - - - - - - - - -

7.21 Output: 6 6 3 Explanation: array variable always returns the base address [] does sum and indirection ( i.e *(base + index) ) and since + is commutative *(base + index ) is equal to *(index + base ) so a[4] is same as 4[a]. *a a gives base address, * returns the value at given address hence 3. - - - - - - - - 7.22 Output: garbage value Explanation: complier does not check array with its bounds, value at the computed location is displayed. - - - - - - - - 7.23 Output: 2 0 3 0 Explanation: When auto variables are partially initialized remaining variables will be initialized to zeros. - - - - - - - - 7.24 Output: 17 Explanation: Only integer values can be as array index, - - - - - - - - 7.25 Output: 789 987 Explanation: String are displayed until INTEGER zero of character ‘\0’( which is equal to integer zero ). - - - - - - - - -

7.26 Output: 1 Explanation: Here a, *a and a[0] is having same garbage value but **a, *a[0] and a[0][0] is having “H”. Therefore g is having TRUE value. - - - - - - - - 7.27 Output: we(i/p) weew(o/p) Explanation: The given program works as follows: i/p=> we x[0]=“w” and x[1]=“e” and j=2(string length) In for loop the string is extended like this x[2]=“e” and x[3]=“w”. Therefore the whole string becomes “weew”. - - - - - - - - -

Answers to Exercises 595

7.28 Output: HE G H I J Explanation: Here str is having “HE” and we get output as follows : printf(“%s\n”,str);=>HE printf(“%c\n”,*str-1);=>*str is having ASCII value of “H” i.e., 72 and *str-1=>72-1=>71 which is a ASCII value of “G”. Therefore “G” is printed. Similarly all others. - - - - - - - - 7.29 Output: IVVI Explanation: The while loop executes until n=0 and str will get IVVI. - - - - - - - - 7.30 Output: 1 Explanation: Here strcmp compares two strings. In this problem, both strings are not equal. Therefore output is 1. - - - - - - - - 7.31 Output: HILLO Explanation: strcat function concatenate two strings but \r puts “HI” at the front. - - - - - - - - 7.32 Output: 2 Explanation: Here (!0)|6|0xf)=>16 ((!0)|6|0xf)>=20?0x10:2=>2 - - - - - - - - 7.33 Output:2 Null pointer assignment Explanation: strcpy copies source to destination but there is no buffer to hold value. Therefore output is generated as 2 and Null pointer assignment. - - - - - - - - 7.34 Output : 1002 1011 Explanation: When base address is incremented it gives next location of arr, when its address is incremented it gives address of the next variable. - - - - - - - - 7.35 Output: 1008 1024 Explanation: Same as above. - - - - - - - - -

7.36 Output: Unequal Explanation: address of variables str1 and str2 are compared which are different. Hence the output. - - - - - - - - 7.37 Output: 12 2 - - - - - - - - 7.38 Output: Error message : Illegal use of pointer in function main Explanation: C permits addition and subtraction operations on pointers. Multiplication or division of a pointer is not allowed. Hence the error message - - - - - - - - 7.39 Output: 10 30 Explanation: a r r returns base address when indirected (*arr) gives value at its base address, i.e., 10, when arr is added with 19 it does pointer arithmetic operation and points location 20 of arr when indirected*(arr + 19) gives 20 which is added with the value at base address. Hence the result. - - - - - - - - 7.40 Output: 10 11 12 13 14 Explanation: &arr[4] gives the address of 5th location of array arr, when address is subtracted( location, So var var points to subsequent location of arr. Hence the output. - - - - - - - - 7.41 Output: Error Expression Syntax Explanation: Condition in for loop is given as [4], expression [x] expects x to be added with some address and indirected( i.e., y[x] = *(x + y) ). Compiler will not be able to indirect value at its 4 the location. - - - - - - - - 7.42 Output: 4 3 2 1 0 Explanation: ptr arr. Initially, arr gives is its base address, so ptr - arr gives 4 (i.e., 5th location - 1th location) using pointer arithmetic, in further iterations, location pointed by ptr reduces. Hence the result. - - - - - - - - -

596

Mastering C

7.43 Output : 1004 0 1016 1004 0 1016 1004 0 Explanation: arr gives its base address, indirecting var has address of locations of array variable arr. var gives its base address, indirecting(*var) the same gives base address of array arr, indirecting this result(*(arr)) gives the value at base location of arr array. - - - - - - - - 7.44 Output: 4004 4016 1 Explanation: arr[2] gives the base address of 3rd row array arr, arr[2][2] gives 3rd element of 3rd row of array arr. - - - - - - - - 7.45 Output: 4016 3 3 Explanation: ptr variable has been declared as an integer pointer with single dimension, So ptr treats arr as continous memory locations, hence indirecting ptr(i.e., ptr[2] and *(ptr + 2) ) gives value at 3rd location. Hence the output. - - - - - - - - 7.46 Output: 0 Explanation: Strings are always terminated with ‘\0’ which is an integer zero base address summed with number of characters in string refers to the last location which has ‘ \0’. Hence the output. - - - - - - - - 7.47 Output: VVVVVVVVVVVVVVVVV Explanation: As said earlier [x]y is equivalent to *(x+y), and addition is commutative x[y] and y[x] should give same result. Hence, through the for loop upper case V is stored in all the locations of the string arr ‘\0’ is stored to mark the end of the string. - - - - - - - - -

But in second printf() address of 10th location is taken and prints characters until ‘\0’ is encountered, %s is used. - - - - - - - - 7.50 Output: Dpnqvufs Explanation: str[i] return ascii value of the character stored at location i, which is incremented by 1 and stored back to the same location. So C becomes D, o becomes p, and so on. - - - - - - - - 7.51 Output: 13579 - - - - - - - - 7.52 Output: MadaM Explanation: Initially ptr is pointed to last element of MadaM (i.e., last but one location ), when indirected prints M, and subsequently prints the characters decrementing the location pointed by ptr. Hence the output. - - - - - - - - -

Chapter 8: Pointers 8.1 Explanation: In the code the user is using pointers to pass the argument to function. But in the function body, the user is comparing i and j, which refer to the addresses instead of values of the two integers. Solution: Replace if(*i==*j) instead of if(i==j). - - - - - - - - -

7.48 Output: VVVVV Explanation: In all 5 locations of str an integer, 86 is stored, ‘V’ is replaced by 86 (ascii value of V) before it is stored. Hence the output. - - - - - - - - -

8.2 Output: Multiplication of two numbers is:: 200 Addition of two numbers is:: 220 Explanation: The user is using pointer in the function “multiply()”, which change the value of i from 10 to 200. Solution: There are two solutions for the problem: 1. Pass the argument in the multiply function by using pass by value instead of pass by reference. 2. Interchange the positions of addition() and multiply() function. - - - - - - - - -

7.49 Output: C Computer Science Explanation printf() the address of 10th location returned and indirected which returns ‘C’.

8.3 Output: Some garbage value. Explanation: In the statement j=increment(&i);, expression is assigning the incremented value of i to j, however in printf

Answers to Exercises 597

statement, expression is printing the value of *j instead of j. Solution: Either replace *j=increment(&i) with j=increment(&i); or replace *j with j in the printf statement. - - - - - - - - 8.4 Error : “Not an allowed type in function main” Explanation: Typecast to the int datatype is not done before derefrencing the void pointer. Solution: Replace *((int *)a)+c with *a+c in the printf statement. - - - - - - - - -

8.9 Explanation: To print the value contained within 3-D array, three * are required. Solution: Replace *(*(*(x+1)+1)+0)) with *(*(x+1)+1)+0). - - - - - - - - 8.10 Errors: “Expression syntax in function main” and “Invalid indirection in function main”. Explanation: Syntax *arr+2[1] and (*(arr+2)+ [1]) are incorrect. Solution: You can replace arr[2][1] with *arr+2[1] and *(arr[1]+2) with (*(arr+1)+[2]) - - - - - - - - 8.11 Output: 5

8.5 Output: Some garbage value. Explanation: In the statement y=x[0];, the user assigning the base address of the array. Solution: Replace y=&x[0] instead of the y=x[0] or y = x. - - - - - - - - 8.6 Error : “Illegal use of pointer in function main”. Explanation: You cannot multiply a pointer with a constant value. Solution: You can perform addition instead of multiplication. - - - - - - - - 8.7 Error : “Invalid indirection in function main” Explanation: One extra * is used in the printf statement. Solution: Replace *(*(x+i)+j) instead of *(*(x[i])+j). Solution2: Replace *(x[i]+j) with *(*(x[i])+j). - - - - - - - - 8.8 Error : Must take address of memory location in function main Explanation: The syntax p=&(x+3)is incorrect. Because x+3 4th element in the array. Solution: Replace p=x+3 with the p=&(x+3) - - - - - - - - -

- - - - - - - - 8.12 Output: -128 - - - - - - - - 8.13 Output: while(*ptr) { *str=*ptr; ++ptr,++str; } *str=*ptr; - - - - - - - - 8.14 Output: Compiler Error Explanation: You should not initialize variables in declaration - - - - - - - - 8.15 Output: 111 222 333 344 Explanation: Let us consider the array and the two pointers with some address arr 0 1 2 3 4 100 102 104 106 108 p 100 102 104 106 108 1000 1002 1004 1006 1008

598

Mastering C

ptr 1000 2000 ptr++ value in ptr becomes 1002, Now ptr – p is (1002 – 1000) / (scaling factor) = 1,*ptr – arr = (102 – 100)/(scaling factor) = 1,**ptr = 1. Hence the output of the printf is 1, 1, 1. *ptr++ becomes 1004. Hence, the outputs for the ptr – p = 2, *ptr – arr = 2, **ptr = 2. *++ptr becomes 1004. Hence, the outputs for the ptr – p = 3, *ptr – arr = 3, **ptr = 3. ++*ptr increments ptr by the scaling factor. So the value in array p at location 1006 changes from 106 10 108. Hence, the outputs for ptr – p = 1006 – 1000 = 3, *ptr – arr = 108 – 100 = 4,**ptr = 4. - - - - - - - - 8.16 Output: UVCUVCollegeVCollegeCollege Explanation: Here we have only one pointer variable of type char, and we take input in the same pointer variable thus we keep overwriting shifting the pointer value by 1. Suppose the inputs are University, Visvesvaraya and College. input suppose the pointer starts at location 1000 then the input one is stored as University\0 When the second input is given the pointer is incremented as i value becomes 1, so the input is 1001. Visvesvaraya\0 1002 Colle ge\0

printf prints the values at the position ptr, ptr+1 and ptr+2 = UVC The second printf prints three strings starting from locations ptr, ptr+1, ptr+2 i.e., UVCollege, VCollege and College. - - - - - - - - 8.17 Output: 100 Explanation: variable have visibility inside block where it is declared. But the lifetime is lifetime of the function

so it lives upto the exit of function. Since the num1 is still allocated space, *num prints the value stored in num1. - - - - - - - - 8.18 Output: garbage value Explanation: ptr is pointing to out of the array range of single_d. - - - - - - - - 8.19 Output: VC Explanation: Since arr in func is local to itself func increment of points to ‘V’ there after incrementing to ‘C’ so VC will be printed. - - - - - - - - 8.20 Output: Compiler Error. We cannot apply indirection on type void*. Solution: *((int *)vod_ptr) - - - - - - - - 8.21 Output integers.

x is a pointer to array of - - - - - - - - -

8.22 Output: f_num = 20 s_num = 10 Explanation: This is one method of swapping two values without using third memory variable. Simple checking will help is understand this concept. - - - - - - - - 8.23 Output: bye Explanation: By the assignment ptr[0] = f_num; the address of the function f_num. Similarly, the other two array elements also get initialized with the addresses of the functions s_num and t_num. So calling t_num() results in printing “bye”. - - - - - - - - 8.24 Output: func is a ptr to a function which takes 2 parameters .(a) an integer variable. (b) a pointer to a function which returns void. The return type of the function is void. - - - - - - - - -

Answers to Exercises 599

8.25 Output: garbage-value 0 Explanation: The memory space allocated by malloc is uninitialized, whereas calloc returns the allocated memory space initialized to zeros. - - - - - - - - -

8.33 Output: Garbage values. Explanation: Both the functions suffer from the problem of dangling pointers because space for variables is allocated from stack space. - - - - - - - - -

8.26 Output: 16 16 16 Explanation: ptr1 and ptr2 both points to the same memory location num. So any changes through ptr1 and ptr2 ultimately affects only the value of num. - - - - - - - - -

8.34 Output: 200 200 200 - - - - - - - - -

8.27 Output: 2 1 Explanation: The integer value 257 can be represented in binary as, 00000001 00000001. The integer value 258 is stored in memory as: 00000001 00000010. - - - - - - - - -

8.28 Output: 0 Explanation: when ‘ptr’ reaches the end of the string, the value pointed by ‘str’ is ‘\0’, value of ‘str’ is less than that of ‘least’. So the value of ‘least’ - - - - - - - - 8.29 Output: No Explanation: Function arguments can only pass pointers to arrays. The numbers inside [] is for more readability. So there is no difference between the declarations. - - - - - - - - 8.30 Output and Explanation: When while statements are not executed, then *p is assigned NULL. Accessing may terminate the program. - - - - - - - - -

8.35 Output: 17 17 27 17 Explanation: bitwise operators returns either TRUE or FALSE so expression becomes a[a[1] – 10 ] -> a[14 - 10] -> a[4]. In second expression (*a + 2 ) -> (13+2) which is less than 17, logically FALSE is returned, Hence (*a ++U -> V. - - - - - - - - -

8.32 Output: Computer Science Explanation: Program gives the output correctly

8.41 Output: 70 Explanation: *a and -*a gets cancelled so only (85 - 15) will remain. Hence the result. - - - - - - - - -

data area and not allocated in stack space. - - - - - - - - -

600

Mastering C

8.42. Output: OK ! IT IS 1 Explanation: The !(++i[x]==—j[y])=>1 then printf(“OK ! IT IS %d”,!(++i[x]==—j[y])=> printf(“OK ! IT IS %d”,1) this returns TRUE value and it is negated. Therefore while(0) is executed. - - - - - - - - -

8.48 Output: hi Explanation - - - - - - - - -

8.43 Output: EQUAL !THIS IS TRUE Explanation: In this program we use 2 ternary operators for conditions. (Is expression TRUE/FALSE)? if expression TRUE: if expression FALSE First f>0?printf(“EQUAL !”):printf(“NOT EQUAL ! “) is executed and it evaluates expression is TRUE(because f=1). Therefore EQUAL is printed and returns integer value. In second ternary operation printf(“THIS IS TRUE”) is executed. - - - - - - - - -

8.50 Output: 1000001 Explanation: binary representation of 65 is 1000001 - - - - - - - - -

8.44 Output: 48 49 50 51 52 Explanation: It prints ASCII value of 01234. - - - - - - - - 8.45 Output: 2 Explanation: Here void main(); is a function declaration and void main(x) The v is void pointer and having 1 as it’s initial value. Pointers cannot be dereferenced without explicit casting. After pre increment of v, it reaches to 2. - - - - - - - - 8.46 Output: m=2 Explanation: The printf prints whatever the value of m. - - - - - - - - 8.47 Output: we(i/p) we 10 Explanation: gets() gets a string from stdin and puts() outputs a string to stdout and appends a new line character. On success, puts returns positive value. - - - - - - - - -

8.49 Output: *.* Explanation: it removes quotes and prints *.* - - - - - - - - -

8.51 Output : 11111 Explanation : (*a)=> a[0]=>1 *(&*a)=> a[0]=>1 a[a[0]*0]=> a[0]=>1 *a=>a[0]=>1 - - - - - - - - 8.52 Output : k = -5 l = 4 Explanation : Both call by reference and call by value is used. - - - - - - - - 8.53 Output : 1000 1000 1000 1000 Explanation: m=1000; n=address of m o=address of n p=address of o - - - - - - - - -

Chapter 9: Structures and Unions 9.1 Error : struct Department; Declaration syntax error Solution: struct Department - - - - - - - - 9.2 Error : class.roll_no= class.roll_no= printf(“\n%d”, printf(“\n%d”,

14; 20; class.roll_no); class.roll_no); class and illegal structure

operation Solution: #include void main()

Answers to Exercises 601

{ struct class { int roll_no; }stu1, stu2; clrscr(); stu1.roll_no= 14; stu2.roll_no= 20; printf(“\n%d”, stu1.roll_no); printf(“\n%d”, stu2.roll_no); getch(); } - - - - - - - - 9.3 Error : class1.strength = 60; printf(“\nThe ranking of school1 is: %d”, school1.rank); printf(“\nThe strength of class1 of school1 is: %d”, class1.strength); structure operation Solution: #include void main() { struct school { int rank; struct class { int strength; }class1; }school1; clrscr(); school1.rank = 1; school1.class1.strength = 60; printf(“\nThe ranking of school1 is: %d”, school1.rank); printf(“\nThe strength of class1 of school1 is: %d”, school1.class1. strength); getch(); } - - - - - - - - 9.4 Error: employee a = { 115, “ABC”, “XYZ” }; Solution: struct employee a = { 115, “ABC”, “XYZ” }; - - - - - - - - -

9.5 Error : } emprec[]; Size of structure or array not known Solution: } emprec[2]; - - - - - - - - 9.6 Error : time *p; p = &time1; Solution: struct time *p; p = &time1; - - - - - - - - 9.7 Error : p.year = 2005; p.month = 12; p.day = 12; printf(“\n%d:%d:%d”, p.year, p.month, p.day); Illegal structure operation Solution: p->year = 2005; p->month = 12; p->day = 12; printf(“\n%d:%d:%d”, p->year, p->month, p->day); or (*p).year = 2005; (*p).month = 12; (*p).day = 12; printf(“\n%d:%d:%d”, (*p).year, (*p). month, (*p).day); - - - - - - - - 9.8 Error : date1.YY = 2005; date1.MM = 12; date1.DD = 12; printf(“\nThe date is %d:%d:%d”, date1.YY, date1.MM, date1.DD); The output is 12:12:12 Solution: date1.YY = 2005; printf(“\nThe date is: %d”, date1.YY); date1.MM = 10;

602

Mastering C

printf(“:%d”, date1.MM); date1.DD = 12; printf(“:%d”, date1.DD); - - - - - - - - 9.9 Error : dept1 new; Solution: struct dept1 new; - - - - - - - - 9.10 Error : struct emp int emp_no; char emp_code[15]; struct emp abc = { 3212, “C-12” }; Declaration syntax error Solution: struct emp { int emp_no; char emp_code[15]; }; struct emp abc = { 3212, “C-12” }; - - - - - - - - 9.11 Output: Garbage values Explanation: Automatic variables are not initialized - - - - - - - - 9.12 Output: 8 Explanation: size of double is 8 which is more than struct x( int 2 + char 1); - - - - - - - - -

9.16 Output: Yes. Explanation: Pointer to any type is of same size - - - - - - - - 9.17 Output: Error Explanation: Forward references are not made for typedefs - - - - - - - - 9.18 Output: Yes Explanation: The typename type is known at the point of declaring the structure. - - - - - - - - 9.19 Output: No Explanation: There is no compilation errors bit not advisory because body of type is not known during declaration of variable. This is known as ‘incomplete types’. - - - - - - - - 9.20 Output: sizeof (void *) = 2 sizeof (int *) = 2 sizeof (double *) = 2 sizeof(struct anything *) = 2 Explanation: The pointer to any type is of same size. - - - - - - - - 9.21 Output: 0 0.0000000 Explanation: If you initialize one variable by a value in struct, then all other remaining variables are initialized by 0. - - - - - - - - 9.22 Yes

9.13 Output: 6 , 6 - - - - - - - - 9.14 Output Explanation time of declaration. Forward reference is not allowed in C in this case - - - - - - - - 9.15 Output: NO Explanation: Because structure declaration to be recursive without end. - - - - - - - - -

- - - - - - - - 9.23 Output: Error Solution: struct emp is mentioned in the prototype - - - - - - - - 9.24 Output: 8 Computer Explanation: The program allocates space of requested size for the structure variable p. However, the code did work. But it is compiler dependent. This is not advisable. - - - - - - - - -

Answers to Exercises 603

9.25 Output: 8, Computer Explanation: Memory is not completely given back memory given to p. - - - - - - - - 9.26 Output: Error Explanation: Structures cannot be compared using logical equal to, we have to compare member to member of structure variables. - - - - - - - - 9.27 Output: 7 Explanation: Gives the total memory occupied by the structure variables (char=1, int=2, longint = 4). - - - - - - - - 9.28 Output: size = 2 Explanation: Total number of bits is turning out to be more than 8 (11 to be precise) the size of the structure is being reported as 2 bytes. - - - - - - - - 9.29 Output: Error Solution: we cannot initialize second member of union. - - - - - - - - 9.30 Output: Error Explanation - - - - - - - - 9.31 Output: Error message : Lvalue required in function main Explanation: The error message is obtained because we have tried assigning string value to a variable instead of copying using strcpy(). - - - - - - - - 9.32 Output: Error message : Declaration syntax in function main Explanation: We should not initialize variables in structure( i.e., age = 25 name missing but still it is correct, error is xyz occurs two times. - - - - - - - - 9.33 Output: Bangalore Madras Delhi angalore elhi

Explanation: snd.city returns base address of string %s, address is pre incremented by ++, now second location address is returned to %s. Similarly ++snd.fst.str - - - - - - - - 9.34 Output: 2 4 - - - - - - - - 9.35 Output: 1292 4999 74676 Explanation: We get all garbage values because variable str is not initialized. - - - - - - - - 9.36 Output: ABC 16961 67 4407873 Explanation: var is a variable which has an unsigned long int ( a 4 byte number), an integer array num[2] and a character array ch[], and array ch[] is copied the string “ABC”. On displaying we get ABC as output var.num[0] union and var.num[1] to the next 2 byte. Since the ascii values of ‘A’ and ‘B’ are 65 and 66 2 bytes contain 65 and 66 in that order whose Binary equivalent is 0100 0010, and 0100 0001 respectively. Taken as an int, the number in var.num[0] is printed out using %u, the decimal equivalent of binary 0100 0010 0100 0001, 16961 is displayed. Similarly, while displaying var. num[1], it outputs 67, which is decimal equivalent of 0000 0000 0100 0011. Similarly displaying var xyz takes 0, 67, 66 and 65.as a whole, its decimal equivalent 4407873 is outputed. - - - - - - - - -

Chapter10: Files 10.1 Error : Non-portable pointer conversion in function main Solution: The error is in the statement f p t r = r is a string and not a character. Hence it should be “r”. - - - - - - - - 10.2 Error always displays 1 as the output. Solution: The fclose(fp) statement should be outside the while loop.

604

Mastering C

{ FILE *fptr; char str[30],str2[8]; clrscr();

fgetc loop terminates, when the character count is one only. - - - - - - - - -

“w+”);

10.3 Error : Non-portable pointer conversion Solution which is fp the fclose statement should be: fclose(fp); - - - - - - - - -

/*Read a string from user */ printf(“\n Enter a string:\n”); gets(str); /*write the string to existing fputs(str,fptr); fputs(“\n”,fptr);

10.4 Error : Extra parameter in call to fclose in function main Solution: fclose statements should be:

and prints it on screen*/

fclose(fout); - - - - - - - - -

are:\n”); fseek(fptr,0,0); while(fgets(str2,20,fptr)) puts(str2); getch(); fclose(fptr);

10.5 Error : Illegal structure operation in function main. Solution FILE *fptr; “r”); - - - - - - - - 10.6 Error : The program runs without any error. to be opened in a mode other than reading, such as “a” and “r”. Solution : - - - - - - - - 10.7 Error : The function will execute without any errors on screen. This is because after it

the character pointer at the beginning. For this you need to use the fseek function, as shown below: (Note: Alternatively, you can also use the rewind function as rewind(fptr);) Solution: #include #include main()

} - - - - - - - - 10.8 Error : Too few parameters in call to ‘fgets’ in function main Solution: Error is in line: while(fgets(str,fptr)!=NULL) The fgets function takes 3 parameters. Here size parameter is missing at the second place. The prototype of fgets is: char *fgets(char *s, int size, FILE *stream); So, the error can be removed by replacing the line with while(fgets(str,8,fptr)!=NULL). - - - - - - - - 10.9 Error and Solution: The program executes but the fopen function, you should use either the double backslashes or a single front slash, as shown:

“a+”);

Answers to Exercises 605

fptr=fopen(“c:/mydir/txtfile.txt”, “a+”); - - - - - - - - 10.10 Warning: Suspicious pointer conversion in function main. Solution: Errors are in the syntaxes of fread and fwrite functions. They should be: fwrite(&student,sizeof(student),1,fp) fread(&student,sizeof(student),1,fp - - - - - - - - 10.11 Output: Contents of xyz.c followed by an Explanation: The condition should be checked against NULL. It is checked against EOF. - - - - - - - - -

10.16 Output: No output Explanation: Though you will not get any message here, fclose closes only fp3. - - - - - - - - -

Chapter 11: Dynamic Memory Allocation 11.1 Error : int stu; Solution: The malloc function returns a pointer, therefore, stu must be a pointer variable. i.e., *stu - - - - - - - - -

10.12 Explanation: After reading 30 records, fread fails reading EOF. So it prints the last record again. After this condition fails , it comes out of while loop. - - - - - - - - -

11.2 Error : numbers=(int*)realloc(length*sizeof (int)); Solution: The realloc function takes two arguments. numbers=(int*)realloc(numbers, length*sizeof(int)); - - - - - - - - -

10.13 Output: No output Explanation: strcpy(char * dest,char *src) returns char * is taken as argument for fopen, so no error - - - - - - - - -

11.3 Error : matrix1=(int**)calloc(col,sizeof(col*)); Solution: matrix1=(int**)calloc(col,sizeof(int*)); - - - - - - - - -

10.14 Output: It’s the Computer Science world! It’s the Computer Science world! It’s the Computer Science world! It’s the Computer Science world! It’s the Computer Science world! . . . . . . Explanation: fgets() on failure returns NULL and not EOF so condition is always true, so control runs

11.4 Error : char names[4][]={“Peter”,“Pat”,“Sam”, “”}; Solution: names should be a pointer variable. while(ages[ctr+1] != 0) - - - - - - - - -

- - - - - - - - 10.15 Output: No Output Explanation: fp is not compared using logical equal, fp is assigned NULL using assignment operator, where condition expression becomes true, so execution exits. Hence control does not reach putch() so nothing is displayed on screen. - - - - - - - - -

11.5 Error : str1=(char *)malloc(j); Solution: str1=(char *)malloc(6); The size parameter of the malloc function is the number of bytes to be allocated to a variable and not the address. Strcpy(str1,“Hello”); Strcpy(str2,“World”); - - - - - - - - 11.6 Error : printf(“ %d”, *ptr); Correction: printf(“ %d”, *(ptr+i)); or printf(“ %d”, ptr[i]); ptr=(int*)calloc(total,sizeof(int)); - - - - - - - - -

606

Mastering C

11.7 Error : free(); And there is syntax error, but charter array should not be assigned. Solution: The function free must contain a parameter. free(string); strcpy(string,“Hello”); - - - - - - - - -

12.3 Error : printf(“\tarr[%d][%d]=%d”,&i,&j,&arr[i] [j]); The use of ampersand with the variables to be printed is incorrect. Solution: printf(“\tarr[%d][%d]=%d”,i,j,arr[i][j]); - - - - - - - - -

11.8 Error:

Chapter 13: Unix Operating System

Solution:

- - - - - - - - 11.9 Error: Solution:

- - - - - - - - 11.10 Error : char string; No Syntax Errors, but there is logical error. Solution: String should be a pointer variable. Remove statement after clrscr(); Strcpy(string,“This is C programming”); - - - - - - - - 11.11 Output: 100 -> 200 64 -> C8 144 -> 310 Explanation: 100 is considered as address of the variable in data segment, and it is a near address value. - - - - - - - - -

Chapter 12: Data Structures 12.1 Error : int i, arr[]; The size of the array is not assigned in the declaration statement. Solution: int i, arr[6]; - - - - - - - - 12.2 Error : scanf(“%d”,&str[i]); The format integer for the character variable ‘str’ is incorrect. Solution: scanf(“%c”,&str[i]); - - - - - - - - -

13.1 Error : The use of main( int argc, char *argv ) in line number 11 is incorrect. Solution: Use main( int argc, char *argv[] ) - - - - - - - - 13.2 Error : The use of print( argv[ 0 ] ); in line number 13 is incorrect. Solution: Use printUsage( argv[ 0 ] ); - - - - - - - - 13.3 Error : The use of mod = 0888; in line number 15 is incorrect. Solution: Use mod = 0777; - - - - - - - - 13.4 Error : The use of in line number 7 is incorrect. Solution: Use “-l”,0); - - - - - - - - 13.5 Error : The use of execl(“/bin/ls/”,“ls”,“-l”); in line number 8 is incorrect. Solution: Use execl(“/bin/ls/”,“ls”,“-l”,0); - - - - - - - - 13.6 Error : The use of fact(f) in line number 9 is incorrect. Solution: Use fact(int f) - - - - - - - - -

Answers to Exercises 607

13.7 Error : The use of fun(int c, int d)in line number 12 is incorrect. Solution: Use fun(int c, int *d) - - - - - - - - 13.8 Error : The use of system(ls); in line number is incorrect. Solution: Use system(“ls”); - - - - - - - - 13.9 Error : The use of const int DELAY1 const int DELAY2 #endif is incorrect. Solution: Use #endif const int DELAY1 const int DELAY2 - - -

= 100000; = 70000;

= 100000; = 70000; - - - - - -

13.10 Error : The use of printf( “\nusage: %s \n\n “); in line number 5 is incorrect. Solution: Use printf( “\nusage: %s \n\n,name”); - - - - - - - - -

Chapter 14: C Library Functions 14.1 Error : int j, c; printf(“\nEnter a letter: ”); scanf(“%d”, &c); The output is always zero Solution: char c; int j; printf(“\nEnter a letter: ”); scanf(“%c”, &c); - - - - - - - - 14.2 Error : f = fopen(data, “w”); main Solution: f = fopen(“data”, “w”); - - - - - - - - -

14.3 Error : text = getc(“data”,f); Wrong number of arguments in call of getc function Solution: text = getc(f); - - - - - - - - 14.4 Error : strcpy(string[30], “My First C program”); Complier displays conversion of integer to pointer Solution: strcpy(string, “My First C program”); - - - - - - - - 14.5 Error : s1 = (char) *malloc(7); s2 = (char) *malloc(6); Invalid indirection in function main Solution: s1 = (char *)malloc(7); s2 = (char *)malloc(6); strcpy(s1,“Program”); strcpy(s2,“ in C”); - - - - - - - - 14.6 Error : getc(s1); printf(“Enter the second string: ”); getc(s2); Pointer required on left side of -> in function main Solution: gets(s1); printf(“Enter the second string: ”); gets(s2); - - - - - - - - 14.7 Error : s2 = strrev(s1); Lvalue required in function main Solution: strcpy(s2, strrev(s1)); - - - - - - - - 14.8 Error : printf(“%c”, isupper(c)); The desired output is not produced. This program should display a non zero value if the character that you entered is an uppercase letter. Solution: printf(“%d”, isupper(c)); - - - - - - - - -

608

Mastering C

14.9 Error : puts(“\nThe entered string is:”, str); Extra parameter in call to puts Solution: puts(“\nThe entered string is:”); puts(str); - - - - - - - - 14.10 Error : x=strcmp(str1[],str2[]); Expression syntax error Solution: x=strcmp(str1,str2); - - - - - - - - 14.11 Output: Str length is 9 Explanation: strlen counts till it encounters \0. - - - - - - - - 14.12 Output: Line no 5: Error : Lvalue required, Cannot apply mod to Explanation: We cannot apply ++ on enumeration constants, Bit-wise operators and % operators cannot fmod() is used to compute - - - - - - - - 14.13 Output: sizeof(ptr) = 2, sizeof(*ptr) = 1, strlen(ptr) = 4 sizeof(xyz) = 5, strlen(xyz) = 4 Explanation: sizeof(ptr) => sizeof(char*) => 2 sizeof(*ptr) => sizeof(char) => 1 Similarly, sizeof(xyz) => size of the character array => 5 - - - - - - - - 14.14 Output:

4 4 4 4 1 1 2 5 Explanation: Strlen function counts number of characters until it encounters \0, but sizeof gives number of memory locations given to variable. - - - - - - - - 14.15 Output: 2 1 2 Explanation: “b” is treated as string so b is followed by ‘\0’, in sizeof(ch ), memory given is one byte, in sizeof(‘b’) ‘b’ is substituted by its ascii value 98 which requires two bytes to store integer value hence the output. - - - - - - - - -

14.16 Output: 2 2 2 2 10 Explanation: sizeof gives the bytes of memory space taken by its operand and i— — is cancelled with i++, i+2 is cancelled with i-2, hence the output. - - - - - - - - -

Chapter 16: Quick Reference 16.1 Output: 27 6 Explanation: output is compiler dependent. - - - - - - - - 16.2 Output: num1/num2=2 - - - - - - - - 16.3 Output: compilation error Explanation: inc(num++) is expanded as num++ ++. because num++ gives rvalue (num ++ ) ++ requires lvalue. - - - - - - - - 16.4 Output: TRUE Explanation: After processing by the preprocessor the code is as follows : main() { if(0) puts(“NULL”); else if(-1) puts(“TRUE”); else puts(“FALSE”); } - - - - - - - - 16.5 Output: 24 Explanation: The macro expands and evaluates to : num1+2*num2-1 => num1+(2*num2)-1 => 24 - - - - - - - - 16.6 Output Explanation: This is a simple example for conditional compilation. The variable var is not known to the compiler making the declaration int know = 0; - - - - - - - - -

Answers to Exercises 609

16.7 Output: 123 0 Explanation: If a variable is not known the preprocessor treats it to be equal to zero. - - - - - - - - -

16.15 Output: 50 2500 Explanation: Preprocessing is done before compiling so getch () is checked against inbuilt function, it is replaced by 50. Hence the result. - - - - - - - - -

16.8 Output: Length of the array is 30 Explanation: The size of integer array of 30 elements is 30 * sizeof(int). The expanded macro is sizeof(arrray)/sizeof(int) => 30 * sizeof(int) / sizeof(int) => 30. - - - - - - - - -

16.16 Output: HELLO IT CITY Explanation: Preprocessing is done before compiling so return is replaced by return; - - - - - - - - -

16.9 Output: Area of the circle is 78.50, Area of the circle is 19.625000 Explanation: Macros can take variables of any data type. - - - - - - - - -

16.17 Output: VERY GOOD Explanation: Here macro. Macros provide a mechanism for token replacement with or without a set of formal, function-line parameters. In this problem the main() is also a token string and it will be placed in place of the main. - - - - - - - - -

16.10 Explanation: #ifdef

macro evaluates to 1 #ifndef macro

evaluates to 1 if var zero .

#endif #ifndef VAR #endif - - - - - - - - 16.11 Output: Statements of the for loop will not be executed, as TRUE 0. - - - - - - - - 16.12 Output: error Explanation: ++ operator requires lvalue; - - - - - - - - 16.13 Output: 20 Explanation: In preprocessing phase compiler replaces all occurrences of const to int so compiler does not prompt error. - - - - - - - - 16.14 Output: HELLO Explanation: getch(i,j) is replaced by i##j -> ij, because ## is used to merge tokens. - - - - - - - - -

16.18 Output: ffff ffff -1 -1 Explanation: The typedef assigns the symbol name PUT and char GET x; PUT y; are becomes char x; char y; and char is having a range between -128 to +127. Therefore the 255 reaches to -1. The -1 is stored as FFFF in memory. - - - - - - - - 16.19 Output: HELLO1 HELLO2 Explanation: Here does not effect on the running of the program. Similarly #ifdef and #endif also not effected. - - - - - - - - 16.20 Output: HELLO HELLO HELLO HI Explanation: printf prints HELLO, then token replacement of HI with HELLO. Similarly, HI;HELLO. - - - - - - - - 16.21 Output: HELLO Explanation: printf(HI) prints HELLO - - - - - - - - -

610

Mastering C

16.22 Output: “CC”CC Explanation: printf(#HI##HI) - - - - - - - - 16.23 Output: something is better than nothing . . . Do you agree with me? Explanation: Here the two statements, #include PROGRAM becomes #include “conio.h” The window(c1,r1,c2,r2) function is in conio.h window according to those parameters and within this window the output will be printed. - - - - - - - - 16.24 Output: hi… Explanation: EXIT will be replaced by exit(0) and program will be terminated at that point. - - - - - - - - 16.25 Output: No output Explanation: The if(EXIT) terminates there itself, therefore further statements are not executed. - - - - - - - - 16.26 Output: digit Explanation: All operations performed as it is with substitution. ch is having ASCII value of 0 (48), therefore if ((ch GTE 65 AND ch LTE 90) OR (ch GTE 97 AND ch LTE 122)) becomes if ((ch >= 65 && ch = 97 && ch = 65 && c = 97 && c 9?5:9). Hence the output. - - - - - - - - 16.37 Solution: 2 3 4 Explanation: int in preprocessing statement is replaced by x, y ,z during preprocessing, so it does not prompt error. - - - - - - - - 16.38 Output: Computer Science - - - - - - - - 16.39 Output: string Explanation: #x string size is x. Hence the output. - - - - - - - - -

Solutions

18 SOLUTIONS

Solution 1 Note the for /* concat3.c: program to concatenate two strings */ #include #include void main() { char str1[ 80 ], str2[ 40 ]; int i1, i2; gets( str1 ); gets( str2 ); /* i1 is the index to str1 and i2 is the index to str2 */ i1 = strlen( str1 ); i2 = 0; for( i1 = strlen( str1 ), i2 = 0; str2[ i2 ]; i1++, i2++ ) str1[ i1 ] = str2[ i2 ]; str1[ i1 ] = 0; puts( "The concatenated string is..." ); puts( str1 ); } Run: UVCE , Bangalore The concatenated string is... UVCE, Bangalore

611

612

Mastering C

Solution 2 /* count2.c: count the number of vowels, consonants and space in a line */ #include #include #include /* Number of types of characters */

{ if( c == ' ' ) else if( isalpha( c ) ) { if( strchr( vowels, c ) ) else } return retval; } void main() { char input[ 80 ]; int len, i;

gets( input ); len = strlen( input ); for( i = 0; i < len; i++ ) { int index = get_type( input[ i ] ); counts[ index ]++; }

} Run:

Solutions 613

Solution 3 inmatrix /* sing.c: # include /* Function to read the given matrix */ { int i,j; for(i = 0; i < n; i++) for(j = 0; j < n; j++) }

{ int

k,m,i,j;

sum = a[0][0] * a[1][1] - a[0][1] * a[1][0]; else { for(k = 0; k < n; k++) for(m = 0; m < n; m++) b[k][m] = a[k][m]; for(k = 0; k < n; k++) for(m = n; m < (2*n-1); m++) b[k][m] = b[k][m-n]; for(j = 0; j < n; j++) { partial = 1; for(i = 0; i < n; i++) { partial = partial * b[i][i+j]; }

614

Mastering C

psum = psum + partial; } for(j = n-1; j < (2*n-1); j++) { partial = 1; for(i = 0; i < n; i++) { partial = partial * b[i][j-i]; } nsum = nsum + partial; } sum = psum - nsum; } /* End of else */ /* Check for singularity */ if(sum == 0) else } void main() { int

x;

inmatrix (A,x); singular (A,x);

/* function calls */

} Run1: Enter the elements of the matrix 1 2 4 6 7 8 9

Run2: Enter the elements of the matrix 12 78 90

Solutions 615

Solution 4

maxr /* matinvr.c: #include /* Read the given matrix */ { int i,j; for(i = 0 ; i < y; i++) for(j = 0 ; j < y ; j++) }

{ int i,j; for(i = 0 ; i < y ;i++) for(j = 0 ; j < y ; j++) { if(i == j) x[i][j] = 1; else x[i][j] = 0; } } /* Find maximum element */ { int i;

{ if(max < x[i][y]) max = x[i][y]; } { if(max == x[i][y]) break; }

616

Mastering C

return(i); } /* Interchange the elements */

{ int i,j; if(m != l) { {

}

temp = x[m][j]; x[m][j] = x[l][j]; x[l][j] = temp; temp = y[m][j]; y[m][j] = y[l][j]; y[l][j] = temp; } /* end if */ /* end function inter */

}

{ int i,j,k;

{ x[m][i]= x[m][i]/dia; y[m][i] = y[m][i]/dia; } { if(i != m) { dd = x[i][m]; { x[i][k] = x[i][k] - x[m][k]*dd; y[i][k] = y[i][k] - y[m][k]*dd; } } } }

Solutions 617

{ int i,j; for(i = 0 ; i < y ; i++) { for(j = 0 ; j < y ; j++)

} } void main() { int n,j,k;

reada(a,n); unity(b,n); for(j = 0 ; j < n ; j++) { k = maxr(a,j,n); inter(a,b,k,j,n); elim(a,b,n,j); } writea(b,n); } Run: enter the matrix elements -1 2 -2 4 7 0 -0.10

-0.06

0.11

0.14

0.09

0.04

Solution 5 /* orth.c: program to check whether a given matrix is orthogonal or not */

{

618

Mastering C

/* transpose the given matrix */ for(i = 0;i temp.weight) { edge[j] = edge[j-1]; j = j - 1; } edge[j] = temp; } } /* Initialise parent array */ initi( int parent[20], int v ) { int i; { parent[i] = 0; }

632

Mastering C

} /* Find minimum kruskal edges */ { int i,j; i = vertex1; j = vertex2; while(parent[i] > 0) { i = parent[i]; } while(parent[j] > 0) { j = parent[j]; } if (i != j) { parent[j] = i; } } void kruskal( struct edgerecord edge[20], int v ) { int edgessofar,edgeindex,i,j,parent[20]; edgessofar = 0; edgeindex = 0; do { edgeindex = edgeindex + 1; edgessofar = edgessofar + 1; i=edge[edgeindex].vertex1; j = edge[edgeindex].vertex2; } while(edgessofar < v); } main() { int i,parent[20],v,e;

e = readedges(edge); sortedges(edge,e); initi(parent,v); kruskal(edge,v); }

Solutions 633

Run1: Input number of vertices Enter value for p Enter vertex1,vertex2,weight 1 2 1 read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Edges =6 Kruskal's spanning tree edges 1 2 2 4 Run2: Input number of vertices 6 Enter value for p Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight 4 6 2 read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight

634

Mastering C

read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight 1 2 6 read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Enter vertex1,vertex2,weight read 9999 to stop Edges =10

4 6

Solution 13 /* queen.c: # include

int x[8]; /* function to specify the position occupied by a queen in the row such

int good( int row ) { int i; for(i=0;inext); } } return; } int {

large( node node int

*record )

*save = record; p = save->info;

{ save = save->next; if (save->info > p) p = save->info; } if(p != -999) return(p); } { int temp,num; temp = large; num = 0; while (temp != 0) { ++num; temp = temp/10; } return(num); } { int i,dig, temp = num; for (i=0; inext = r; top[dig] = r; } return; } node {

*link( int poc, node *record ) node *pr; int i; record = bot[poc]; for (i=poc+1; inext = bot[i]; else top[i] = pr; } return(record);

} node {

*radix( node

*record )

int lar,m,i,j,dig,poc; node *nex,*r,*prev; lar = large(record); if(lar == -999) return record; m = numdig(lar); for (j=1; jnext; update(dig,r); r = nex; } /* end of while */ if (r->info != -999) { dig = digit(r->info,j); update(dig,r); } poc = 0; poc++; record = link(poc,record); display(record); } return(record); } void main() { node *start;

create(start); start = radix(start); display(start); } Run: Enter the elements of the list Enter -999 to stop 12 67

-999

640

Mastering C

Number of digits of the number 67 is 2 1th digit of no. 12 is 2 1th digit of no. 67 is 7

2th digit of no. 12 is 1

2th digit of no. 67 is 6

Solution 15

x and y

x < y implies H(x) info == -9999) { return; } else {

/* create a node for next number */

create(record->next); } return; } /* displaying the linked list of numbers */ void display ( node *record ) { { if (record->info != -9999) { display (record->next); } } return; } /* function

returns the largest number in list */

{ node *save; int big; save = start; big = save->info; { if (save->info > big) big = save->info; save = save->next; } return (big); } /* Non-decreasing Hashing Function */ { int hash; hash = (int)((long)data*(m-1)/largest); return (hash);

642

Mastering C

} /* Address calculation sort function */ void addrcalsort ( int large, node *data ) { node *temp,*p,*s; int key; temp = data;

{ /* All the numbers are hashed */ temp->next = hashtable[key]; hashtable[key] = temp; } else { /* Hashing every number in the list */ p = hashtable[key]; if (p->info > temp->info) { hashtable[key] = temp; temp->next = p; p = hashtable[key]; } else p = p->next; s = p->next; p->next = temp; temp->next = s; } return; } /* Function merges the ordered sets after all numbers are hashed node *link ( node *tmp, int i ) { node *p, *start; int j; start = tmp; j = i+1; while (j < m) { {

*/

Solutions 643

p = hashtable[i]; p = p->next; p->next = hashtable[j]; i = j; } j = j+1; } return(start); } /* Function displays hashing table after all numbers are hashed void check( node *pass, int n ) {

{ pass = pass->next; } } void main() { node *start,*heady,*tmp,*pass; int i,n,lrg;

create (start); for (i = 0; i < m; i++)

if(lrg == -9999) exit(1); heady = start; /* Hashing all the numbers in the list */

{ if (heady->info != -9999) { pass->info = heady->info; addrcalsort (lrg,pass);

*/

644

Mastering C

} heady = heady->next; } for (n = 0; n < m; n++) { pass = hashtable[n]; check (pass,n); } i = 0; ++i; /* merge the hashed numbers */ tmp = hashtable[i]; start = link (tmp,i); display (start); } Run: 12

89 67 -9999 Number Number Number Number Number Number Number

? ? ? ? ? ? ?

---------------------------------------

Solutions 645

Hashtable Hashtable

1 2

| |

Hashtable

4

|

Hashtable Hashtable Hashtable

6 7 8

| | |

Hashtable Hashtable Hashtable

10 11 12

| | |

Hashtable

14

|

12

67

Solution 16

/* add.c: multiple precision addition on integers.*/ #include typedef signed char byte; struct one_dig { byte info; struct one_dig *next; }; struct number { struct one_dig *last_dig; byte sign; }; void get_number( struct number *no ) {

646

Mastering C

byte temp,dot_pressed; int count; struct one_dig *prev; count = 0; dot_pressed = 0; temp = getchar(); /* Negative number entered */ if (temp == '-') { no->sign = 1; temp = getchar(); } else no->sign = 0; if (temp == '+') { no->sign = 0; temp = getchar(); } while (temp == '0') temp = getchar(); { /* If character is a number */ /* Create a new node and store entered number in it */ temp -= '0'; prev = no->last_dig; no->last_dig->info = temp; no->last_dig->next = prev; ++count; temp = getchar(); } } void reverse( struct number *no ) /* Reverse the linked list for display */ { struct one_dig *current,*next,*prev; int total; current = no->last_dig; total = 0;

Solutions 647

{ next = current->next; current->next = prev; prev = current; current = next; ++total; } no->last_dig = prev; } void display_number( struct number *no ) { struct one_dig *current; int count; reverse(no); count = 0; current = no->last_dig; if (no->sign) putchar('-'); { putchar(current->info + '0'); current = current->next; ++count; } reverse(no); } void free_number( struct number *no ) /* Free the memory allocated to store a number */ { struct one_dig *next; { next = no->last_dig->next; free(no->last_dig); no->last_dig = next; } } void subtract ( struct number *num1,struct number *num2, struct number *res ) { int diff;

648

Mastering C

p1 = num1->last_dig; p2 = num2->last_dig;

numbers runs out of digits */ { new->info = p1->info + radixm1 - p2->info + carry; { carry = 1; } else carry = 0; p1 = p1->next; p2 = p2->next; *res_ptr = new; } /* If p1 still has digits */ { lim = 0; larger = p1; } /* If p2 still has digits */ { lim = 1; larger = p2; } /* larger points to the pointer pointing to the number still having digits left, transfer the digits from *larger to the result */ { if (lim) new->info = radixm1 - larger->info + carry; else new->info = larger->info + radixm1 + carry; {

Solutions 649

carry = 1; } else carry = 0; *res_ptr = new; larger = larger->next; } p1 = res->last_dig; if (carry) /* The result is positive and needs to be incremented */ do { lim = p1->info + 1; lim = 0; p1->info = lim; p1 = p1->next; } else complemented*/ { p1->info = radixm1 - p1->info; p1 = p1->next; } /* Adjust sign of result */ res->sign = !carry ^ num1->sign; } void add( struct number *num1, struct number *num2, struct number *res ) /* Add num1 to num2 and store the result in res */ { byte carry = 0; int diff; p1 = num1->last_dig; p2 = num2->last_dig;

{ new->info = p1->info + p2->info + carry;

650

Mastering C

{ carry = 1; } else carry = 0; p1 = p1->next; p2 = p2->next; *res_ptr = new; } larger = p1; larger = p2; /* larger points to the pointer pointing to the number having digits remaining */ /* Add carry to the remaining digits and append to the result list */ { new->info = larger->info + carry; { carry = 1; } else carry = 0; *res_ptr = new; larger = larger->next; } /* If there is a carry, even after both numbers have run out of digits, then create a new node for carry at the end of the result list */ if (carry) { new->info = 1; *res_ptr = new; } res->sign = num1->sign; }

Solutions 651

void main() { char choice,done; struct number n1,n2,res;

if( n1.sign == n2.sign ) else

} Run:

added to gives Enter the

added to gives

Enter added to -999999999999 gives

-999999999999

652

Mastering C

added to gives -66666666666666666666 -99999999999999999999 -66666666666666666666 added to -99999999999999999999 gives -6666666666666666666 777777777777 -6666666666666666666 added to 777777777777 gives

Solution 17 /* infinite.c: #include typedef signed char byte; struct one_dig { byte info; struct one_dig *next; }; struct number { struct one_dig *last_dig; int point_pos; byte sign; };

{ struct one_dig *release; { release = no->last_dig; no->last_dig = no->last_dig->next;

Solutions 653

free(release); --no->point_pos; } } void get_number( struct number *no ) { byte temp,dot_pressed; int count; struct one_dig *prev; count = 0; no->point_pos = 0; dot_pressed = 0; temp = getchar(); /* Negative number entered */ if (temp == '-') { no->sign = 1; temp = getchar(); } else no->sign = 0; if (temp == '+') { no->sign = 0; temp = getchar(); } while (temp == '0') temp = getchar(); { /* If character is a number */ if (temp != '.') { /* Create a new node and store entered number in it */ temp -= '0'; prev = no->last_dig; no->last_dig->info = temp; no->last_dig->next = prev; ++count; }

654

Mastering C

/* Character is a else { /* Record the dot_pressed = no->point_pos } temp = getchar();

decimal point */

position of the decimal point */ 1; = count;

} /* If the number has a decimal point */ if (dot_pressed) no->point_pos = count - no->point_pos; } void reverse( struct number *no ) /* Reverse the linked list for display */ { struct one_dig *current,*next,*prev; int total; current = no->last_dig; total = 0;

{ next = current->next; current->next = prev; prev = current; current = next; ++total; } no->last_dig = prev; no->point_pos = total - no->point_pos; } void display_number( struct number *no ) { struct one_dig *current; int count; reverse(no); count = 0; current = no->last_dig; if (no->sign) putchar('-'); if (!no->point_pos)

Solutions 655

putchar('0'); { if (count == no->point_pos) putchar('.'); putchar(current->info + '0'); current = current->next; ++count; } reverse(no); } void free_number( struct number *no ) /* Free the memory allocated to store a number */ { struct one_dig *next; { next = no->last_dig->next; free(no->last_dig); no->last_dig = next; } no->point_pos = 0; } void subtract ( struct number *num1,struct number *num2, struct number *res ) { int diff; struct one_dig *p1,*p2,**res_ptr,*new,**larger; p1 = num1->last_dig; p2 = num2->last_dig; diff = num1->point_pos - num2->point_pos; /*If diff is -ve,num1 has more digits after decimal point and vice versa*/ if (diff > 0) { lim = 0; /* p1, ie num1, has more digits after the decimal point */ res->point_pos = num1->point_pos; }

656

Mastering C

else { lim = 1; /* p2, ie num2, has more digits after the decimal point */ res->point_pos = num2->point_pos; } /* larger points to the pointer to the number having the larger number of digits after the decimal point */ /* lim = 1 indicates that the larger points to the minuend */ diff = abs(diff); /* Align the two numbers by transferring the extra digits after the decimal point to the result */ while (diff) { if (lim) new->info = radixm1 - (*larger)->info; else { new->info = (*larger)->info + radixm1; { carry = 1; } else carry = 0; } *res_ptr = new; *larger = (*larger)->next; --diff; } numbers runs out of digits */ { new->info = p1->info + radixm1 - p2->info + carry; { carry = 1; } else

Solutions 657

carry = 0; p1 = p1->next; p2 = p2->next; *res_ptr = new; } /* If p1 still has digits */ { lim = 0; *larger = p1; } /* If p2 still has digits */ { lim = 1; *larger = p2; } /* larger points to the pointer pointing to the number still having digits left */ /* Transfer the digits from **larger to the result */ { if (lim) new->info = radixm1 - (*larger)->info + carry; else new->info = (*larger)->info + radixm1 + carry; { carry = 1; } else carry = 0; *res_ptr = new; *larger = (*larger)->next; } p1 = res->last_dig; if (carry)

/* The result is positive and needs to be incremented */ do

658

Mastering C

{ lim = p1->info + 1; lim = 0; p1->info = lim; p1 = p1->next; } else complemented*/ { p1->info = radixm1 - p1->info; p1 = p1->next; } /* Adjust sign of result */ res->sign = !carry ^ num1->sign; } void add( struct number *num1, struct number *num2, struct number *res ) /* Add num1 to num2 and store the result in res */ { byte carry = 0; int diff; struct one_dig *p1,*p2,**res_ptr,*new,**larger; p1 = num1->last_dig; p2 = num2->last_dig; diff = num1->point_pos - num2->point_pos; if (diff > 0) { /*If diff is -ve,num1 has more digits after decimal point and vice versa*/ res->point_pos = num1->point_pos; } else { res->point_pos = num2->point_pos; } diff = abs(diff); result, thus aligning the two numbers about the decimal point */ while (diff)

Solutions 659

{ new->info = (*larger)->info; *res_ptr = new; *larger = (*larger)->next; --diff; } /* Add the corresponding digits of the two numbers while both the numbers have digits left */ { new->info = p1->info + p2->info + carry; { carry = 1; } else carry = 0; p1 = p1->next; p2 = p2->next; *res_ptr = new; } *larger = p1; *larger = p2; /* larger points to the pointer pointing to the number having digits remaining */ /* Add carry to the remaining digits and append to the result list */ { new->info = (*larger)->info + carry; { carry = 1; } else carry = 0; *res_ptr = new;

660

Mastering C

*larger = (*larger)->next; } /* If there is a carry, even after both numbers have run out of digits, then create a new node for carry at the end of the result list */ if (carry) { new->info = 1; *res_ptr = new; }

res->sign = num1->sign; } void multiply ( struct number *num1, struct number *num2, struct number *res ) { byte carry,temp; struct one_dig *mplier,*mcand,**result,**current; mplier = num2->last_dig; needs to be stored */

{ if (mplier->info) { mcand = num1->last_dig; carry = 0; { /* If there is no previous multiplication at this place */ { /* create a new node to store the result */ dig)); temp = 0; } /* There is already a node in this place */

Solutions 661

else /* add the result of the current multiplication to previous result in this place */ temp = (*result)->info; temp += mcand->info * mplier->info + carry;

mcand = mcand->next; } if (carry) /* If there is a carry at the end of a pass, create a new node for the carry */ { dig)); (*result)->info = carry; } } else { /* Create a new node at the end of the result list and store a result = current;

(*result)->info = 0; }

pass is to take place */ mplier = mplier->next; } /* Adjust decimal point and sign of the result */ res->point_pos = num1->point_pos + num2->point_pos; res->sign = (num1->sign != num2->sign); } void main() { char choice,done;

662

Mastering C

struct number n1,n2,res;

do {

do choice = getchar(); done = getchar(); {

switch (choice) {

if (n1.sign == n2.sign) else break;

if (n1.sign != n2.sign) else break;

} done = 0;

} else

Solutions 663

{ done = 1; }

} while (!done); } Run: a

added to gives

s

decremented by gives

m

multiplied by gives

q Quit

664

Mastering C

Solution 18 /* poly.c: polynomial addition */ #include /*function to read in the polynomials*/ { unsigned int temp=0; unsigned int expo=0; int i, exp, coeff; {

arr[exp]=coeff;

expo=0;

/*initially 0*/

temp|=expo;

/*corresponding exponent bit*/ /*Temp will represent the exponents of polynomial A*/

} return temp; } /* function to write the polynomials */ void prin( int arr[], unsigned int temp ) { unsigned int test=0; int j; do { /*is set to 1*/ if(test!=0) if(arr[j] m = (a -> m) h = false; for (i = (a->m)-1 ;

+ 1; /* increment m - the no. of elements */

{ /* provide space to insert new element a ->key[i] = a -> key[i-1]; a ->p[i+1] = a -> p[i];

*/

} /* insert element at the correct position */ a -> key[i] = u.num ; a -> p[i+1] = u.ptr; } else /*page a -> is full;split it and assign the emerging item to v */ { if (high key[n-1]; v1.ptr = a ->p[n]; for ( i = n ; i >= (high+2) ; i--) { /* provide space to insert new element */ a ->key[i-1] = a -> key[i-2]; a ->p[i] = a -> p[i-1]; } /* insert new element */ a -> key[high] = u.num; a -> p[high+1] = u.ptr; } for (i = 0 ; i < n ; i++) { /* add to new node, the elements of the split page */ b ->key[i] = a->key[i+n]; b ->p[i+1] = a->p[i+n+1]; } } else

Solutions 669

{ /* insert u in right page */ high = high - n-1; v1.num = a ->key[n]; v1.ptr = a ->p[n+1]; for ( i = 0; i key[i] = a-> key[i+n+1]; b->p[i+1] = a-> p[i+n+2]; } b -> key[high] = u.num; b -> p[high+1] = u.ptr; for (i = high+1; i< n ; i++) { b->key[i] = a-> key[i+n]; b -> p[i+1] = a -> p[i+n+1]; } } a -> m = n; b->m = n; /* pages a and b are half full */ b-> p[0] = v1.ptr; v1.ptr = b; } return (v1); } item {

search (int x, node *a)

otherwise insert an item with key x and count 1 in tree. If an item emerges to be passed to a lower level, then assign it to v; h = "tree a has to become higher " */ item u,v; int k,low,high ; node *q; int found,i; /* search key x on page pointed by a ; h =false */ {

/* element not found */ h = true; v.num = x;

} else { found = false;

670

Mastering C

{ if ( x == a -> key[i]) found = true; if ( found) h = false; else { high = i ; q = a ->p[high]; u = search (x,q); if ( h ) /* element found hence insert */ v = insert(a,u,high); }

}

} return(v); /* end of search;

}

*/

void printtree(node *p1,int l) { /* this routine prints the tree int i;

*/

{ for (i=1;i m ; i++)

for(i=0;i m ;i++) { printtree(p1 -> p[i],l+1); } } } /* end of printtree */ void del ( node *c, node *a,int k) { /* c is the son a is the ancestor */ node *q; int m1 = c->m; q = c -> p[m1]; { del (q,a,k);

} else { /* delete the element */ c -> p[m1] = a -> p[k+1]; a -> key[k] = c -> key[m1-1];

Solutions 671

a -> p[k+1] = c -> p[m1]; h = m1 < n; } c -> m = m1; }

node *b; int i,k,mb,mc; mc = c->m; /* h = true a->m = n-1 */ if (s < mc) { /* b= page to the right of a */ b = c->p[s+1]; mb = b->m; k = (mb - n +1) / 2; /* k is the no of items available on page p*/ a->key[n-1] = c->key[s]; a->p[n] = b->p[0]; if (k > 0) { /* move k items from b to a */ for (i = 1;i key[i+n] = b->key[i]; a->p[i+n+1] = b->p[i+1]; } c->key[s] = b->key[k-1]; c->p[s+1] = b; b->p[0] = b->p[k]; mb = mb - k; for (i = 0;i < mb;i++) { b->key[i] = b->key[i+k]; b->p[i+1] = b->p[i+k+1]; } b->m = mb; a->m = n-1+k; h = false; } else { /* merge pages a and b */ for (i = 0;i < n;i++) { a->key[i+n] = b->key[i]; a->p[i+n+1] = b->p[i+1]; }

672

Mastering C

for (i = s;i key[i] = c->p[i+1] = } a->m = nn; c->m = mc - 1; h = (c->m < n);

mc-1;i++) c->key[i+1]; c->p[i+2];

/*

dispose b

*/

} } else { /* b = page to the left of a */ b = c->p[s-1]; mb = (b->m); k = (mb - n + 1) / 2; if ( k > 0) { /* move k items from page b to a */ { a->key[i+k] = a->key[i]; a->p[i+k+1] = a->p[i+1]; } a->key[k-1] = c->key[s-1]; a->p[k] = a->p[0]; mb = mb - k; { a->key[i] = b->key[i+mb]; a->p[i+1] = b->p[i+mb+1]; } a->p[0] = b->p[mb]; c->key[s-1] = b->key[mb]; c->p[s] = a; b->m = mb; a->m = n - 1 + k; h = false; } else { /* merge pages a and b */ b-> key[mb] = c->key[s-1]; b->p[mb+1] = a->p[0]; for (i = 1;i key[i+mb] = a->key[i-1]; b->p[i+mb+1] = a->p[i]; }

Solutions 673

b->m = nn; c->m = mc - 1; h = (c->m) < n;

/*

dispose (a)

*/

} } } void del(int x,node *a) { /*this routine gives the position of the element to be deleted in the tree*/ int i,k,low,high; node *q; { h = false; } else { low = 0; high = (a->m) - 1; do { k = (low + high) / 2; if ( x key[k]) high = k - 1; if ( x >= a -> key[k]) low = k + 1; } while ( high >= low ); high++; high and low so as to maintain the difference */ q = a -> p[high]; if ((low - high) > 1) {

{ /* a is a terminal page a -> m = (a -> m) - 1;

*/

for ( i = k ; i < (a -> m) ; i++ ) { a -> key[i] = a -> key[i+1]; a -> p[i+1] = a -> p[i+2];

674

Mastering C

} } else { del(q,a,k); if ( h ) } } else { del(x,q); if ( h ) { } } } } int {

menu() int choice;

if ((choice == 1) || (choice == 2)) return choice; } int main() { int i; i = menu(); { switch(i) {

Solutions 675

printf("? "); while (x != 0) { u = search(x,root); if (h) { /* insert new base page */ q = root; root root root root

-> -> -> ->

m = 1; p[0] = q; key[0] = u.num; p[1] = u.ptr;

} printtree(root,1); printf("? "); } break; printf("? "); while (x != 0) { del(x,root); { if ( root -> m == 0 ) { q = root ; root = q -> p[0];/*dispose the node pointed by q */ } } printtree(root,1); printf("? "); } break; } i = menu(); } return 0; }

676

Mastering C

Run: ------------------------------------| | | -------------------------------------

------------------------------------1 please enter the key, ? 20 20 ? 40 20 40 ? 60 20 40 60

40

? 10 40

40

20

40

20

40

20

40

20

40

0 to end process

Solutions 677

? 0 ------------------------------------| | | -------------------------------------

------------------------------------2 please enter the key, 0 to end process ? 20 40

? 10

? 0 ------------------------------------| | | | | | -------------------------------------

-------------------------------------

678

Mastering C

Solution 20

p /* AVLtree.c: #include #include /* structure of a tree node */ struct tree_element { int info; int level; struct tree_element *left; struct tree_element *right; int bal; }; typedef struct tree_element node; void create( node *record, int n ) /* Argument points to the current node { int save; if (n > record->info) { { save = record->level; record = record->right; record->info = n;

record->level = ++save; record->bal = 0; } else create(record->right,n); } else if (n < record->info) {

*/

Solutions 679

{ save = record->level; record = record->left; record->info = n;

record->level = ++save; record->bal = 0; } else create(record->left,n); } else return; } /* Finding the height of each subtree */ int depth ( node *record, int i ) { { if (record->level > i) i = record->level; i = depth (record->right,i); i = depth (record->left,i); } return (i); } to insertion operation */ node *balance ( node *record ) { int i,l,r; /* Repeat until there are no more nodes in the tree */ { i l i r

= = = =

0; depth (record->left,i); 0; depth (record->right,i);

/* Node is a leaf */

680

Mastering C

record->bal = 0; /* Node has no left_child */ else if (l == 0) record->bal = record->level - r; /* Node has no right-child */ else if (r == 0) record->bal = l - record->level; /* Node has both children */ else record->bal = l-r; /* Check if the binary tree is height balanced */ if ((record->bal != 0) || (record->bal != 1) || (record->bal != -1)) { /* Binary tree entered is not height balanced */ return (record); } balance (record->right); balance (record->left); } return (record); } void traverse ( node *record ) /* Argument points to the current node { { traverse (record->left); traverse (record->right); } return; } node *leftrotation ( node *record ) { node *q,*hold; q = record->right; hold = q->left; q->left = record; record->right = hold; return (q) ; } /* Right Rotation */

*/

Solutions 681

node *rightrotation ( node *record ) { node *q,*hold; q = record->left; hold = q->right; q->right = record; record->left = hold; return (q); } node *maketree ( node *record, int info ) { node *p; p->info = info;

return (p); } node *insert ( node *record, int key ) { node *s,*p,*q,*fp,*fya,*ya; int imbal; p = record;

ya = p; /* ya points to the youngest ancestor which may become unbalanced */ /* fya points to the father of ya, and fp points to the father of p */ { if (key == p->info) return (record);

if (q->bal != 0) { fya = p; ya = q; } /* end if */ fp = p; p = q; } /* end while */ /* insert new node */ q = maketree (record,key); q->bal = 0;

682

Mastering C

if (key < fp->info) fp->left = q; else fp->right = q; /* the balance of all nodes between node(ya) and node(q) must be */ /* changed from 0 */ s = p; while (p != q) { if (key < p->info) { p->bal = 1; p = p->left; } else { p->bal = -1; p = p->right; } /* end if */ } /* end while */ /* Ascertain whether or not the tree is unbalanced, if it is, q is the newly inserted node, ya is its youngest unbalanced brother fya is the father of ya and s is the son of ya in the direction of imbalance */ /* another level has been added to the tree the tree remains balance */ if (ya->bal == 0) { ya->bal = imbal; return (record); } /* end if */ /* the added node has been placed in the opposite direction of the imbalance. The tree remains balanced */ if (ya->bal != imbal) { ya->bal = 0; return (record); } /* end if */ /* the additional node has unbalanced the tree, rebalance it by performing the required rotations and then adjust the balance of the node involved ya and s have been unbalanced in the same direction, ya= a, and s = b*/ if (s->bal == imbal) { p = s; if (imbal == 1)

Solutions 683

ya = rightrotation(ya); else ya = leftrotation(ya); ya->bal = 0; s->bal = 0; } /* ya and s are unbalanced in the opposite directions else { if (imbal == 1) { p = s->right; s = leftrotation (s); ya->left = p; ya = rightrotation (ya); } else { p = s->left; ya->right = p; s = rightrotation (s); ya = leftrotation (ya); } /* end if */

if (p->bal == 0) { /* p was inserted node */ ya->bal = 0; s->bal = 0; } else { if (p->bal == imbal) { ya->bal = -imbal; s->bal = 0; } else { ya->bal = 0; s->bal = imbal; } /* end if */ p->bal = 0; } /* end if */

*/

684

Mastering C

/*

adjust the pointer to the rotated subtree */ record = p;

else { if (ya == fya->right) fya->right = p; else fya->left = p; } return (record); } } void main() { node *tree; int num,key,choice; /* Building a tree */ do {

tree->info = num;

tree->bal = 0; tree->level = 0; { create(tree,num); } tree = balance (tree);

}

/* do while */

traverse(tree);

Solutions 685

if (choice == 1) {

tree = insert(tree,key);

traverse (tree); } } Run: Type numbers one per line

1 8 11 9 14 6

1 Key to be inserted 7

?

Type numbers one per line

7 2

0

1 Key to be inserted 1

?

686

Mastering C

Type numbers one per line 10 8 9 6

1 Key to be inserted

?

Type numbers one per line 10 8 12 6 9

1 Key to be inserted 14

?

Solutions 687

Type numbers one per line 10 8 7 6 9

0 1 2

2 1 1

10 8 7

2

0

9

1 Key to be inserted

2

1

1 Key to be inserted 2

0 2 0

?

0 1

7

?

2 7

688

Mastering C

APPENDIX

INTERVIEW QUESTIONS IT interviews aim at testing the aptitude and problem-solving skills of candidates with a certain amount of focus on the technical knowledge. In this appendix, we have compiled a series of questions commonly asked during IT interviews. Question 1: What is structured programming? Answer: Refer Section 1.11. Question 2: What is the difference between printf and fprintf? Answer: The printf function writes data to the standard output device while the fprintf function writes data to Question 3: What is the difference between structure and union? Answer: Refer Section 9.13. Question 4: Why is a break statement added at the end of each case sequence in a switch-case block? Answer: Refer Section 4.11 [Page 105]. Question 5: Which data structure is used by the system for processing a recursive function call? Answer: Stack. Question 6: What is the :: operator? Why is it used? Answer: Refer Section 6.2.1 [Page 181]. Question 7: What are the different storage classes in C? Answer: Refer Section 6.3. Question 8: What is a void pointer? In which situations is it used? Answer: Refer Section 8.6. Question 9: What is a pointer to pointer? Answer: Refer Section 8.8. Question 10: What is a self-referential structure? Answer: Self-referential structures are those structures that contain a member pointing to the same structure type. For example, struct node { int info; struct node *next; }; For more details, refer Section 11.4.

Appendix 689

Question 11: What is the difference between malloc and calloc? Answer: Refer Section 11.2. Question 12: What is the difference between while and do-while loop? Answer: Refer Section 4.8, 4.9. Question 13: What is a NULL pointer? Answer: A NULL pointer is assigned the NULL value to indicate the pointer does not point to any valid object. Question 14: What is a wild pointer? Answer: A pointer that has not been assigned any address value is called a wild pointer. Question 15: What is a NULL character? Answer: The termination of character strings is indicated by the presence of a null character represented by ‘\0’. The ASCII value of a null character is zero. Question 16: Give examples of linear and non-linear structures. Answer: Linear structures: arrays, stacks, linked lists, queues Non-linear structures: trees, graphs Question 17: What is the difference between LIFO and FIFO? Answer: LIFO or Last-In-First-Out is a technique used to perform insert and delete operations on stack data FIFO or First-In-First-Out is a technique used to perform insert and delete operations on queue data structure. Question 18: What is a priority queue? Answer: Refer Section 12.4.4 [Page 448]. Question 19: Which operators in C have the highest and lowest precedence? Answer: Highest: (), [], ->, ::, . Lowest: , Question 20: If x and y are two integers, write a code snippet to swap the values of x and y without using a third variable. Answer: x=y+x; y=x-y; x=x-y; Question 21: What is the difference between a linker and loader? Answer:

Question 22: What is pointer to a function? Answer: Refer Section 8.22. Question 23: What is the use of atoi() and itoa() functions? Answer: atoi() function converts an integer to a character, while the itoa() function converts an integer to a string. Question 24: What is the difference between formal arguments and actual arguments? Answer: Refer Section 5.7. Question 25: What will be the output of the code snippet given below? int a = 1, b = 1, c; c = a++ + ++b; printf(“a=%d, b=%d, c=%d”, a, b,c); Answer: Output: a = 2, b = 2, c = 3

690

Mastering C

Question 26: What will be the output of the code snippet given below? int i=1; i= i++ + ++i; printf(“i=%d”,i); Answer: Output: I = 5 Question 27: What is recursion? Answer: Refer Section 5.9. Question 28: What is the difference between const char* ptr and char const* ptr? Answer: In case of const char*p, the character value pointed by the pointer variable ptr is constant. Thus, the character value cannot change but ptr may be allocated some other address value. In case of char const* p, the address value stored in ptr is constant while the referenced character value is not constant. Thus, the character value can change but ptr cannot be allocated any other address value. Question 29: Is the execution time of i++ faster than I=i+1? Answer: Yes. i++ executes in a single machine instruction, i.e. INR while i=i+1 requires two machine instructions, i.e. addition (i+1) and assignment(=). Question 30: Write a C program to print Hello World without using a semicolon. Answer: void main() { if(printf(“Hello World”)) { } } Question 31: When is it better to use a switch statement in place of multiple if-else statements? Answer: A switch statement should be typically used in situations where there is a need to test more than two conditional expressions. Question 32: What is a ternary operator? Answer: Refer Section 2.14 [page 40]. Question 33: What will be the output of the program given below? void main() { int i; for(i=0;i