Sunday, February 7, 2010

INDIA FACTS


INDIA FACTS :

The official Sanskrit name for India is Bharat.

INDIA has been called Bharat
even in Satya yuga ( Golden Age )

More INTERESTING FACTS ABOUT India

The name `India' is derived from the River Indus, the valleys around which were the home of the early settlers. The Aryan worshippers referred to the river Indus as the Sindhu.

The Persian invaders converted it into Hindu. The name `Hindustan' combines Sindhu and Hindu and thus refers to the land of the Hindus.

The number system was invented by India. Aryabhatta was the scientist who invented the digit zero.

Sanskrit is considered as the mother of all higher languages. This is because it is the most precise, and therefore suitable language for computer software. ( a report in Forbes magazine, July 1987 ).

Chess was invented in India

Algebra, Trigonometry and Calculus are studies which originated in India.

The' place value system' and the 'decimal system' were developed in 100 BC in India.

The first six Mogul Emperor's of India ruled in an unbroken succession from father to son for two hundred years, from 1526 to 1707.

The World's First Granite Temple is the Brihadeswara temple at Tanjavur in Tamil Nadu. The shikhara is made from a single ' 80-tonne ' piece of granite. Also, this magnificient temple was built in just five years, (between 1004 AD and 1009 AD) during the reign of Rajaraja Chola.

India is.......the Largest democracy in the world, the 6th largest country in the world AND one of the most ancient and living civilizations (at least 10, 000 years old).

The game of snakes & ladders was created by the 13th century poet saint Gyandev. It was originally called 'Mokshapat.' The ladders in the game represented virtues and the snakes indicated vices. The game was played with cowrie shells and dices. Later through time, the game underwent several modifications but the meaning is the same i.e good deeds take us to heaven and evil to a cycle of re-births.

The world's highest cricket ground is in Chail, Himachal Pradesh.
Built in 1893 after levelling a hilltop, this cric
ket pitch is 2444 meters above sea level.

India has the most post offices in the world !

The largest employer in the world is the Indian railway system, employing over a million people !

The World's first university was established in Takshila in 700 BC. More than 10,500 students from all over the world studied more than 60 subjects. The University of Nalanda built in the 4th century was one of the greatest achievements of ancient India in the field of education.

Ayurveda is the earliest school of medicine known to mankind. The father of medicine, Charaka, consolidated Ayurveda 2500 years ago.

Although modern images & descriptions of India often show poverty, India was one of the richest countries till the time of British in the early 17th Century. Christopher Columbus was attracted by India's wealth and was looking for route to India when he discovered America by mistake.

The art of Navigation & Navigating was born in the river Sindh 6000 over years ago. The very word 'Navigation' is derived from the Sanskrit word NAVGATIH. The word navy is also derived from the Sanskrit word 'Nou'.

Bhaskaracharya rightly calculated the time taken by the earth to orbit the sun hundreds of years before the astronomer Smart. His calculations was - Time taken by earth to orbit the sun: ( 5th century ) 365.258756484 days.

The value of "pi" was first calculated by the Indian Mathematician Budhayana, and he explained the concept of what is known as the Pythagorean Theorem. He discovered this in the 6th century, which was long before the European mathematicians.

Algebra, trigonometry and calculus also orignated from India. Quadratic equations were used by Sridharacharya in the 11th century. The largest numbers the Greeks and the Romans used were 106 whereas Hindus used numbers as big as 10*53 ( i.e 10 to the power of 53 ) with specific names as early as 5000 B.C. during the Vedic period. Even today, the largest used number is Tera: 10*12( 10 to the power of 12 ).

Until 1896, India was the only source for diamonds to the world. ( Source . Gemological Institute of America )

The Baily Bridge is the highest bridge in the world. It is located in the Ladakh valley between the Dras and Suru rivers in the Himalayan mountains. It was built by the Indian Army in August 1982.

Sushruta is regarded as the father of surgery. Over 2600 years ago Sushrata & his team conducted complicated surgeries like cataract, artificial limbs, cesareans, fractures, urinary stones and also plastic surgery and brain surgeries.

Usage of anesthesia was well known in ancient India medicine. Detailed knowledge of anatomy, embryology, digestion, metabolism, physiology, etiology, genetics and immunity is also found in many ancient Indian texts.
Did you know ?

India also celebrates the birthday of Sarvepalli Radhakrishnan, former President and Vice-President and great statesman, as "Teachers' Day".

Born on September 5, 1888, at Tiruttani, 40 miles to the north-east of Madras, Radhakrishnan grew to become the most famous Indian teacher and philosopher of all times. In his honour, this day is celebrated as Teacher's Day.
He was also the Vice-President of India from 1952-1962. He held the office of the Chancellor, University of Delhi, before taking over as the President of India in May 1962.

"What makes a nation, is the past, what justifies one nation against others is the past", says the noted historian Eric Hobsbawm.

Hence, when talking of a nation, it becomes very imperative that the past should also be talked about. And the past of India is as fascinating and interesting as it is momentous.

History Of GOOGLE

Type Public
NASDAQ: GOOG
LSE: GGEA
Founded Menlo Park, California (September 4, 1998)[1]
Founder(s) Sergey M. Brin
Lawrence E. Page
Headquarters Googleplex, Mountain View, California, United States
Area served Worldwide
Key people Eric E. Schmidt
(Chairman) & (CEO)
Sergey M. Brin
(Technology President)
Lawrence E. Page
(Products President)
Industry Internet, Computer software
Products See list of Google products
Help
Google Web Search Features
Google Services & Tools
Google Labs[2]
Revenue 31.3% $ 21.796 billion (2008)[3]
Operating income 30.4% $ 6.632 billion (2008)[3]
Net income .6% $ 4.227 billion (2008)[3]
Total assets $ 31.768 billion (2008)[3]
Total equity $ 28.239 billion (2008)[3]
Employees 19,835 – December 31, 2009[4]
Website Google.com


Google Inc. (NASDAQ: GOOG, LSE: GGEA) is an American public corporation specializing in Internet search. It also generates profits from advertising bought on its similarly free-to-user e-mail, online mapping, office productivity, social networking and video-sharing services. Advert-free versions are available via paid subscription. Google has more recently developed an open source web browser and a mobile phone operating system. Its headquarters, often referred to as the Googleplex, is located in Mountain View, California. As of March 31, 2009 (2009 -03-31), the company had 19,786 full-time employees. It runs thousands of servers across the world, processing millions of search requests each day and about one petabyte of user-generated data each hour.[5]

Google was founded by Larry Page and Sergey Brin while students at Stanford University. It was first incorporated as a privately held company on September 4, 1998. The initial public offering was on August 19, 2004. It raised $1.67 billion, implying a total value of $23 billion. Google's rapid growth has sparked a sequence of new products, acquisitions and partnerships beyond its core search engine. Environmentalism, philanthropy and positive employee relations were from the start assigned an important role in establishing brand image. Google has been repeatedly named Fortune Magazine's Number One Best Place to Work[6] and most powerful brand in the world.[7] Alexa lists Google as the Internet's most visited website.[8]

The company's stated mission from the outset was "to organize the world's information and make it universally accessible and useful."[9] Its unofficial slogan, coined by Gmail's first engineer, Paul Buchheit, was Don't be evil.[10][11][12] Google has been criticized over issues of privacy of personal information, copyright and censorship.


History

Google in 1998
The first iteration of Google production servers was built with inexpensive hardware and was designed to be very fault-tolerant

Google began in January 1996, as a research project by Larry Page, who was soon joined by Sergey Brin, when they were both PhD students at Stanford University in California.[17] They hypothesized that a search engine that analyzed the relationships between websites would produce better ranking of results than existing techniques, which ranked results according to the number of times the search term appeared on a page.[18] Their search engine was originally nicknamed "BackRub" because the system checked backlinks to estimate the importance of a site.[19][20] A small search engine called Rankdex was already exploring a similar strategy.[21]

Convinced that the pages with the most links to them from other highly relevant web pages must be the most relevant pages associated with the search, Page and Brin tested their thesis as part of their studies, and laid the foundation for their search engine. Originally, the search engine used the Stanford University website with the domain google.stanford.edu. The domain google.com was registered on 15 September 1997,[22] and the company was incorporated as Google Inc. on 4 September 1998 at a friend's garage in Menlo Park, California. The total initial investment raised for the new company amounted to almost $1.1 million, including a $100,000 check by Andy Bechtolsheim, one of the founders of Sun Microsystems.[23]

Both Brin and Page had been against using advertising pop-ups in a search engine, or an "advertising funded search engines" model, and they wrote a research paper in 1998 on the topic while still students. However, they soon changed their minds and early on allowed simple text ads.[24]

In March 1999, the company moved into offices in Palo Alto, home to several other noted Silicon Valley technology startups.[25] After quickly outgrowing two other sites, the company leased a complex of buildings in Mountain View, California at 1600 Amphitheatre Parkway from Silicon Graphics (SGI) in 2003.[26] The company has remained at this location ever since, and the complex has since come to be known as the Googleplex (a play on the word googolplex). In 2006, Google bought the property from SGI for $319 million.[27]

The Google search engine attracted a loyal following among a growing number of Internet users, who liked its simple design and useful results.[28] In 2000, Google began selling advertisements associated with search keywords.[17] The ads were text-based to maintain an uncluttered page design and to maximize page loading speed.[17] Keywords were sold based on a combination of price bid and clickthroughs, with bidding starting at 5 cents per click.[17] This model of selling keyword advertising was pioneered by Goto.com (later renamed Overture Services, before being acquired by Yahoo! and rebranded as Yahoo! Search Marketing).[29][30][31] Goto.com was an Idealab spin off created by Bill Gross, and was the first company to successfully provide a pay-for-placement search service. Overture Services later sued Google over alleged infringements of Overture's pay-per-click and bidding patents by Google's AdWords service. The case was settled out of court, with Google agreeing to issue shares of common stock to Yahoo! in exchange for a perpetual license.[32] Thus, while many of its dot-com rivals failed in the new Internet marketplace, Google quietly rose in stature while generating revenue.[17]

A patent describing part of the Google ranking mechanism (PageRank) was granted on 4 September 2001.[33] The patent was officially assigned to Stanford University and lists Lawrence Page as the inventor.

Financing and initial public offering

The first funding for Google as a company was secured in August 1998, in the form of a $100,000 contribution from Andy Bechtolsheim, co-founder of Sun Microsystems, given to a corporation which did not yet exist.[34]

On June 7, 1999 a round of funding of $25 million was announced,[35] with the major investors being rival venture capital firms Kleiner Perkins Caufield & Byers and Sequoia Capital.[34]

The Google IPO took place on 19 August 2004. 19,605,052 shares were offered at a price of $85 per share.[36][37] Of that, 14,142,135 (another mathematical reference as √2 ≈ 1.4142135) were floated by Google, and the remaining 5,462,917 were offered by existing stockholders. Shares were sold in a unique[38] online auction format using a system built by Morgan Stanley and Credit Suisse, underwriters for the deal[39]. The sale of $1.67 billion gave Google a market capitalization of more than $23 billion.[40] The vast majority of the 271 million shares remained under the control of Google. Many Google employees became instant paper millionaires. Yahoo!, a competitor of Google, also benefited from the IPO because it owned 8.4 million shares of Google as of 9 August 2004, ten days before the IPO.[41]

The stock performance of Google after its first IPO launch has gone well, with shares hitting $700 for the first time on 31 October 2007,[42] due to strong sales and earnings in the advertising market, as well as the release of new features such as the desktop search function and its iGoogle personalized home page.[43] The surge in stock price is fueled primarily by individual investors, as opposed to large institutional investors and mutual funds.[43]

The company is listed on the NASDAQ stock exchange under the ticker symbol GOOG and under the London Stock Exchange under the ticker symbol GGEA.

Growth

While the primary business interest is in the web content arena, Google has begun experimenting with other markets, such as radio and print publications. On 17 January 2006, Google announced the purchase of a radio advertising company "dMarc", which provides an automated system that allows companies to advertise on the radio.[44] This will allow Google to combine two niche advertising media—the Internet and radio—with Google's ability to laser-focus on the tastes of consumers. Google has also begun an experiment in selling advertisements from its advertisers in offline newspapers and magazines, with select advertisements in the Chicago Sun-Times.[45] They have been filling unsold space in the newspaper that would have normally been used for in-house advertisements.

Acquisitions

Since 2001, Google has acquired several companies, mainly focusing on small start-ups.

In 2004, Google acquired a company called Keyhole, Inc.,[46] which developed a product called Earth Viewer, renamed in 2005 to Google Earth.

In February 2006, software company Adaptive Path sold Measure Map, a weblog statistics application, to Google. Registration to the service has since been temporarily disabled. The last update regarding the future of Measure Map was made on 6 April 2006 and outlined many of the known issues of the service.[47]

In late 2006, Google bought the online video site YouTube for $1.65 billion in stock.[48] Shortly after, on 31 October 2006, Google announced that it had also acquired JotSpot, a developer of wiki technology for collaborative Web sites.[49]

On 13 April 2007, Google reached an agreement to acquire DoubleClick. Google agreed to buy the company for $3.1 billion.[50]

On 2 July 2007, Google purchased GrandCentral. Google agreed to buy the company for $50 million.[51]

On 9 July 2007, Google announced that it had signed a definitive agreement to acquire enterprise messaging security and compliance company Postini.[52]

On August 5 2009, Google announced the purchase of video software maker On2 Technologies for $106.5 million - its first acquisition of a public company. [53]

On 24 November 2009, Google announced the purchase of Teracent, a California based start up company, for an undisclosed price. This is another acquisition on Google's behalf in a series of advertising related purchases- AdMob, Double Click. [54]

Partnerships

In 2005, Google entered into partnerships with other companies and government agencies to improve production and services. Google announced a partnership with NASA Ames Research Center to build up 1,000,000 square feet (93,000 m2) of offices and work on research projects involving large-scale data management, nanotechnology, distributed computing, and the entrepreneurial space industry.[55] Google also entered into a partnership with Sun Microsystems in October to help share and distribute each other's technologies.[56] The company entered into a partnership with AOL of Time Warner,[57] to enhance each other's video search services.

The same year, the company became a major financial investor of the new .mobi top-level domain for mobile devices, in conjunction with several other companies including Microsoft, Nokia, and Ericsson.[58] In September 2007, Google launched, "Adsense for Mobile", a service for its publishing partners which provides the ability to monetize their mobile websites through the targeted placement of mobile text ads,[59] and acquired the mobile social networking site, Zingku.mobi, to "provide people worldwide with direct access to Google applications, and ultimately the information they want and need, right from their mobile devices."[60]

In 2006, Google and Fox Interactive Media of News Corp. entered into a $900 million agreement to provide search and advertising on the popular social networking site, MySpace.[61]

In 2007 Google, displaced America Online, who had been a NORAD Tracks Santa program sponsor since the year 2000, as a key partner and sponsor of the NORAD Tracks Santa program.[62][63][64] For the 2007 NORAD Tracking Santa season, Google Earth was used for the first time to track Santa Claus in 3-D.[65] During the 2007 NORAD Tracking Santa season, the NORAD Tracks Santa Web site received 10.6 plus million unique visitors from 212 countries and territories. [66][67] In 2007, the NORAD Tracks Santa program made its presence known on YouTube at the NORADTracksSanta Channel on YouTube as part of the partnership with Google.[68] The 2007 NORAD Tracks Santa infrastructure integration effort, in the words of Google's Official Blog, was, "In 2007, Google became NORAD's official Santa Tracking technology partner and hosted www.noradsanta.org. In addition to tracking Santa in Google Earth, we added a Google Maps tracker and integrated YouTube videos into the journey as well. Now, we had Santa on the map and on 'Santa Cam' arriving in several different locations around the world, with commentary in six different languages. The heavy traffic — several millions of users — put Google's infrastructure to the test, but with some heroic work by our system reliability engineers, the Santa Tracker worked continuously."[69]

Google has developed a partnership with GeoEye to launch a satellite providing Google with high-resolution (0.41 m monochrome, 1.65 m color) imagery for Google Earth. The satellite was launched from Vandenberg Air Force Base on 6 September 2008.[70]

In 2008, Google announced that it was hosting an archive of Life magazine's photographs, as part of a joint effort. Some of the images in the archive were never published in the magazine.[71] The photos are watermarked and originally had copyright notices posted on all photos, regardless of public domain status.






























Thursday, February 4, 2010

Learn C in 24hrs

MKann Teach Yourself C in 24 Hours



Hour 1 - Getting Started
A journey of a thousand miles is started by taking the first step.
—Chinese proverb
High thoughts must have high language.
—Aristophanes
Welcome to Teach Yourself C in 24 Hours. In this first lesson you'll learn the following:
 What C is
 Why you need to learn C
 The ANSI standard
 Hardware and software required in order to run the C program
What Is C?
C is a programming language. The C language was first developed in 1972 by Dennis Ritchie at AT&T Bell Labs.
Ritchie called his newly developed language C simply because there was a B programming language already. (As a
matter of fact, the B language led to the development of C.)
C is a high-level programming language. In fact, C is one of the most popular general-purpose programming
languages.
In the computer world, the further a programming language is from the computer architecture, the higher the
language's level. You can imagine that the lowest-level languages are machine languages that computers understand
directly. The high-level programming languages, on the other hand, are closer to our human languages. (See Figure
1.1.)
Figure 1.1. The language spectrum.
High-level programming languages, including C, have the following advantages:
 Readability: Programs are easy to read.
 Maintainability: Programs are easy to maintain.
 Portability: Programs are easy to port across different computer platforms.
The C language's readability and maintainability benefit directly from its relative closeness to human languages,
especially English.
Each high-level language needs a compiler or an interpreter to translate instructions written in the high-level
programming language into a machine language that a computer can understand and execute. Different machines may
need different compilers or interpreters for the same programming language. For instance, I use Microsoft's C
compiler to compile the C programs in this book for my personal computer (PC). If I need to run the C programs on a
UNIX-based workstation, I have to use another type of C compiler to compile these programs. Therefore, the
portability of programs written in C is realized by re-compiling the programs with different compilers for different
machines. (See Figure 1.2.)
Figure 1.2. Porting programs written in C into different types of computers.
The Computer's Brain
You may know that the brain of a computer is the central processing unit (CPU). Some computers may
have more than one CPU inside. A CPU has millions of transistors that make use of electronic switches.
The electronic switches have only two states: off and on. (Symbolically, 0 and 1 are used to represent the
two states.) Therefore, a computer can only understand instructions consisting of series of 0s and 1s. In
other words, machine-readable instructions have to be in binary format.
However, a computer program written in a high-level language, such as C, Java, or Perl, is just a text file,
consisting of English-like characters and words. We have to use some special programs, called compilers
or interpreters, to translate such a program into a machine-readable code. That is, the text format of all
instructions written in a high-level language has to be converted into the binary format. The code
obtained after the translation is called binary code. Prior to the translation, a program in text format is
called source code.
The smallest unit of the binary code is called a bit (from binary digit), which can have a value of 0 or 1. 8
bits make up one byte, and half a byte (4 bits) is one nibble.
In addition, the C language has other advantages. Programs written in C can be reused. You can save your C
programs into a library file and invoke them in your next programming project simply by including the library file.
More details on using libraries and invoking C library functions are covered in the rest of this book.
C is a relatively small programming language, which makes life easier for you. You don't have to remember many C
keywords or commands before you start to write programs in C to solve problems in the real world.
For those who seek speed while still keeping the convenience and elegance of a high-level language, the C language
is probably the best choice. In fact, C allows you to get control of computer hardware and peripherals. That's why the
C language is sometimes called the lowest high-level programming language.
Many other high-level languages have been developed based on C. For instance, Perl is a popular programming
language in World Wide Web (WWW) design across the Internet. Perl actually borrows a lot of features from C. If
you understand C, learning Perl is a snap. Another example is the C++ language, which is simply an expanded
version of C, although C++ makes object-oriented programming easier. Also, learning Java becomes much easier if
you already know C.
NOTE
There are two types of programming languages:compiled language and interpreted language.
A compiler is needed to translate a program written in a compiled language into machineunderstandable
code (that is, binary code) before you can run the program on your machine. When the
translation is done, the binary code can be saved into an application file. You can keep running the
C and the ANSI Standard
For many years, the de facto standard for the C programming language was the K&R standard because of the book
The C Programming Language, written by Brian Kernighan and Dennis Ritchie in 1978. However, there were many
changes unofficially made to the C language that were not presented in the K&R standard.
Fearing that C might lose its portability, a group of compiler vendors and software developers petitioned the
American National Standards Institute (ANSI) to build a standard for the C language in 1983. ANSI approved the
application and formed the X3J11 Technical Committee to work on the C standard. By the end of 1989, the
committee approved the ANSI standard for the C programming language.
The ANSI standard for C enhances the K&R standard and defines a group of commonly used C functions that are
expected to be found in the ANSI C standard library. Now, all C compilers have the standard library, along with some
other compiler-specific functions.
This book focuses on the C functions defined in the ANSI standard, which is supported by all compiler vendors. All
programs in this book can be compiled by any compilers that support the ANSI standard. If you're interested in a
specific compiler, you can learn the compiler-specific functions from the compiler's reference manual.
Assumptions About You
No previous programming experience is required for you to learn the C language from this book, although some
knowledge of computers helps. Also, it's up to you to determine how quickly to go through the 24 hours of this book:
You could sit up with a big pot of coffee and power through the book in a sitting or you could take an hour a day for
24 days.
Setting Up Your System
Basically, you need a computer and a C compiler in order to compile and run your own C programs or the C
programs from this book. The recommended hardware and software are listed in the following sections.
Hardware
Any type of computer that has or can access a C compiler is fine. (The C compiler should support the ANSI
standard.) More likely, you may have a PC on your desktop. A 286 PC with a 50MB hard drive and 1MB memory
(RAM) is probably the minimum requirement to run a DOS-based C compiler. For a Windows-based C compiler, you
must have a bigger hard drive and add more memory to your computer. Check your compiler vendor for more details.
Software
If you're using a UNIX-based workstation, you might already have a C compiler loaded
on your machine, or at least you might be able to access a C compiler on a server machine. Check with your system
application file without the compiler unless the program (source code) is updated and you have to
recompile it. The binary code or application file is also called executable code (or an executable file).
On the other hand, a program written in an interpreted language can be run immediately after you finish
writing it. But such a program always needs an interpreter to translate the high-level instructions into
machine-understandable instructions (binary code) at runtime. You cannot run the program on a
machine unless the right interpreter is available.
You can think of the C language as a compiled language because most
C language vendors make only C compilers to support programs written in C.
administrator to find out about a C compiler that supports the ANSI standard, and set up the right path to access it. On
a UNIX-based machine, you should know how to use a text editor, such as vi and emacs, to write C programs.
If you have a PC, you need to install a C compiler and a text editor on it. Most C compilers come with an editor. You
can also use a text editor that is already installed on your machine.
Borland International's Turbo C and Microsoft's Quick C used to be very popular in the C compiler market. These
days, C compiler vendors like to bundle C and C++ compilers together. For instance, Borland International sells
Borland C++ with a C compiler. The same thing is true for Microsoft's Visual C++. Both Borland C++ and Visual
C++ support the ANSI standard. Both of them provide an integrated development environment (IDE), which you can
use to edit your C programs, along with other fancy features for advanced Windows programming.
Appendix D, "Some Popular Commercial C/C++ Compilers," introduces several C compilers besides Borland C++
and Microsoft's Visual C++.
You can pick up any C compiler you like, as long as the compiler supports the ANSI standard. You shouldn't have
any problems installing a C compiler on your machine if you read the manuals that come with the compiler and
follow the installation instructions correctly. Most C/C++ compilers provide a quick tutorial that shows you how to
install the compiler and set up a development environment on your computer.
The Hardware and Software I Use for C Programming
I have a Pentium 100MHz PC with 32MB memory and with a 2.5GB hard drive. (32MB memory may be more than
enough to run the C programs from this book, but I need a lot of memory space for Windows programming.) I have
both Windows 95 and Windows NT on my machine.
Figure 1.3. An example of the IDE from Visual C++ version 1.5.
In this book, all C programs are developed with Microsoft Visual C++ version 1.5. (The latest version of Visual C++
is 5.0.) The reasons I chose Visual C++ 1.5 are simple: All C programs in this book are written in ANSI C and can be
compiled into DOS-based applications; Visual C++ 1.5 has a good C compiler that supports the ANSI standard, as
well as a simple but friendly enough IDE. Figure 1.3 shows an example of the IDE from Visual C++ 1.5. (The later
version of Visual C++ has a fancy IDE with more features added. However, many of those features are not needed for
running the C programs in this book.)
I set up my development environment in such a way that all C programs in this book can be compiled and made into
DOS applications. Also, I test and run the applications made from the C programs at a DOS prompt provided by
Windows 95.
Summary
In this first lesson you've learned the following:
 C is a general-purpose programming language.
 C is a high-level language that has the advantages of readability, maintainability, and portability.
TIP
You can learn more about Borland C++ or Visual C++ from books such as Teach Yourself Borland C++
5 in 21 Days (from Sams Publishing/Borland Press) and Teach Yourself Visual C++ 5 in 21 Days (also
from Sams Publishing).
 C is a very efficient language that allows you to get control of computer hardware and peripherals.
 C is a small language that you can learn easily in a relatively short time.
 Programs written in C can be reused.
 Programs written in C must be compiled and translated into machine-readable code before the computer can
execute them.
 C provides many programming languages, such as Perl, C++, and Java, with basic concepts and useful features.
 The ANSI standard for C is the standard supported by all C compiler vendors to guarantee the portability of C.
 You can use any C compilers that support the ANSI standard and compile all C programs in this book.
In the next lesson you'll learn to write your first C program.
Q&A
Q What is the lowest-level language in the computer world?
A The computer's machine language is the lowest because the machine language, made up of 0s and 1s,
is the only language that the computer can understand directly.
Q What are the advantages of high-level programming languages?
A Readability, maintainability, and portability are the main advantages of high-level programming
languages.
Q What is C, anyway?
A C is a general-purpose programming language. It's a high-level language that has advantages such as
readability, maintainability, and portability. Also, C allows you to get down to the hardware to increase
the performance speed if needed. A C compiler is needed to translate programs written in C into
machine-understandable code. The portability of C is realized by recompiling the C programs with
different C compilers specified for different types of computers.
Q Can I learn C in a short time?
A Yes. C is a small programming language. There are not many C keywords or commands to remember.
Also, it's very easy to read or write in C because C is a high-level programming language that is close to
human languages, especially English. You can learn C in a relatively short time.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions provided
in the Workshop before you move to the next lesson. The answers and hints to the questions are given in Appendix E,
"Answers to Quiz Questions and Exercises."
Quiz
1. What are the lowest-level and highest-level languages mentioned in this book?
2. Can a computer understand a program written in C? What do you need to translate a program written in C into
the machine-understandable code (that is, binary code)?
3. If needed, can a C program be reused in another C program?
4. Why do we need the ANSI standard for the C language?
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 2 - Writing Your First C Program
Cut your own wood and it will warm you twice.
—Chinese proverb
In Hour 1, "Getting Started," you learned that C is a high-level programming language and that you need a C
compiler to translate your C programs into binary code that your computer can understand and execute. In this lesson
you'll learn to write your first C program and the basics of a C program, such as
 The #include directive
 Header files
 Comments
 The main() function
 The return statement
 The exit() function
 The newline character (\n)
 The void data type
 Translating a C program into an executable file
 Debugging
A Simple C Program
Let's have a look at our first C program, demonstrated in Listing 2.1. Later in this lesson you're going to write your
own C program for the first time.
TYPE
Listing 2.1. A simple C program.
1: /* 02L01.c: This is my first C program */
2: #include
3:
4: main()
5: {
6: printf ("Howdy, neighbor! This is my first C program.\n");
7: return 0;
8: }
This is a very simple C program, which is saved in a file called 02L01.c. Note that the name of a C program file must
have an extension of .c. If you've installed a C compiler and set up the proper development environment, you should
be able to compile this C program and make it into an executable file.
I set up my development environment in such a way that all C programs in this book can be compiled and made into
DOS-based applications. For instance, 02L01.exe is the name of the DOS application made from 02L01.c. Note
that .exe is included as the extension to the name of a DOS application program (that is, an executable file).
Also, on my machine, I save all the executable files made from the C programs in this book into a dedicated directory
called C:\app. Therefore, if I type in 02L01 from a DOS prompt and press the Enter key, I can run the 02L01.exe
executable file and display the message Howdy, neighbor! This is my first C program. on the screen. The following
output is a copy from the screen:
C:\app> 02L01
Howdy, neighbor! This is my first C program.
C:\app>
Comments
Now let's take a close look at the C program in Listing 2.1.
The first line contains a comment:
/* 02L01.C: This is my first C program */
You notice that this line starts with a combination of a slash and an asterisk, /*, and ends with */. In C, /* is called the
opening comment mark, and */ is the closing comment mark. The C compiler ignores everything between the opening
comment mark and closing comment mark. That means the comment in the first line of Listing 2.1, 02L01.C: This is
my first C program, is ignored by the compiler.
The only purpose of including comments in your C program is to help you document what the program or some
specific sections in the programs do. Remember, comments are written for programmers like you. For example, when
you read someone's code, the comments in the code help you to understand what the code does, or at least what the
code intends to do.
You don't need to worry about the size or performance speed of your C program if you add many comments into it.
Adding comments into a C program does not increase the size of the binary code of the program (that is, the
executable file), although the size of the program itself (that is, the source code) may become larger. Also, the
performance speed of the executable file made from your C program is not affected by the comments inside your C
program.
Most C compilers allow you to write a comment that crosses more than one line. For instance, you can write a
comment in C like this:
/*
This comment does not increase the size of
the executable file (binary code), nor does
it affect the performance speed.
*/
which is equivalent to this:
/* This comment does not increase the size of */
/* the executable file (binary code), nor does */
/* it affect the performance speed. */
NOTE
These days, there is another way to put comments into a C program. C++ started using two slashes (//)
to mark the beginning of a comment line; many C compilers now use this convention as well. The
comment ends at the end of the line. For instance, if I write a C program in Borland C++ or Visual C++,
the following two comments are identical:
/*
This comment does not increase the size of
the executable file (binary code), nor does
it affect the performance speed.
*/
// This comment does not increase the size of
// the executable file (binary code), nor does
// it affect the performance speed.
One thing that needs to be pointed out is that the ANSI standard does not support nested comments, that is, comments
within comments. For instance, the following is not allowed by the ANSI standard:
/* This is the first part of the first comment
/* This is the second comment */
This is the second part of the first comment */
The #include Directive
Let's now move to line 2 in the C program of Listing 2.1:
#include
You see that this line starts with a pound sign, #, which is followed by include. In C, #include forms a preprocessor
directive that tells the C preprocessor to look for a file and place the contents of the file in the location where the
#include directive indicates.
The preprocessor is a program that does some preparations for the C compiler before your code is compiled. More
details about the C preprocessor are discussed in Hour 23, "The C Preprocessor."
Also in this line, you see that follows #include. You may guess that the file the #include directive asks for
is something called stdio.h. You are exactly right! Here, the #include directive does ask the C preprocessor to look for
and place stdio.h where the directive is in the C program.
The name of the stdio.h file stands for standard input-output header file. The stdio.h file contains numerous
prototypes and macros to perform input or output (I/O) for C programs. You'll see more program I/O in Hour 5,
"Reading from and Writing to Standard I/O."
Header Files
The files that are required by the #include directive, like stdio.h, are called header files because the #include
directives are almost always placed at the head of C programs. Actually, the extension name of .h does mean
"header."
Besides stdio.h, there are more header files, such as stdlib.h, string.h, math.h, and so on. Appendix A, "ANSI
Note that this new style of using // as the beginning mark of a comment has not been approved by ANSI.
Make sure your C compiler supports // before you use it.
TIP
You can use the opening comment mark, /*, and closing comment mark, */, to help you test and fix any
errors found in your C program. You can comment out one or more C statements in your C program
with /* and */ when you need to focus on other statements and watch their behaviors closely. The C
compiler will ignore the statements you comment out.
Later, you can always restore the previously commented-out statements simply by removing the
opening comment and closing comment marks. In this way, you don't need to erase or rewrite any
statements during the testing and debugging.
NOTE
The C programming language distinguishes between lowercase and uppercase characters. In other
words, C is a case-sensitive language. For instance, stdio.h and STDIO.H are different filenames in C.
Likewise, main() and Main() are two different function names.
Standard Header Files," gives a list of all the ANSI standard header files.
Angle Brackets (< >) and Double Quotes (" ")
In the second line of Listing 2.1, there are two angle brackets, <>, that are used to surround stdio.h. You may be
wondering what the angle brackets do. In C, the angle brackets ask the C preprocessor to look for a header file in a
directory other than the current
one.
For instance, the current directory containing the 02L01.C file is called C:\code on my computer. Therefore, the angle
brackets around tell the C preprocessor to look for stdio.h in a directory other than C:\code.
If you want to let the C preprocessor look into the current directory first for a header file before it starts to look
elsewhere, you can use double quotes to surround the name of the header file. For instance, when the C preprocessor
sees "stdio.h", it looks in the current directory, which is C:\code on my machine, first before it goes elsewhere for the
stdio.h header file.
Normally, the header files are saved in a subdirectory called include. For instance, I might install a Microsoft C
compiler in the directory MSVC on my hard drive, which is labeled as the C drive. Then the path to access the header
files becomes C:\MSVC\include.
The main() Function
In line 4 of Listing 2.1, you see this function:
main ()
This is a very special function in C. Every C program must have a main() function, and every C program can only
have one main() function. More generic discussions about functions are given in Hour 3, "The Essentials of C
Programs."
You can put the main() function wherever you want in your C program. However, the execution of your program
always starts with the main() function.
In Listing 2.1, the main() function body starts in line 4 and ends in line 8. Because this is a very simple program, the
main() function is the only function defined in the program. Within the main() function body, a C library function,
printf(), is called in order to print out a greeting message. (See line 6.) More details about printf() are covered in Hour
5.
One more important thing about main() is that the execution of every C program ends with main(). A program ends
when all the statements within the main() function have been executed.
The Newline Character (\n)
In the printf() function, one thing worth mentioning at this moment is the newline character, \n. Usually suffixed at
the end of a message, the newline character tells the computer to generate a carriage-return and line-feed sequence so
that anything printed out after the message will start on the next new line on the screen.
Exercise 3 in this lesson gives you a chance to use the newline character to break a one-line message into two lines.
The return Statement
All functions in C can return values. For instance, when you make a function to add two numbers, you can make such
a function that returns to you the value of the addition.
The main() function itself returns a value. By default, main() returns an integer. In C, integers are decimal numbers
without fraction portions.
Therefore, in line 7 of Listing 2.1, there is a statement, return 0;, that indicates that 0 is returned from the main()
function and the program is terminated normally.
A nonzero value returned by the return statement tells the operating system that an error has occurred. The bigger the
return value, the more severe the error.
The exit() Function
There is also a C library function, exit(), that can be used to cause a program to end. Because the exit() function is
defined in a header file, stdlib.h, you have to include the header file at the beginning of your program.
Unlike main(), the exit() function itself does not return any values, but the argument to exit() indicates whether the
program is terminated normally. A nonzero argument to the exit() function tells the operating system that the program
has terminated abnormally.
Actually, you can replace return 0; in line 7 of Listing 2.1 with exit(0); and get a similar result after running the
modified program.
Note that return and exit() can also be used in other functions. You'll see more examples in the rest of the book.
Listing 2.2 contains the program that uses exit() instead of return.
TYPE
Listing 2.2. A C program with exit().
1: /* 02L02.c */
2: #include
3: #include
4:
5: void main()
6: {
7: printf ("Howdy, neighbor! This is my first C program.\n");
8: exit(0);
9: }
After compiling the program in Listing 2.2, you should be able to run the program and get the same message, Howdy,
neighbor! This is my first C program., printed out on the screen.
The void Data Type
You may notice that the void word has been added into the C program in Listing 2.2. void is a keyword for a data
type in C. When a void is placed prior to a function name, it indicates that the function does not return a value.
As you have learned, the exit() function does not return any values, but, by default, the main() function does.
Therefore, as shown in line 5 of Listing 2.2, void is used to modify the returning data type of main() and to make the
main() function not return any value. (You'll learn more about data types in C in Hours 4, "Data Types and Names in
C," and 18, "More Data Types and Functions.")
Compiling and Linking
You may already be anxious to know how an executable file is made. Let's have a look at how a C program is
compiled and translated into an executable file (binary code). As shown in Figure 2.1, there are at least three steps
needed to create an executable file.
Figure 2.1. Make an executable file by the compiler and linker.
First, a program written in C, called source code, is made. Then the source code is compiled by a C compiler, which
creates a new file. The new file is an object file. In the UNIX operating system, the name of an object file ends with
the extension .o; in the DOS operating system, the extension is .obj.
You cannot execute the object file because there is some function code missing. You have to finish the next step:
linking. Linking is done by invoking a special program called a linker, which normally comes with the compiler
package.
A linker is used to link together the object file, the ANSI standard C library, and other user-generated libraries to
produce an executable file—the binary code. In this stage, the binary code of the library functions that are called in
the source code is combined with the object file; the result is saved into a new file—an executable file. As you
learned in the first hour of this book, the name of an executable file usually ends with the extension .exe in DOS.
(.com is another extension used for a DOS executable filename.) In UNIX, it's not necessary to include such an
extension to an executable filename.
Later, you'll learn that in many cases, there may be several object files that have to be linked together in order to
make an executable program.
Note that the object file and executable file are both machine-dependent. You cannot simply move an executable file,
without recompiling the source code, from the current computer platform to another one that is operated by a different
operating system even though the source code of the executable file, presumably written in ANSI C, is machine
independent (that is, portable).
What's Wrong with My Program?
When you finish writing a C program and start to compile it, you might get some error or warning messages. Don't
panic when you see error messages. We're human beings. Everybody makes mistakes. Actually, you should
appreciate that your compiler catches some errors for you before you go any further.
Usually, your compiler can help you check the grammar of your C program and make sure you've followed the C
programming rules properly. For instance, if you forget to put the ending brace on the main() function in line 8 of
Listing 2.1, you'll get an error message something like this: syntax error : end of file found.
Also, the linker will issue an error message if it cannot find the missing code for a needed function in the libraries.
For instance, if you misspell printf() as pprintf() in the program of Listing 2.1, you'll see an error message: `_pprintf':
unresolved external (or something similar).
All errors found by the compiler and linker must be fixed before an executable file (binary code) can be made.
Debugging Your Program
In the computer world, program errors are also called bugs. In many cases, your C compiler and linker do not find
any errors in your program, but the result generated by running the executable file of the program is not what you
expect. In order to find those "hidden" errors in your program, you may need to use a debugger.
Normally, your C compiler vendor already includes a debugger software program in the C compiler package. The
debugger can execute your program one line at a time so that you can watch closely what's going on with the code in
each line, or so that you can ask the debugger to stop running your program on any line. For more details about your
debugger, refer to the manuals made by your C compiler vendor.
Later in this book, you'll learn that debugging is a very necessary and important step in writing software programs.
(This topic is covered in Hour 24, "What You Can Do Now.")
Summary
In this lesson you've learned the following:
 Some header files should be included at the beginning of your C program.
 Header files, such as stdio.h and stdlib.h, contain the declarations for functions used in your C program; for
example, the printf() and exit() functions.
 Comments in your C programs are needed to help you document your programs. You can put comments
anywhere you like in your programs.
 In ANSI C, a comment starts with the opening comment mark, /*, and ends with the closing comment mark, */.
 Every C program should have one but only one main() function. The program execution starts and ends with
the main() function.
 The sequence of a carriage return and a line feed is carried out when the computer sees the newline character,
\n.
 The return statement can be used to return a value to indicate to the operating system whether an error has
occurred. The exit() function terminates a program; the argument to the function indicates the error status, too.
 The void data type can be used to modify the type of a return value for a function. Applying void to main() tells
the operating system that the main() function does not return any value after termination.
 Compiling and linking are consecutive steps that have to be finished before an executable file is produced.
 Everybody, including yourself, makes mistakes in programming. Debugging is a very important step in your
program design and coding.
In the next lesson you'll learn more about the essentials of C programs.
Q&A
Q Why do you need to put comments into your programs?
A Comments help us document what a program, or a special portion of a program, does. Especially when
a program becomes very complex, we need to write comments to mark different parts in the program.
Q Why is the main() function needed in your program?
A The execution of a C program starts and ends with the main() function. Without the main() function,
the computer does not know where to start to run a program.
Q What does the #include directive do?
A The #include directive is used to include header files that contain the declarations to the functions used
in your C program. In other words, the #include directive tells the C preprocessor to look into directories
and find the specified header file.
Q Why do you need a linker?
A After compiling, some function code may still be missing in the object file of a program. A linker must
then be used to link the object file to the C standard library or other user-generated libraries and include
the missing function code so that an executable file can be created.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. Can a C compiler see the comments within your C program?
2. What kinds of files does a C compiler actually produce?
3. Does the exit() function return a value? How about the return statement?
4. What is a header file?
Exercises
1. Is #include the same as #include "stdio.h"?
2. It's time for you to write your own first program. Referring to the program in Listing 2.1, write a C program
that can print out a message: It's fun to write my own program in C.
3. Update the program in Listing 2.1 by adding one more newline character into the message printed out by the
printf() function. You should see two lines of the message on the screen after running the updated executable
file:
Howdy, neighbor!
This is my first C program.
4. What warning or error messages will you get when you're trying to compile the following program?
#include
#include
main()
{
printf ("Howdy, neighbor! This is my first C program.\n");
exit(0);
}
5. What error messages will you get when you're trying to compile the following program?
void main()
{
printf ("Howdy, neighbor! This is my first C program.\n");
return 0;
}
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 3 - The Essentials of C Programs
The whole is equal to the sum of its parts.
—Euclid
In Hour 2, "Writing Your First C Program," you saw and wrote some simple C programs. You also learned about the
basic structure of a C program. You know that a program written in C has to be compiled before it can be executed. In
this lesson you'll learn more essentials within a C program, such as
 Constants and variables
 Expressions
 Statements
 Statement blocks
 C function types and names
 Arguments to functions
 The body of a function
 Function calls
The Basics of the C Program
As a building is made of bricks, a C program is made of basic elements, such as expressions, statements, statement
blocks, and function blocks. These elements are discussed in the following sections. But first, you need to learn two
smaller but important elements, constant and variable, which make up expressions.
Constants and Variables
As its name implies, a constant is a value that never changes. A variable, on the other hand, can be used to present
different values.
You can think of a constant as a music CD-ROM; the music saved in the CD-ROM is never changed. A variable is
more like an audio cassette: You can always update the contents of the cassette by simply overwriting the old songs
with new ones.
You can see many examples in which constants and variables are in the same statement. For instance, consider the
following:
i = 1;
where the symbol 1 is a constant because it always has the same value (1), and the symbol i is assigned the constant 1.
In other words, i contains the value of 1 after the statement is executed. Later, if there is another statement,
i = 10;
after it is executed, i is assigned the value of 10. Because i can contain different values, it's called a variable in the C
language.
Expressions
An expression is a combination of constants, variables, and operators that are used to denote computations.
For instance, the following:
(2 + 3) * 10
is an expression that adds 2 and 3 first, and then multiplies the result of the addition by 10. (The final result of the
expression is 50.)
Similarly, the expression 10 * (4 + 5) yields 90. The 80/4 expression results in 20.
Here are some other examples of expressions:
Arithmetic Operators
As you've seen, an expression can contain symbols such as +, *, and /. In the C language, these symbols are called
arithmetic operators. Table 3.1 lists all the arithmetic operators and their meanings.
Table 3.1. C arithmetic operators.
You may already be familiar with all the arithmetic operators, except the remainder (%) operator. % is used to obtain
the remainder of the first operand divided by the second operand. For instance, the expression
6 % 4
yields a value of 2 because 4 goes into 6 once with a remainder of 2.
The remainder operator, %, is also called the modulus operator.
Among the arithmetic operators, the multiplication, division, and remainder operators have a higher precedence than
the addition and subtraction operators. For example, the expression
2 + 3 * 10
yields 32, not 50. Because of the higher precedence of the multiplication operator, 3 * 10 is calculated first, and then
2 is added into the result of the multiplication.
As you might know, you can put parentheses around an addition (or subtraction) to force the addition (or subtraction)
to be performed before a multiplication, division, or modulus computation. For instance, the expression
(2 + 3) * 10
Expression Description
6 An expression of a constant.
i An expression of a variable.
6 + i An expression of a constant plus a variable.
exit(0) An expression of a function call.
Symbol Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% Remainder (or modulus)
performs the addition of 2 and 3 first before it does the multiplication of 10.
You'll learn more operators of the C language in Hours 6, "Manipulating Data with Operators," and 8, "More
Operators."
Statements
In the C language, a statement is a complete instruction, ending with a semicolon. In many cases, you can turn an
expression into a statement by simply adding a semicolon at the end of the expression.
For instance, the following
i = 1;
is a statement. You may have already figured out that the statement consists of an expression of i = 1 and a semicolon
(;).
Here are some other examples of statements:
i = (2 + 3) * 10;
i = 2 + 3 * 10;
j = 6 % 4;
k = i + j;
Also, in the first lesson of this book you learned statements such as
return 0;
exit(0);
printf ("Howdy, neighbor! This is my first C program.\n");
Statement Blocks
A group of statements can form a statement block that starts with an opening brace ({) and ends with a closing brace
(}). A statement block is treated as a single statement by the C compiler.
For instance, the following
for(. . .) {
s3 = s1 + s2;
mul = s3 * c;
remainder = sum % c;
}
is a statement block that starts with { and ends with }. Here for is a keyword in C that determines the statement block.
The for keyword is discussed in Hour 7, "Doing the Same Thing Over and Over."
A statement block provides a way to group one or more statements together as a single statement. Many C keywords
can only control one statement. If you want to put more than one statement under the control of a C keyword, you can
add those statements into a statement block so that the block is considered one statement by the C keyword.
Anatomy of a C Function
Functions are the building blocks of C programs. Besides the standard C library functions, you can also use some
other functions made by you or another programmer in your C program. In Hour 2 you saw the main() function, as
well as two C library functions, printf() and exit(). Now, let's have a closer look at functions.
As shown in Figure 3.1, a function consists of six parts: the function type, the function name, arguments to the
function, the opening brace, the function body, and the closing
Figure 3.1. The anatomy of a function in the C language. brace.
The six parts of a function are explained in the following sections.
Determining a Function's Type
The function type is used to signify what type of value a function is going to return after its execution. In Hour 2, for
instance, you learned that the default function type of main() is integer. You also learned how to change the function
type of main() to void so that the main() function does need to return any value.
In C, int is used as the keyword for the integer data type. In the next hour, you'll learn more about data types.
Giving a Function a Valid Name
A function name is given in such a way that it reflects what the function can do. For
instance, the name of the printf() function means "print formatted data."
There are certain rules you have to follow to make a valid function name. The following are examples of illegal
function names in C:
Some samples of valid function names are as follows:
 print2copy
 total_number
 _quick_add
 Method3
Arguments to C Functions
You often need to pass a function some information before executing it. For example, in Listing 2.1 in Hour 2, a
character string, "Howdy, neighbor! This is my first C program.\n", is passed to the printf() function, and then printf()
prints the string on the screen.
Pieces of information passed to functions are known as arguments. The argument of a function is placed between the
parentheses that immediately follow the function name.
The number of arguments to a function is determined by the task of the function. If a function needs more than one
Illegal Name The Rule
2 (digit) A function name cannot start with a digit.
* (Asterisk) A function name cannot start with an asterisk.
+ (Addition) A function name cannot start with one of the arithmetic signs that are reserved C keywords.
. (dot) A function name cannot start with ..
total-number A function name cannot contain a minus sign.
account'97 A function name cannot contain an apostrophe.
argument, arguments passed to the function must be separated by commas; these arguments are considered an
argument list.
If no information needs to be passed to a function, you just leave the argument field between the parentheses blank.
For instance, the main() function in Listing 2.1 of Hour 2 has no argument, so the field between the parentheses
following the function name is empty.
The Beginning and End of a Function
As you may have already figured out, braces are used to mark the beginning and end of a function. The opening brace
({) signifies the start of a function body, while the closing brace (}) marks the end of the function body.
As mentioned earlier, the braces are also used to mark the beginning and end of a statement block. You can think of it
as a natural extension to use braces with functions because a function body can contain several statements.
The Function Body
The function body in a function is the place that contains variable declarations and C statements. The task of a
function is accomplished by executing the statements inside the function body one at a time.
Listing 3.1 demonstrates a function that adds two integers specified by its argument and returns the result of the
addition.
TYPE
Listing 3.1. A function that adds two integers.
1: /* This function adds two integers and returns the result */
2: int integer_add( int x, int y )
3: {
4: int result;
5: result = x + y;
6: return result;
7: }
ANALYSIS
As you learned in Hour 2, line 1 of Listing 3.1 is a comment that tells the program-mer what the function
can do.
In line 2, you see that the int data type is prefixed prior to the function name. Here int is used as the function type,
which signifies that an integer should be returned by the function. The function name shown in line 2 is integer_add.
The argument list contains two arguments, int x and int y, in line 2, where the int data type specifies that the two
arguments are both integers.
Line 4 contains the opening brace ({) that marks the start of the function.
The function body is in lines 4_6 in Listing 3.1. Line 4 gives the variable declaration of result, whose value is
specified by the int data type as an integer. The statement in line 5 adds the two integers represented by x and y and
assigns the computation result to the result variable. The return statement in line 6 then returns the computation result
represented by result.
Last, but not least, the closing brace (}) in line 7 is used to close the function.
TIP
When you create a function in your C program, don't assign the function too much work. If a function
has too much to do, it will be very difficult to write and debug. If you have a complex programming
Making Function Calls
Based on what you've learned so far, you can write a C program that calls the integer_add() function to calculate an
addition and then print out the result on the screen. An example of such a program is demonstrated in Listing 3.2.
TYPE
Listing 3.2. A C program that calculates an addition and prints the result to the screen.
1: /* 03L02.c: Calculate an addition and print out the result */
2: #include
3: /* This function adds two integers and returns the result */
4: int integer_add( int x, int y )
5: {
6: int result;
7: result = x + y;
8: return result;
9: }
10:
11: int main()
12: {
13: int sum;
14:
15: sum = integer_add( 5, 12);
16: printf("The addition of 5 and 12 is %d.\n", sum);
17: return 0;
18: }
OUTPUT
The program in Listing 3.2 is saved as a source file called 03L02.c. After this program is compiled and
linked, an executable file for 03L02.c is created. On my machine, the executable file is named
03L02.exe. The following is the output printed on the screen after I run the executable from a DOS
prompt on my machine:
C:\app> 03L02
The addition of 5 and 12 is 17.
C:\app>
ANALYSIS
Line 1 in Listing 3.2 is a comment about the program. As you learned in Hour 2, the include directive in
line 2 includes the stdio.h header file because of the printf() function in the program.
Lines 3_9 represent the integer_add() function that adds two integers, as discussed in the previous section.
The main() function, prefixed with the int data type, starts in line 11. Lines 12 and 18 contain the opening brace and
closing brace for the main() function, respectively. An integer variable, sum, is declared in line 13.
The statement in line 15 calls the integer_add() function that we examined in the previous section. Note that two
integer constants, 5 and 12, are passed to the integer_add() function, and that the sum variable is assigned the result
returned from the integer_add() function.
You first saw the C standard library function printf() in Hour 2. Here you may find something new added to the
function in line 16. You're right. This time, there are two arguments that are passed to the printf() function. They are
the string "The addition of 5 and 12 is %d.\n" and the variable sum.
Note that a new symbol, %d, is added into the first argument. The second argument is the integer variable sum.
project, break it into smaller pieces. And try your best to make sure that each function has just one task
to do.
Because the value of sum is going to be printed out on the screen, you might think that the %d has something to do
with the integer variable sum. You're right again. %d tells the computer the format in which sum should be printed on
the screen.
More details on %d are covered in Hour 4, "Data Types and Names in C." The relationship between %d and sum is
discussed in Hour 5, "Reading from and Writing to Standard I/O."
More importantly, you should focus on the program in Listing 3.2 and pay attention to how to call either a usergenerated
function or a standard C library function from the main() function.
Summary
In this lesson you've learned the following:
 A constant in C is a value that never changes. A variable, on the other hand, can present different values.
 A combination of constants, variables, and operators is called an expression in the C language. An expression is
used to denote different computations.
 The arithmetic operators include +, -, *, /, and %.
 A statement consists of a complete expression suffixed with a semicolon.
 The C compiler treats a statement block as a single statement, although the statement block may contain more
than one statement.
 The function type of a function determines the type of the return value made by the function.
 You have to follow certain rules to make a valid function name.
 An argument contains information that you want to pass to a function. An argument list contains two or more
arguments that are separated by commas.
 The opening brace ({) and closing brace (}) are used to mark the start and end of a C function.
 A function body contains variable declarations and statements. Usually, a function should accomplish just one
task.
In the next lesson you'll learn more about data types in the C language.
Q&A
Q What is the difference between a constant and a variable?
A The major difference is that the value of a constant cannot be changed, while the value of a variable
can. You can assign different values to a variable whenever it's necessary in your C program.
Q Why do you need a statement block?
A Many C keywords can only control one statement. A statement block provides a way to put more than
one statement together and put the statement block under the control of a C keyword. Then, the statement
block is treated as a single statement.
Q Which arithmetic operators have a higher precedence?
A Among the five arithmetic operators, the multiplication, division, and remainder operators have a
higher precedence than the addition and subtraction operators.
Q How many parts does a function normally have?
A A function normally has six parts: the function type, the function name, the arguments, the opening
brace, the function body, and the closing brace.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. In the C language, is 74 a constant? How about 571?
2. Is x = 570 + 1 an expression? How about x = 12 + y?
3. Are the following function names valid?
2methods
m2_algorithm
*start_function
Room_Size
.End_Exe
_turbo_add
4. Is 2 + 5 * 2 equal to (2 + 5) * 2?
5. Does 7 % 2 produce the same result as 4 % 3?
Exercises
1. Given two statements, x = 3; and y = 5 + x;, how can you build a statement block with the two statements?
2. What is wrong with the following function?
int 3integer_add( int x, int y, int z)
{
int sum;
sum = x + y + z;
return sum;
}
3. What is wrong with the following function?
int integer_add( int x, int y, int z)
{
int sum;
sum = x + y + z
return sum;
}
4. Write a C function that can multiply two integers and return the calculated result.
5. Write a C program that calls the C function you just wrote in exercise 4 to calculate the multiplication of 3
times 5 and then print out the return value from the function on the screen.
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 4 - Data Types and Names in C
What's in a name? That which we call a rose
By any other name would smell as sweet.
—W. Shakespeare
You learned how to make a valid name for a C function in Hour 3, "The Essentials of C Programs." Now, you're
going to learn more about naming a variable and the C keywords reserved by the C compiler in this hour.
Also in this hour you're going to learn about the four data types of the C language in detail:
 char data type
 int data type
 float data type
 double data type
C Keywords
The C language reserves certain words that have special meanings to the language. Those reserved words are
sometimes called C keywords. You should not use the C keywords as variable, constant, or function names in your
program. The following are the 32 reserved C keywords:
Keyword Description
auto Storage class specifier
break Statement
case Statement
char Type specifier
const Storage class modifier
continue Statement
default Label
do Statement
double Type specifier
else Statement
enum Type specifier
extern Storage class specifier
float Type specifier
for Statement
goto Statement
if Statement
int Type specifier
long Type specifier
register Storage class specifier
return Statement
short Type specifier
Don't worry if you can't remember all the C keywords the first time through. In the rest of the book, you'll become
more familiar with them and start to use many of the keywords through examples and exercises.
Note that all C keywords are written in lowercase letters. As I've mentioned, C is a case-sensitive language.
Therefore, int, as shown in the list here, is considered as a C keyword, but INT is not.
The char Data Type
An object of the char data type represents a single character of the character set used by your computer. For example,
A is a character, and so is a. But 7 is a number.
But a computer can only store numeric code. Therefore, characters such as A, a, B, b, and so on all have a unique
numeric code that is used by computers to represent the characters. Usually, a character takes 8 bits (that is, 1 byte) to
store its numeric code.
For many computers, the ASCII codes are the de facto standard codes to represent a character set. (ASCII, just for
your information, stands for American Standard Code for Information Interchange.) The original ASCII character set
has only 128 characters because it uses the lower 7 bits that can represent 27 (that is, 128) characters.
On IBM-compatible PCs, however, the character set is extended to contain a total of 256 (that is, 28) characters.
Appendix C, "ASCII Character Set," gives a list of the 256 characters.
Character Variables
A variable that can represent different characters is called a character variable.
You can set the data type of a variable to char by using the following declaration format:
char variablename;
where variablename is the place where you put the name of a variable.
If you have more than one variable to declare, you can either use the following format:
char variablename1;
char variablename2;
char variablename3;
or this one:
signed Type specifier
sizeof Operator
static Storage class specifier
struct Type specifier
switch Statement
typedef Statement
union Type specifier
unsigned Type specifier
void Type specifier
volatile Storage class modifier
while Statement
char variablename1, variablename2, variablename3;
Character Constants
A character enclosed in single quotes (`) is called a character constant. For instance, `A', `a', `B', and `b' are all
character constants that have their unique numeric values in the ASCII character set.
You can remember to use the single quote (`), instead of the double quote ("), in character constants because a
character constant represents a single character. You'll see later in the book that the double quote is used to indicate a
string of characters.
From the ASCII character set listed in Appendix C, you will find that the unique numeric (decimal) values of `A', `a',
`B', and `b' are 65, 97, 66, and 98, respectively. Therefore, given x as a character variable, for instance, the following
two assignment statements are equivalent:
x = `A';
x = 65;
So are the following two statements:
x = `a';
x = 97;
Later in this hour, you'll see a program (in Listing 4.2) that converts numeric values back to the corresponding
characters.
The Escape Character (\)
Actually, you first saw the escape character (\) in Hour 2, "Writing Your First C Program," when you learned to use
the newline character (\n) to break a message into two pieces. In the C language, the backslash (\) is called the escape
character; it tells the computer that a special character follows.
For instance, when the computer sees \ in the newline character \n, it knows that the next character, n, causes a
sequence of a carriage return and a line feed.
Besides the newline character, several other special characters exist in the C language, such as the following:
Printing Out Characters
You already know that the printf() function, defined in the C header file stdio.h, can be used to print out messages on
the screen. In this section, you're going to learn to use the character format specifier, %c, which indicates to the printf
() function that the argument to be printed is a character. Let's first have a look at the program in Listing 4.1, which
prints out characters on the screen.
TYPE
Listing 4.1. Printing out characters on the screen.
1: /* 04L01.c: Printing out characters */
Character Description
\b The backspace character; moves the cursor to the left one character.
\f The form-feed character; goes to the top of a new page.
\r The return character; returns to the beginning of the current line.
\t The tab character; advances to the next tab stop.
2: #include
3:
4: main()
5: {
6: char c1;
7: char c2;
8:
9: c1 = `A';
10: c2 = `a';
11: printf("Convert the value of c1 to character: %c.\n", c1);
12: printf("Convert the value of c2 to character: %c.\n", c2);
13: return 0;
14: }
OUTPUT
After the executable file of 04L01.c in Listing 4.1 is created, you can run it to see what will be printed
out on the screen. On my machine, the executable file is named as 04L01.exe. The following is the
output printed on the screen after I run the executable from a DOS prompt:
C:\app> 04L01
Convert the value of c1 to character: A.
Convert the value of c2 to character: a.
C:\app>
ANALYSIS
As you know, line 2 includes the header file, stdio.h, for the printf() function. Lines 5_14 make up the
main() function body.
Lines 6 and 7 declare two character variables, c1 and c2, while lines 9 and 10 assign c1 and c2 with the character
constants `A' and `a', respectively.
Note that the %c format specifier is used in the printf() function in lines 11 and 12, which tells the computer that the
contents contained by c1 and c2 should be printed as characters. When the two statements in lines 11 and 12 are
executed, two characters are formatted and output to the screen, based on the numeric values contained by c1 and c2,
respectively.
Now look at the program shown in Listing 4.2. This time, %c is used to convert the numeric values back to the
corresponding characters.
TYPE
Listing 4.2. Converting numeric values back to characters.
1: /* 04L02.c: Converting numeric values back to characters */
2: #include
3:
4: main()
5: {
6: char c1;
7: char c2;
8:
9: c1 = 65;
10: c2 = 97;
11: printf("The character that has the numeric value of 65 is: %c.\n", c1);
12: printf("The character that has the numeric value of 97 is: %c.\n", c2);
13: return 0;
14: }
OUTPUT
The following is the output printed on the screen after I run the executable file, 04L02.exe, from a DOS
prompt:
C:\app> 04L02
The character that has the numeric value of 65 is: A.
The character that has the numeric value of 97 is: a.
C:\app>
ANALYSIS
The program in Listing 4.2 is similar to the one in Listing 4.1 except for the two statements in lines 9 and
10. Note that in lines 9 and 10 of Listing 4.2, the character variables c1 and c2 are assigned 65 and 97,
respectively.
As you know, 65 is the numeric value (decimal) of the A character in the ASCII character set; 97 is the numeric value
of a. In lines 11 and 12, the %c format specifier converts the numeric values, 65 and 97, into the A and a,
respectively. The A and a characters are then printed out on the screen.
The int Data Type
You saw the integer data type in Hour 3. The int keyword is used to specify the type of a variable as an integer.
Integer numbers are also called whole numbers, which have no fractional part or decimal point. Therefore, the result
of an integer division is truncated, simply because any fraction part is ignored.
Depending on the operating system and the C compiler you're using, the length of an integer varies. On most UNIX
workstations, for example, an integer is 32 bits long, which means that the range of an integer is from 2147483647
(that is, 231_1) to -2147483648. The range of a 16-bit integer is from 32767 (that is, 215_1) to -32768.
The C compiler I'm using for this book is Visual C++ 1.5, which only provides the 16-bit integer, while a 32-bit
version of Visual C++, such as Visual C++ 4.0 or Visual C++ 5.0, supports the 32-bit integer.
Declaring Integer Variables
You also saw the declaration of an integer in Hour 3. The following shows the basic declaration format:
int variablename;
Similar to the character declaration, if you have more than one variable to declare, you can use either the format like
this
int variablename1;
int variablename2;
int variablename3;
or like this:
int variablename1, variablename2, variablename3;
Here variablename1, variablename2, and variablename3 indicate the places where you put the names of int variables.
Showing the Numeric Values of Characters
Like the character format specifier (%c) that is used to format a single character, %d, called the integer format
specifier, is used to format an integer. You might recall that in line 16 of Listing 3.2, %d is used in the printf()
function to format the second argument of the function to an integer.
In this section you're going to study a program, shown in Listing 4.3, that can print out the numeric values of
characters by using the integer format specifier %d with printf().
TYPE
Listing 4.3. Showing the numeric values of characters.
1: /* 04L03.c: Showing the numeric values of characters */
2: #include
3:
4: main()
5: {
6: char c1;
7: char c2;
8:
9: c1 = `A';
10: c2 = `a';
11: printf("The numeric value of A is: %d.\n", c1);
12: printf("The numeric value of a is: %d.\n", c2);
13: return 0;
14: }
OUTPUT
I get the following output on the screen after running the executable file, 04L03.exe:
C:\app> 04L03
The numeric value of A is: 65.
The numeric value of a is: 97.
C:\app>
ANALYSIS
You may find that the program in Listing 4.3 is quite similar to the one in Listing 4.1. As a matter of fact,
I simply copied the source code from Listing 4.1 to Listing 4.3 and made changes in lines 11 and 12. The
major change I made was to replace the character format specifier (%c) with the integer format specifier
(%d).
The two statements in lines 11 and 12 format the two character variables (c1 and c2) by using the integer format
specifier %d, and then print out two messages showing the numeric values 65 and 97 that represent, respectively, the
characters A and a in the ASCII character set.
The float Data Type
The floating-point number is another data type in the C language. Unlike an integer number, a floating-point number
contains a decimal point. For instance, 7.01 is a floating-point number; so are 5.71 and -3.14. A floating-point number
is also called a real number.
A floating-point number is specified by the float keyword in the C language. Floating-point numbers can be suffixed
with f or F to specify float. A floating-point number without a suffix is double by default. The double data type is
introduced later in this lesson.
Like an integer number, a floating-point number has a limited range. The ANSI standard requires that the range be at
least plus or minus 1.0*1037. Normally, a floating-point number is represented by taking 32 bits. Therefore, a
floating-point number in C is of at least six digits of precision. That is, for a floating-point number, there are at least
six digits (or decimal places) on the right side of the decimal point.
Not like an integer division from which the result is truncated and the fraction part is discarded, a floating-point
division produces another floating-point number. A floating-point division is carried out if both the divisor and the
dividend, or one of them, are floating-point numbers.
For instance, 571.2 / 10.0 produces another floating-point number, 57.12. So do 571.2 / 10 and 5712 / 10.0.
Declaring Floating-Point Variables
The following shows the declaration format for a floating-point variable:
float variablename;
Similar to the character or integer declaration, if you have more than one variable to declare, you can either use the
format like this:
float variablename1;
float variablename2;
float variablename3;
or like the following one:
float variablename1, variablename2, variablename3;
The Floating-Point Format Specifier (%f)
Also, in C, you can use the floating-point format specifier (%f) to format your output. Listing 4.4 gives an example
showing how to use the format specifier %f with the printf() function.
TYPE
Listing 4.4. Printing out results of integer and floating-point divisions.
1: /* 04L04.c: Integer vs. floating-point divisions */
2: #include
3:
4: main()
5: {
6: int int_num1, int_num2, int_num3; /* Declare integer variables */
7: float flt_num1, flt_num2, flt_num3; /* Declare floating-point variables */
8:
9: int_num1 = 32 / 10; /* Both divisor and dividend are integers */
10: flt_num1 = 32 / 10;
11: int_num2 = 32.0 / 10; /* The divisor is an integer */
12: flt_num2 = 32.0 / 10;
13: int_num3 = 32 / 10.0; /* The dividend is an integer */
14: flt_num3 = 32 / 10.0;
15:
16: printf("The integer divis. of 32/10 is: %d\n", int_num1);
17: printf("The floating-point divis. of 32/10 is: %f\n", flt_num1);
18: printf("The integer divis. of 32.0/10 is: %d\n", int_num2);
19: printf("The floating-point divis. of 32.0/10 is: %f\n", flt_num2);
20: printf("The integer divis. of 32/10.0 is: %d\n", int_num3);
21: printf("The floating-point divis. of 32/10.0 is: %f\n", flt_num3);
22: return 0;
23: }
OUTPUT
The following output is a copy from the screen after the executable file, 04L04.exe, is run on my
machine (I did get several warning messages about type conversions while I was compiling the program
in Listing 4.4, but I ignored them all because I'd like to create an executable file and show you the
differences between the int data type and the float data type.):
C:\app> 04L04
The integer divis. of 32/10 is: 3
The floating-point divis. of 32/10 is: 3.000000
The integer divis. of 32.0/10 is: 3
The floating-point divis. of 32.0/10 is: 3.200000
The integer divis. of 32/10.0 is: 3
The floating-point divis. of 32/10.0 is: 3.200000
C:\app>
ANALYSIS
Inside the main() function, the two statements in lines 6 and 7 declare three integer variables, int_num1,
int_num2, and int_num3, and three floating-point variables, flt_num1, flt_num2, and flt_num3.
Lines 9 and 10 assign the result of 32/10 to int_num1 and flt_num1, respectively; 32.0 / 10 to int_num2 and flt_num2
in lines 11 and 12, and 32 / 10.0 to int_num3 and flt_num3 in lines 13 and 14.
Then, lines 16_21 print out the values contained by the three int variables and the three floating-point variables. Note
that, %d is used for the integer variables, and the floating-point specifier (%f) is used for formatting the floating-point
variables in the printf() function.
Because the truncation occurs in the integer division of 32 / 10, flt_num1 contains 3.000000, not 3.200000, which you
can see from the second line of the output. However, flt_num2 and flt_num3 are assigned 3.200000, because both
32.0 / 10 and 32 / 10.0 are considered as the floating-point division.
But int_num2 and int_num3, as integer variables, discard respectively the fraction parts of the floating-point divisions
of 32.0 / 10 and 32 / 10.0. Therefore, you just see the integer 3 in both the third and fifth lines of the output.
The double Data Type
In the C language, a floating-point number can also be represented by another data type, called the double data type.
In other words, you can specify a variable by the double keyword, and assign the variable a floating-point number.
The difference between a double data type and a float data type is that the former normally uses twice as many bits as
the latter. Therefore, a double floating-point number is of at least 10 digits of precision, although the ANSI standard
does not specify it for the double data type.
In Hour 8, "More Operators," you'll learn to use the sizeof operator to obtain the length of a data type, such as char,
int, float, or double, specified on your computer system.
Using Scientific Notation
The C language uses scientific notation to help you write lengthy floating-point numbers.
In scientific notation, a number can be represented by the combination of the mantissa and the exponent. The format
of the notation is that the mantissa is followed by the exponent, which is prefixed by e or E. Here are two examples:
[mantissa]e[exponent],
and
[mantissa]E[exponent].
For instance, 5000 can be represented by 5e3 in scientific notation. Likewise, -300 can be represented by -3e2, and
0.0025 by 2.5e-3.
Correspondingly, the format specifier, %e or %E, is used to format a floating-point number in scientific notation. The
usage of %e or %E in the printf() function is the same as %f.
Naming a Variable
You've learned how to make a valid function name. In this section, let's focus on naming variables. Function names
and variable names are both identifiers in C.
The following are all the characters you can use to make a valid variable name:
 Characters A through Z and a through z.
 Digit characters 0 through 9, which can be used in any position except the first of a variable name.
 The underscore character (_).
For instance, stop_sign, Loop3, and _pause are all valid variable names.
Now, let's see what you cannot use in variable naming:
 A variable name cannot contain any C arithmetic signs.
 A variable name cannot contain any dots (.).
 A variable name cannot contain any apostrophes (`).
 A variable name cannot contain any other special symbols such as *, @, #, ?, and so on.
Some invalid variable names, for example, are, 4flags, sum-result, method*4, and what_size?.
Summary
In this lesson you've learned about the following:
 The C keywords reserved in the C language
 The char data type and the %c format specifier
 The int data type and the %d format specifier
 The float data type and the %f format specifier
 Floating-point numbers can be suffixed with f or F to specify float. A floating-point number without suffix is
double by default.
 The possible ranges of the char, int, and float data types
 The double data type
 Scientific notation and the %e and %E format specifiers
 The rules you have to follow to make a valid variable name
In the next lesson you'll learn more about the printf() function and other functions to deal with input and output.
Q&A
Q Why do characters have their unique numeric values?
A Characters are stored in computers in the form of bits. The combinations of bits can be used to
represent different numeric values. A character has to have a unique numeric value in order to distinguish
itself. Many computer systems support the ASCII character set, which contains a set of unique numeric
values for up to 256 characters.
Q How can you declare two character variables?
A There are two ways to do the declaration. The first one is
WARNING
Never use the C keywords reserved in the C language, or the names of the standard C library functions,
as variable names in your C program.
…char variable-name1, variable-name2;
char variable-name1;
char variable-name2;
Q What are %c, %d, and %f?
A These are format specifiers. %c is used to obtain the character format; %d is for the integer format; %f
is for the floating-point format. %c, %d, and %f are often used with C functions such as printf().
Q What are the main differences between the int data type (integer) and the float data type (floatingpoint)?
A First, an integer does not contain any fraction parts, but a floating-point number does. A floating-point
number must have a decimal point. In C, the float data type takes more bits than the int data type. In
other words, the float data type has a larger range of numeric values than the int data type. Also, the
integer division truncates the fraction part. For instance, the integer division of 16/10 produces a result of
1, not 1.6.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. Are the integer divisions of 134/100 and 17/10 equal?
2. Is the result of 3000 + 1.0 a floating-point number? How about 3000/1.0?
3. How can you represent the following numbers in scientific notation?
 3500
 0.0035
 -0.0035
4. Are the following variable names valid?
 7th_calculation
 Tom's_method
 _index
 Label_1
Exercises
1. Write a program that prints out the numeric values of characters Z and z.
2. Given two numeric values, 72 and 104, write a program to print out the corresponding two characters.
3. For a 16-bit integer variable, can you assign the variable with an integer value of 32768?
4. Given the declaration double dbl_num = 123.456;, write a program that prints out the value of dbl_num in both
floating-point and scientific notation formats.
5. Write a program that can print out the numeric value of the newline character (\n). (Hint: assign `\n' to a
character variable.)
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 5 - Reading from and Writing to Standard I/O
I/O, I/O, it's off to work we go…
–The Seven Dwarfs (sort of)
In the last lesson you learned how to print out characters, integers, and floating-point numbers to the screen by calling
the printf() function. In this lesson you're going to learn more about printf(), as well as about the following functions,
which are necessary to receive the input from the user or print the output to the screen:
 The getc() function
 The putc() function
 The getchar() function
 The putchar() function
Before we jump into these new functions, let's first get an idea about the standard input and output in C.
The Standard Input and Output (I/O)
A file contains related characters and numbers. Because all characters and numbers are represented in bits on
computers, the C language treats a file as a series of bytes. (8 bits make up 1 byte.) A series of bytes is also called a
stream. In fact, the C language treats all file streams equally, although some of the file streams may come from a disk
or tape drive, from a terminal, or even from a printer.
Additionally, in C, there are three file streams that are pre-opened for you:
 stdin–The standard input for reading.
 stdout–The standard output for writing.
 stderr–The standard error for writing error messages.
Usually, the standard input (stdin) file stream links to your keyboard, while the standard output (stdout) and the
standard error (stderr) file streams point to your terminal screen. Also, many operating systems allow you to redirect
these files' streams.
In fact, you've already used stdout. When you executed the printf() function in the last lesson, you were in fact
sending the output to the default file stream, stdout, which points to your screen.
You'll learn more on stdin and stdout in the following sections.
Getting the Input from the User
In these days, typing from keyboard is still the de facto standard way to input information into computers. The C
language has several functions to direct the computer to read the input from the user (typically through the keyboard.)
In this lesson the getc() and getchar() functions are introduced.
NOTE
The C language provides many functions to manipulate file reading and writing (I/O). The header file
stdio.h contains the declarations for those functions. Therefore, always include the header file stdio.h in
your C program before doing anything with the file I/O.
Using the getc() Function
The getc() function reads the next character from a file stream, and returns the character as an integer.
The syntax for the getc() function is
#include
int getc(FILE *stream);
Here FILE *stream declares a file stream (that is, a variable). The function returns the numeric value of the character
read. If an end-of-file or error occurs, the function returns EOF.
At this moment, don't worry about the FILE structure. More details about it are introduced in Hours 21, "Disk File
Input and Output: Part I," and 22, "Disk File Input and Output: Part II." In this section, the standard input stdin is used
as the file stream specified by FILE *stream.
Listing 5.1 shows an example that reads a character typed in by the user from the keyboard and then displays the
character on the screen.
TYPE
Listing 5.1. Reading in a character entered by the user.
1: /* 05L01.c: Reading input by calling getc() */
2: #include
3:
4: main()
5: {
6: int ch;
7:
8: printf("Please type in one character:\n");
9: ch = getc( stdin );
10: printf("The character you just entered is: %c\n", ch);
11: return 0;
12: }
The following is the output displayed on the screen after I run the executable file, 05L01.exe, enter the character H,
and press the Enter key:
C:\app> 05L01
Please type in one character:
NOTE
Defined in the header file stdio.h, EOF is a constant. EOF stands for end-of-file. Usually, the value of
EOF is -1. But keep using EOF, instead of -1, if you need an end-of-file indicator, in case a compiler
uses a different value.
H
The character you just entered is: H
C:\app>
OUTPUT
You see in line 2 of Listing 5.1 that the header file stdio.h is included for both the getc() and printf()
functions used in the program. Lines 4_12 give the name and body of the main() function.
ANALYSIS
In line 6, an integer variable, ch, is declared; it is assigned the return value from the getc() function later
in line 9. Line 8 prints out a piece of message that asks the user to enter one character from the keyboard.
As I mentioned earlier in this lesson, the printf() function in line 8 uses the default standard output stdout
to display messages on the screen.
In line 9, the standard input stdin is passed to the getc() function, which indicates that the file stream is from the
keyboard. After the user types in a character, the getc() function returns the numeric value (that is, an integer) of the
character. You see that, in line 9, the numeric value is assigned to the integer variable ch.
Then, in line 10, the character entered by the user is displayed on the screen with the help of printf(). Note that the
character format specifier (%c) is used within the printf() function in line 10. (Exercise 1 in this lesson asks you to
use %d in a program to print out the numeric value of a character entered by the user.)
Using the getchar() Function
The C language provides another function, getchar(), to perform a similar operation to getc(). More precisely, the
getchar() function is equivalent to getc(stdin).
The syntax for the getchar() function is
#include
int getchar(void);
Here void indicates that no argument is needed for calling the function. The function
returns the numeric value of the character read. If an end-of-file or error occurs, the function returns EOF.
The program in Listing 5.2 demonstrates how to use the getchar() function to read the input from the user.
TYPE
Listing 5.2. Reading in a character by calling getchar().
1: /* 05L02.c: Reading input by calling getchar() */
2: #include
3:
4: main()
5: {
6: int ch1, ch2;
7:
8: printf("Please type in two characters together:\n");
9: ch1 = getc( stdin );
10: ch2 = getchar( );
11: printf("The first character you just entered is: %c\n", ch1);
12: printf("The second character you just entered is: %c\n", ch2);
13: return 0;
14: }
OUTPUT
After running the executable file, 05L02.exe, and entering two characters (H and i) together without
spaces, I press the Enter key and the following output is displayed on the screen:
C:\app> 05L02
Please type in two characters together:
Hi
The first character you just entered is: H
The second character you just entered is: i
C:\app>
ANALYSIS
The program in Listing 5.2 is quite similar to the one in Listing 5.1, except that the former reads in two
characters.
The statement in line 6 declares two integers, ch1 and ch2. Line 8 displays a message asking the user to enter two
characters together.
Then, the getc() and getchar() functions are called in lines 9 and 10, respectively, to read in two characters entered by
the user. Note that in line 10, nothing is passed to the getchar() function. This is because, as mentioned earlier,
getchar() has its default file stream–stdin. You can replace the getchar() function in line 10 with getc(stdin), because
getc(stdin) is equivalent to getchar().
Lines 11 and 12 send two characters (kept by ch1 and ch2, respectively) to the screen.
Printing the Output on the Screen
Besides getc() and getchar() for reading, the C language also provides two functions, putc() and putchar(), for writing.
The following two sections introduce these functions.
Using the putc() Function
The putc() function writes a character to the specified file stream, which, in our case, is the standard output pointing
to your screen.
The syntax for the putc() function is
#include
int putc(int c, FILE *stream);
Here the first argument, int c, indicates that the output is a character saved in an integer variable c; the second
argument, FILE *stream, specifies a file stream. If successful, putc() returns the character written; otherwise, it
returns EOF.
In this lesson the standard output stdout is used to be the specified file stream in putc().
The putc() function is used in Listing 5.3 to put the character A on the screen.
TYPE
Listing 5.3. Putting a character on the screen.
1: /* 05L03.c: Outputting a character with putc() */
2: #include
3:
4: main()
5: {
6: int ch;
7:
8: ch = 65; /* the numeric value of A */
9: printf("The character that has numeric value of 65 is:\n");
10: putc(ch, stdout);
11: return 0;
12: }
OUTPUT
The following is what I get from my machine:
C:\app> 05L03
The character that has numeric value of 65 is:
A
C:\app>
ANALYSIS
As mentioned, the header file stdio.h, containing the declaration of putc(), is included in line 2.
The integer variable, ch, declared in line 6, is assigned the numeric value of 65 in line 8. You may remember that 65
is the numeric value of character A.
Line 9 displays a message to remind the user of the numeric value of the character that is going to be put on the
screen. Then, the putc() function in line 10 puts character A on the screen. Note that the first argument to the putc()
function is the integer variable (ch) that contains 65, and the second argument is the standard output file stream,
stdout.
Another Function for Writing: putchar()
Like putc(), putchar() can also be used to put a character on the screen. The only difference between the two functions
is that putchar() needs only one argument to contain the character. You don't need to specify the file stream, because
the standard output (stdout) is the default file stream to putchar().
The syntax for the putchar() function is
#include
int putchar(int c);
Here int c is the argument that contains the numeric value of a character. The function returns EOF if an error occurs;
otherwise, it returns the character that has been written.
An example of using putchar() is demonstrated in Listing 5.4.
TYPE
Listing 5.4. Outputting characters with putchar().
1: /* 05L04.c: Outputting characters with putchar() */
2: #include
3:
4: main()
5: {
6: putchar(65);
7: putchar(10);
8: putchar(66);
9: putchar(10);
10: putchar(67);
11: putchar(10);
12: return 0;
13: }
OUTPUT
After running the executable file, 05L04.exe, I get the following output:
C:\app> 05L04
A
B
C
C:\app>
ANALYSIS
The way to write the program in Listing 5.4 is a little bit different. There is no variable declared in the
program. Rather, integers are passed to putchar() directly, as shown in lines 6_11.
As you might have figured out, 65, 66, and 67 are, respectively, the numeric values of characters A, B, and C. From
exercise 5 of Hour 4, "Data Types and Names in C," or from Appendix C, "ASCII Character Set," you can find out
that 10 is the numeric value of the newline character (\n).
Therefore, respectively, lines 6 and 7 put character A on the screen and cause the computer to start at the beginning of
the next line. Likewise, line 8 puts B on the screen, and line 9 starts a new line. Then, line 10 puts C on the screen,
and line 11 starts another new line. Accordingly, A, B, and C, are put at the beginnings of three consecutive lines, as
shown in the output section.
Revisiting the printf() Function
The printf() function is the first C library function you used in this book to print out messages on the screen. printf() is
a very important function in C, so it's worth it to spend more time on it.
The syntax for the printf() function is
#include
int printf(const char *format-string, ...);
Here const char *format-string is the first argument that contains the format specifier(s); ... indicates the expression
section that contains the expression(s) to be formatted according to the format specifiers. The number of expressions
is determined by the number of the format specifiers inside the first argument. The function returns the numbers of
expressions formatted if it succeeds. It returns a negative value if an error occurs.
const char * is explained later in this book. For the time being, consider the first argument to the printf() function as a
series of characters surrounded with double quotes with some format specifiers inside. For instance, you can pass
"The sum of two integers %d + %d is: %d.\n" to the function as the first argument, if needed.
Figure 5.1 shows the relationship between the format string and expressions. Note that the format specifiers and the
expressions are matched in order from left to right.
Figure 5.1. The relation between the format string and the expressions in printf().
Please remember that you should use exactly the same number of expressions as the number of format specifiers
within the format string.
The following are all the format specifiers that can be used in printf():
%c The character format specifier.
%d The integer format specifier.
%i The integer format specifier (same as %d).
Among the format specifiers in this list, %c, %d, %f, %e, and %E have been introduced so far. Several others are
explained later in this book. The next section shows you how to convert decimal numbers to hexadecimal numbers by
using %x or %X.
Converting to Hex Numbers
The difference between a decimal number and a hexadecimal number is that the hexadecimal is a base-16 numbering
system. A hexadecimal number can be represented by four bits. (24 is equal to 16, which means four bits can produce
16 unique numbers.) Hexadecimal is often written as hex for short.
The hexadecimal numbers 0 through 9 use the same numeric symbols founded in the decimal numbers 0 through 9.
uppercase A, B, C, D, E, and F are used to represent, respectively, the hexadecimal numbers 10 through 15.
(Similarly, in lowercase, a, b, c, d, e, and f are used to represent these hex numbers.)
Listing 5.5 provides an example of converting decimal numbers to hex numbers by using %x or %X in the printf()
function.
TYPE
Listing 5.5. Converting to hex numbers.
1: /* 05L05.c: Converting to hex numbers */
2: #include
3:
4: main()
5: {
6: printf("Hex(uppercase) Hex(lowercase) Decimal\n");
7: printf("%X %x %d\n", 0, 0, 0);
8: printf("%X %x %d\n", 1, 1, 1);
9: printf("%X %x %d\n", 2, 2, 2);
10: printf("%X %x %d\n", 3, 3, 3);
11: printf("%X %x %d\n", 4, 4, 4);
%f The floating-point format specifier.
%e The scientific notation format specifier (note the lowercase e).
%E The scientific notation format specifier (note the uppercase E).
%g Uses %f or %e, whichever result is shorter.
%G Uses %f or %E, whichever result is shorter.
%o The unsigned octal format specifier.
%s The string format specifier.
%u The unsigned integer format specifier.
%x The unsigned hexadecimal format specifier (note the lowercase x).
%X The unsigned hexadecimal format specifier (note the uppercase X).
%p Displays the corresponding argument that is a pointer.
%n Records the number of characters written so far.
%% Outputs a percent sign (%).
12: printf("%X %x %d\n", 5, 5, 5);
13: printf("%X %x %d\n", 6, 6, 6);
14: printf("%X %x %d\n", 7, 7, 7);
15: printf("%X %x %d\n", 8, 8, 8);
16: printf("%X %x %d\n", 9, 9, 9);
17: printf("%X %x %d\n", 10, 10, 10);
18: printf("%X %x %d\n", 11, 11, 11);
19: printf("%X %x %d\n", 12, 12, 12);
20: printf("%X %x %d\n", 13, 13, 13);
21: printf("%X %x %d\n", 14, 14, 14);
22: printf("%X %x %d\n", 15, 15, 15);
23: return 0;
24: }
OUTPUT
The following output is obtained by running the executable file, 05L05.exe, on my machine:
C:\app> 05L05
Hex(uppercase) Hex(lowercase) Decimal
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
A a 10
B b 11
C c 12
D d 13
E e 14
F f 15
C:\app>
ANALYSIS
Don't panic when you see so many printf() functions being used in Listing 5.5. In fact, the program in
Listing 5.5 is very simple. The program has just one function body from lines 5_23.
The printf() function in line 6 prints out a headline that contains three fields: Hex(uppercase), Hex(lowercase), and
Decimal.
Then, lines 7_22 print out the hex and decimal numbers 0 through 15. Sixteen printf() functions are called to
accomplish the job. Each of the printf() functions has a format string as the first argument followed by three integers
as three expressions. Note that the hex format specifiers %X and %x are used within the format string in each of the
printf() functions to convert the corresponding expressions to the hex format (both uppercase and lowercase).
In reality, nobody would write a program like the one in Listing 5.5. Instead, a loop can be used to call the printf()
function repeatedly. Looping (or iteration) is introduced in Hour 7, "Doing the Same Thing Over and Over."
Adding the Minimum Field Width
The C language allows you to add an integer between the percent sign (%) and the letter in a format specifier. The
integer is called the minimum field width specifier because it specifies the minimum field width and ensures that the
output reaches the minimum width. For example, in %10f, 10 is a minimum field width specifier that ensures that the
output is at least 10 character spaces wide.
The example in Listing 5.6 shows how to use the minimum field width specifier.
TYPE
Listing 5.6. Specifying the minimum field width.
1: /* 05L06.c: Specifying minimum field width */
2: #include
3:
4: main()
5: {
6: int num1, num2;
7:
8: num1 = 12;
9: num2 = 12345;
10: printf("%d\n", num1);
11: printf("%d\n", num2);
12: printf("%5d\n", num1);
13: printf("%05d\n", num1);
14: printf("%2d\n", num2);
15: return 0;
16: }
OUTPUT
The following is the result I obtain by running the executable file 05L06.exe:
C:\app> 05L06
12
12345
12
00012
12345
C:\app>
ANALYSIS
In Listing 5.6, two integer variables, num1 and num2, are declared in line 6, and assigned 12 and 12345,
respectively, in lines 8 and 9.
Without using any minimum field width specifiers, lines 10 and 11 print out the two integers by calling the printf()
function. You can see in the output section that the output made by the statements in line 10 is 12, which takes two
character spaces, while the output, 12345, from line 11 takes five character spaces.
In line 12, a minimum field width, 5, is specified by %5d. The output from line 12 therefore takes five character
spaces, with three blank spaces plus two character spaces of 12. (See the third output line in the output section.)
The %05d in printf(), shown in line 13, indicates that the minimum field width is 5, and zeros are used to pad the
spaces. Therefore, you see the output made by the execution of the statement in line 13 is
00012
The %2d in line 14 sets the minimum field width to 2, but you still see the full-size output of 12345 from line 14.
This means that when the minimum field width is shorter than the width of the output, the latter is taken, and the
output is still printed in full.
Aligning Output
As you might have noticed in the previous section, all output is right-justified. In other words, by default, all output is
placed on the right edge of the field, as long as the field width is longer than the width of the output.
You can change this and force output to be left-justified. To do so, you need to prefix the minimum field specifier
with the minus sign (-). For example, %-12d specifies the minimum field width as 12, and justifies the output from
the left edge of the field.
Listing 5.7 gives an example of aligning output by left- or right-justification.
TYPE
Listing 5.7. Left- or right-justified output.
1: /* 05L07.c: Aligning output */
2: #include
3:
4: main()
5: {
6: int num1, num2, num3, num4, num5;
7:
8: num1 = 1;
9: num2 = 12;
10: num3 = 123;
11: num4 = 1234;
12: num5 = 12345;
13: printf("%8d %-8d\n", num1, num1);
14: printf("%8d %-8d\n", num2, num2);
15: printf("%8d %-8d\n", num3, num3);
16: printf("%8d %-8d\n", num4, num4);
17: printf("%8d %-8d\n", num5, num5);
18: return 0;
19: }
OUTPUT
I get the following output displayed on the screen after I run the executable 05L07.exe from a DOS
prompt on my machine:
C:\app> 05L07
1 1
12 12
123 123
1234 1234
12345 12345
C:\app>
ANALYSIS
In Listing 5.7, there are five integer variables, num1, num2, num3, num4, and num5, that are declared in
line 6 and are assigned values in lines 8_12.
These values represented by the five integer variables are then printed out by the printf() functions in lines 13_17.
Note that all the printf() functions have the same first argument: "%8d %-8d\n". Here the first format specifier, %8d,
aligns the output at the right edge of the field, and the second specifier, %-8d, does the alignment by justifying the
output from the left edge of the field.
After the execution of the statements in lines 13_17, the alignment is accomplished and the output is put on the screen
like this:
1 1
12 12
123 123
1234 1234
12345 12345
Using the Precision Specifier
You can put a period (.) and an integer right after the minimum field width specifier. The combination of the period
(.) and the integer makes up a precision specifier. The precision specifier is another important specifier you can use to
determine the number of decimal places for floating-point numbers, or to specify the maximum field width (or length)
for integers or strings. (Strings in C are introduced in Hour 13, "Manipulating Strings.")
For instance, with %10.3f, the minimum field width length is specified as 10 characters long, and the number of
decimal places is set to 3. (Remember, the default number of decimal places is 6.) For integers, %3.8d indicates that
the minimum field width is 3, and the maximum field width is 8.
Listing 5.8 gives an example of left- or right-justifying output by using precision specifiers.
TYPE
Listing 5.8. Using precision specifiers.
1: /* 05L08.c: Using precision specifiers */
2: #include
3:
4: main()
5: {
6: int int_num;
7: double flt_num;
8:
9: int_num = 123;
10: flt_num = 123.456789;
11: printf("Default integer format: %d\n", int_num);
12: printf("With precision specifier: %2.8d\n", int_num);
13: printf("Default float format: %f\n", flt_num);
14: printf("With precision specifier: %-10.2f\n", flt_num);
15: return 0;
16: }
OUTPUT
After running the executable file 05L08.exe on my machine, I get the following output on the screen:
C:\app> 05L08
Default integer format: 123
With precision specifier: 00000123
Default float format: 123.456789
With precision specifier: 123.46
C:\app>
ANALYSIS
The program in Listing 5.8 declares one integer variable, int_num, in line 6, and one floating-point
number, flt_num, in line 7. Lines 9 and 10 assign 123 and 123.456789 to int_num and flt_num,
respectively.
In line 11, the default integer format is specified for the integer variable, int_num, while the statement in line 12
specifies the integer format with a precision specifier that indicates that the maximum field width is 8 characters long.
Therefore, you see that five zeros are padded prior to the integer 123 in the second line of the output.
For the floating-point variable, flt_num, line 13 prints out the floating-point value in the default format, and line 14
reduces the decimal places to two by putting the precision specifier .2 within the format specifier %-10.2f. Note here
that the left-justification is also specified by the minus sign (-) in the floating-point format specifier.
The floating-point number 123.46 in the fourth line of the output is produced by the statement in line 14 with the
precision specifier for two decimal places. Therefore, 123.456789 rounded to two decimal places becomes 123.46.
Summary
In this lesson you've learned the following:
 The C language treats a file as a series of bytes.
 stdin, stdout, and stderr are three file streams that are pre-opened for you to use.
 The C library functions getc() and getchar() can be used to read in one character from the standard input.
 The C library functions putc() and putchar() can be used to write one character to the standard output.
 %x or %X can be used to convert decimal numbers to hex numbers.
 A minimum field width can be specified and ensured by adding an integer into a format specifier.
 An output can be aligned at either the left or right edge of the output field.
 A precision specifier can be used to specify the decimal place number for floating-point numbers, or the
maximum field width for integers or strings.
In the next lesson you'll learn about some important operators in C.
Q&A
Q What are stdin, stdout, and stderr?
A In C, a file is treated as a series of bytes that is called file stream. stdin, stdout, and stderr are all preopened
file streams. stdin is the standard input for reading; stdout is the standard output for writing;
stderr is the standard error for outputting error messages.
Q How much is the hex number 32?
A Hexadecimal, or hex for short, is a base-16 numerical system. Therefore, 32 (hex) is equal to
3*161+2*160, or 50 in decimal.
Q Are getc(stdin) and getchar() equivalent?
A Because the getchar() function reads from the file stream stdin by default, getc(stdin) and getchar() are
equivalent.
Q In the function printf("The integer %d is the same as the hex %x", 12, 12), what is the relationship
between the format specifiers and the expressions?
A The two format specifiers, %d and %x, specify the formats of numeric values contained in the
expression section. Here the first numeric value of 12 is going to be printed out in integer format, while
the second 12 (in the expression section) will be displayed in the hex format. Generally speaking, the
number of format specifiers in the format section should match the number of expressions in the
expression section.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. Can you align your output at the left edge, rather than the right edge, of the output field?
2. What is the difference between putc() and putchar()?
3. What does getchar() return?
4. Within %10.3f, which part is the minimum field width specifier, and which one is the precision specifier?
Exercises
1. Write a program to put the characters B, y, and e together on the screen.
2. Display the two numbers 123 and 123.456 and align them at the left edge of the field.
3. Given three integers–15, 150, and 1500–write a program that prints the integers on the screen in the hex format.
4. Write a program that uses getchar() and putchar() to read in a character entered by the user and write the
character to the screen.
5. If you compile the following C program, what warning or error messages will you get?
main()
{
int ch;
ch = getchar();
putchar(ch);
return 0;
}
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 6 - Manipulating Data with Operators
"The question is," said Humpty Dumpty, "which is to be master—that's all."
—L. Carroll
You can think of operators as verbs in C that let you manipulate data. In fact, you've learned some operators, such as
+ (addition), - (subtraction), * (multiplication), / (division), and % (remainder), in Hour 3, "The Essentials of C
Programs." The C language has a rich set of operators. In this hour, you'll learn about more operators, such as
 Arithmetic assignment operators
 Unary minus operators
 Increment and decrement operators
 Relational operators
 Cast operator
Arithmetic Assignment Operators
Before jumping into the arithmetic assignment operators, you first need to learn more about the assignment operator.
The Assignment Operator (=)
In the C language, the = operator is called an assignment operator, which you've seen and used for several hours.
The general statement form to use an assignment operator is
left-hand-operand = right-hand-operand;
Here the statement causes the value of the right-hand-operand to be assigned (or written) to the memory location of
the left-hand-operand. Additionally, the assignment statement itself returns the same value that is assigned to the lefthand-
operand.
For example, the a = 5; statement writes the value of the right-hand operand (5) into the memory location of the
integer variable a (which is the left-hand operand in this case).
Similarly, the b = a = 5; statement assigns 5 to the integer variable a first, and then to the integer variable b. After the
execution of the statement, both a and b contain the value of 5.
Combining Arithmetic Operators with =
Consider this example: Given two integer variables, x and y, how do you assign the sum of x and y to another integer
variable, z?
By using the assignment operator (=) and the addition operator (+), you get the following statement:
WARNING
Don't confuse the assignment operator (=) with the relational operator, == (called the equal-to operator).
The == operator is introduced later in this hour.
z = x + y;
As you can see, it's pretty simple. Now, consider the same example again. This time, instead of assigning the result to
the third variable, z, let's write the sum back to the integer variable, x:
x = x + y;
Here, on the right side of the assignment operator (=), the addition of x and y is executed; on the left side of =, the
previous value saved by x is replaced with the result of the addition from the right side.
The C language gives you a new operator, +=, to do the addition and the assignment together. Therefore, you can
rewrite the x = x + y; statement to
x += y;
The combinations of the assignment operator (=) with the arithmetic operators, +, -, *, /, and %, give you another type
of operators—arithmetic assignment operators:
The following shows the equivalence of statements:
x += y; is equivalent to x = x + y;
x -= y; is equivalent to x = x - y;
x *= y; is equivalent to x = x * y;
x /= y; is equivalent to x = x / y;
x %= y; is equivalent to x = x % y;
Note that the statement
z = z * x + y;
is not equivalent to the statement
z *= x + y;
because
z *= x + y
is indeed the same as
z = z * (x + y);
Listing 6.1 gives an example of using some of the arithmetic assignment operators.
TYPE
Listing 6.1. Using arithmetic assignment operators.
Operator Description
+= Addition assignment operator
-= Subtraction assignment operator
*= Multiplication assignment operator
/= Division assignment operator
%= Remainder assignment operator
1: /* 06L01.c: Using arithmetic assignment operators */
2: #include
3:
4: main()
5: {
6: int x, y, z;
7:
8: x = 1; /* initialize x */
9: y = 3; /* initialize y */
10: z = 10; /* initialize z */
11: printf("Given x = %d, y = %d, and z = %d,\n", x, y, z);
12:
13: x = x + y;
14: printf("x = x + y assigns %d to x;\n", x);
15:
16: x = 1; /* reset x */
17: x += y;
18: printf("x += y assigns %d to x;\n", x);
19:
20: x = 1; /* reset x */
21: z = z * x + y;
22: printf("z = z * x + y assigns %d to z;\n", z);
23:
24: z = 10; /* reset z */
25: z = z * (x + y);
26: printf("z = z * (x + y) assigns %d to z;\n", z);
27:
28: z = 10; /* reset z */
29: z *= x + y;
30: printf("z *= x + y assigns %d to z.\n", z);
31:
32: return 0;
33: }
OUTPUT
After this program is compiled and linked, an executable file is created. On my machine, this executable
file is named as 06L01.exe. The following is the output printed on the screen after I run the executable
from a DOS prompt:
C:\app> 06L01
Given x = 1, y = 3, and z = 10,
x = x + y assigns 4 to x;
x += y assigns 4 to x;
z = z * x + y assigns 13 to z;
z = z * (x + y) assigns 40 to z;
z *= x + y assigns 40 to z.
C:\app>
ANALYSIS
Line 2 in Listing 6.1 includes the header file stdio.h by using the include directive in C. The stdio.h
header file is needed for the printf() function used in the main() function body in lines 4_33.
Lines 8_10 initialize three integer variables, x, y, and z, which are declared in line 6. Line 11 then prints out the initial
values assigned to x, y, and z.
The statement in line 13 uses the one addition operator and one assignment operator to add the values contained by x
and y, and then assigns the result to x. Line 14 displays the result on the screen.
Similarly, lines 17 and 18 do the same addition and display the result again, after the variable x is reset in line 16.
This time, the arithmetic assignment operator, +=, is used. Also, line 16 in Listing 6.1 resets the value of x to 1,
before the addition.
The value of x is reset again in line 20. Line 21 performs a multiplication and an addition and saves the result to the
integer variable z; that is, z = z * x + y;. The printf() function in line 22 displays the result, 13, on the screen. Again,
the x = 1; statement in line 20 resets the integer variable, x.
Lines 24_30 display two results from two computations. The two results are actually the same (that is, 40), because
the two computations in lines 25 and 29 are equivalent. The only difference between the two statements in lines 25
and 29 is that the arithmetic assignment operator, *=, is used in line 29.
Getting Negations of Numeric Numbers
If you want to change the sign of a numeric number, you can put the minus operator (-) right before the number. For
instance, given an integer of 7, you can get its negation by changing the sign of the integer like this: -7. Here, - is the
minus operator.
Precisely, - is called the unary minus operator in C. This is because the operator takes only one operand. The type of
the operand can be any integer or floating-point number.
You can apply the unary minus operator to an integer or a floating-point variable as well. For example, given x =
1.234, -x equals -1.234. Or, given x = -1.234, -x equals 1.234.
Incrementing or Decrementing by One
The increment and decrement operators are very handy to use when you want to add or subtract 1 from a variable.
The symbol for the increment operator is ++. The decrement operator is --.
For instance, you can rewrite the statement x = x + 1; as ++x;, or you can replace x = x 1; with --x;.
Actually, there are two versions of the increment operator and of the decrement operator. In the ++x; statement, the
increment operator is called the pre-increment operator, because the operator adds 1 to x first and then gets the value
of x. Likewise, in the --x; statement, the pre-decrement operator first subtracts 1 from x and then gets the value of x.
If you have an expression like x++, you're using the post-increment operator. Similarly, in x--, the decrement operator
is called the post-decrement operator.
For example, in the y = x++; statement, y is assigned the original value of x, not the one after x is increased by 1. In
other words, the post-increment operator makes a copy of the original value of x and stores the copy in a temporary
location. Then, x is increased by 1. However, instead of the modified value of x, the copy of the unmodified value of
WARNING
Don't confuse the unary minus operator with the subtraction operator, although both operators use the
same symbol. For instance, the following statement:
z = x - -y;
z = x - (-y);
or this one:
z = x + y;
Here, in both statements, the first - symbol is used as the subtraction operator, while the second - symbol
is the unary minus operator.
x is returned and assigned to y.
The post-decrement operator has a similar story. This operator returns a copy of the original value of a variable, rather
than the current value of the variable (which has been decreased by 1).
The program in Listing 6.2 shows the differences between the two versions of increment operators and decrement
operators.
TYPE
Listing 6.2. Using pre- or post-increment and decrement operators.
1: /* 06L02.c: pre- or post-increment(decrement) operators */
2: #include
3:
4: main()
5: {
6: int w, x, y, z, result;
7:
8: w = x = y = z = 1; /* initialize x and y */
9: printf("Given w = %d, x = %d, y = %d, and z = %d,\n", w, x, y, z);
10:
11: result = ++w;
12: printf("++w gives: %d\n", result);
13: result = x++;
14: printf("x++ gives: %d\n", result);
15: result = --y;
16: printf("--y gives: %d\n", result);
17: result = z--;
18: printf("z-- gives: %d\n", result);
19: return 0;
20: }
OUTPUT
The following result is obtained by running the executable file 06L02.exe:
C:\app> 06L02
Given w = 1, x = 1, y = 1, and z = 1,
++w gives: 2
x++ gives: 1
--y gives: 0
z-- gives: 1
C:\app>
ANALYSIS
Inside the main() function, line 8 in Listing 6.2 assigns 1 to each of the integer variables, w, x, y, and z.
The printf() function in line 9 displays the values contained by the four integer variables.
Then, the statement in line 11 is executed and the result of the pre-increment of w is given to the integer variable
result. In line 12, the value of result, which is 2, is printed out to the screen.
Lines 13 and 14 get the post-increment of x and print out the result. As you know, the result is obtained before the
value of x is increased. Therefore, you see the numeric value 1 from the result of x++ on the screen.
The pre-decrement operator in line 15 causes the value of y to be reduced by 1 before the value is assigned to the
integer variable result. Therefore, you see 0 as the result of --y shown on the screen.
In line 17, however, the post-decrement operator has no effect on the assignment because the original value of z is
given to the integer variable result before z is decreased by 1. Line 18 thus prints out 1, which is the original value of
z.
Greater Than or Less Than?
There are six types of relationships between two expressions: equal to, not equal to, greater than, less than, greater
than or equal to, and less than or equal to. Accordingly, the C language provides six relational operators:
continues
All the relational operators have lower precedence than the arithmetic operators. Therefore, all arithmetic operations
are carried out before any comparison is made. You should use parentheses to enclose operations of operators that
have to be performed first.
Among the six operators, the >, <, >=, and <= operators have higher precedence than the == and != operators. For example, the expression x * y < x =" 3" y =" 5,">
3:
4: main()
5: {
6: int x, y;
7: double z;
8:
9: x = 7;
10: y = 25;
11: z = 24.46;
12: printf("Given x = %d, y = %d, and z = %.2f,\n", x, y, z);
13: printf("x >= y produces: %d\n", x >= y);
14: printf("x == y produces: %d\n", x == y);
Operator Description
== Equal to
!= Not equal to
> Greater than
Operator Description
<>= Greater than or equal to
<= Less than or equal to 15: printf("x <> z produces: %d\n", y > z);
17: printf("x != y - 18 produces: %d\n", x != y - 18);
18: printf("x + y != z produces: %d\n", x + y != z);
19: return 0;
20: }
OUTPUT
After the executable 06L03.exe is executed from a DOS prompt, the following output is displayed on the
screen:
C:\app> 06L03
Given x = 7, y = 25, and z = 24.46,
x >= y produces: 0
x == y produces: 0
x <> z produces: 1
x != y - 18 produces: 0
x + y != z produces: 1
C:\app>
ANALYSIS
There are two integer variables, x and y, and one floating-point variable z, declared in lines 6 and 7,
respectively.
Lines 9_11 initialize the three variables. Line 12 prints out the values assigned to the variables.
Because the value of x is 7 and the value of y is 25, y is greater than x. Therefore, line 13 prints out 0, which is
returned from the relational expression, x >= y.
Likewise, in line 14, the relational expression x == y returns 0.
Lines 15 and 16, however, print out the result of 1, returned from either x <> z.
The statement in line 17 displays 0, which is the result of the relational expression x != y --18. In line 18, the
expression x + y != z produces 1, which is output on the screen.
WARNING
Be careful when you compare two values for equality. Because of the truncation, or rounding up, some
relational expressions, which are algebraically true, may return 0 instead of 1. For example, look at the
following relational expression:
1 / 2 + 1 / 2 == 1
this is algebraically true and is supposed to return
The expression, however, returns 0, which means that the equal-to relationship does not hold. This is
because the truncation of the integer division—that is, 1 / 2—produces 0, not 0.5.
Another example is 1.0 / 3.0, which produces 0.33333.... This is a number with an infinite number of
decimal places. But the computer can only hold a limited number of decimal places. Therefore, the
expression
1.0 / 3.0 + 1.0 / 3.0 + 1.0 / 3.0 == 1.0
might not return 1 on some computers, although the expression is theoretically true.
Playing with the Cast Operator
In C, you can convert one data type to a different one by prefixing the cast operator to the operand.
The general form of the cast operator is
(data-type)x
Here data-type specifies the data type you want to convert to. x is a variable (or, expression) that contains the value of
the current data type. You have to include the parentheses ( and ) to make up a cast operator.
For example, the (float)5 expression converts the integer 5 to a floating-point number, 5.0.
The program in Listing 6.4 shows another example of using the cast operator.
TYPE
Listing 6.4. Using the cast operator.
1: /* 06L04.c: Using the cast operator */
2: #include
3:
4: main()
5: {
6: int x, y;
7:
8: x = 7;
9: y = 5;
10: printf("Given x = %d, y = %d\n", x, y);
11: printf("x / y produces: %d\n", x / y);
12: printf("(float)x / y produces: %f\n", (float)x / y);
13: return 0;
14: }
OUTPUT
The following output is obtained by running the executable 06L04.exe from a DOS prompt:
C:\app> 06L04
Given x = 7, y = 5
x / y produces: 1
(float)x / y produces: 1.400000
C:\app>
ANALYSIS
In Listing 6.4, there are two integer variables, x and y, declared in line 6, and initialized in lines 8 and 9,
respectively. Line 10 then displays the values contained by the integer variables x and y.
The statement in line 11 prints out the integer division of x/y. Because the fractional part is truncated, the result of the
integer division is 1.
However, in line 12, the cast operator (float) converts the value of x to a floating-point value. Therefore, the (float)x/y
expression becomes a floating-point division that returns a floating-point number. That's why you see the floatingpoint
number 1.400000 shown on the screen after the statement in line 12 is executed.
Summary
In this lesson you've learned about the following:
 The assignment operator (=), which has two operands on each side. The value of the right-side operand is
assigned to the operand on the left side.
 The arithmetic assignment operators, +=, -=, *=, /=, and %=, which are the combinations of the arithmetic
operators with the assignment operator.
 The unary minus operator (-), which returns the negation of a numeric value.
 The two versions of the increment operator, ++. You know that in ++x, the ++ operator is called the preincrement
operator; and in x++, ++ is the post-increment operator.
 The two versions of decrement operator, --. You have learned that, for example, in --x, the -- operator is the
pre-decrement operator, while in x--, -- is called the post-decrement operator.
 The six relational operators in C: == (equal to), != (not equal to), > (greater than), < (less than), >= (greater
than or equal to), and <= (less than or equal to).  How to change the type of data by prefixing a cast operator to the data. In the next lesson you'll learn about loops in the C language. Q&A Q What is the difference between the pre-increment operator and the post-increment operator? A The pre-increment operator increases the operand's value by 1 first, and then returns the modified value. On the other hand, the post-increment operator stores a copy of the operand value in a temporary location and then increases the operand value by 1. However, the copy of the unmodified operand value is returned in the expression. For instance, given x = 1, the ++x expression returns 2, while the x++ expression returns 1. Q Is the unary minus operator (-) the same as the subtraction operator (-)? A No, they are not the same, although the two operators share the same symbol. The unary minus operator is used to change the sign of a value. In other words, the unary minus operator returns the negation of the value. The subtraction operator is an arithmetic operator that performs subtraction between its two operands. Q Which one has a higher precedence, a relational operator or an arithmetic operator? A An arithmetic operator has a higher precedence than a relational operator. For instance, the x * y + z >
x + y expression is interpreted as ((x * y) + z) > (x + y).
Q What does a relational expression return?
A A relational expression returns either 0 or 1. If the relationship indicated by a relational operator in an
expression is true, the expression returns 1; otherwise, the expression returns 0.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. What is the difference between the = operator and the == operator?
2. In the x + - y - - z expression, which operator is the subtraction operator, and which one is the unary minus
operator?
3. Given x = 15 and y = 4, what do the x / y and (float)x / y expressions return, respectively?
4. Is the y *= x + 5 expression equivalent to the y = y * x + 5 expression?
Exercises
1. Given x = 1 and y = 3, write a program to print out the results of these expressions: x += y, x += -y, x -= y, x -=
-y, x *= y, and x *= -y.
2. Given x = 3 and y = 6, what is the value of z after the expression
z = x * y == 18 is executed?
3. Write a program that initializes the integer variable x with 1 and outputs results with the following two
statements:
printf("x++ produces: %d\n", x++);
printf("Now x contains: %d\n", x);
4. Rewrite the program you wrote in exercise 3. This time, include the following two statements:
printf("x = x++ produces: %d\n", x = x++);
printf("Now x contains: %d\n", x);
What do you get after running the executable of the program? Can you explain why you get such a result?
5. The following program is supposed to compare the two variables, x and y, for equality. What's wrong with the
program? (Hint: Run the program to see what it prints out.)
#include
main()
{
int x, y;
x = y = 0;
printf("The comparison result is: %d\n", x = y);
return 0;
}
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 7 - Doing the Same Thing Over and Over
Heaven and earth:
Unheard sutra chanting
Repeated…
—Zen saying
In the previous lessons, you've learned the basics of the C program, several important C functions, standard I/O, and
some useful operators. In this lesson you'll learn a very important feature of the C language—looping. Looping, also
called iteration, is used in programming to perform the same set of statements over and over until certain specified
conditions are met.
Three statements in C are designed for looping:
 The for statement
 The while statement
 The do-while statement
The following sections explore these statements.
Looping Under the for Statement
The general form of the for statement is
for (expression1; expression2; expression3) {
statement1;
statement2;
.
.
.
}
You see from this example that the for statement uses three expressions (expression1, expression2, and expression3)
that are separated by semicolons.
Several statements, such as statement1 and statement2, are placed within the braces ({ and }). All the statements and
the braces form a statement block that is treated as a single statement. (You learned about this in Hour 3, "The
Essentials of C Programs.")
In the preceding for statement format, the beginning brace ({) is put on the same line of the for keyword. You can
place the beginning brace on a separate line beneath the for keyword.
The for statement first evaluates expression1, which usually initializes one or more variables. In other words,
expression1 is only evaluated once when the for statement is first encountered.
The second expression, expression2, is the conditional part that is evaluated right after the evaluation of expression1
and then is evaluated after each successful looping by the for statement. If expression2 returns a nonzero value, the
statements within the braces are executed. Usually, the nonzero value is 1. If expression2 returns 0, the looping is
stopped and the execution of the for statement is finished.
The third expression in the for statement, expression3, is not evaluated when the for statement is first encountered.
However, expression3 is evaluated after each looping and before the statement goes back to test expression2 again.
In Hour 5, "Reading from and Writing to Standard I/O," you saw an example (in Listing 5.5) that converts the
decimal numbers 0 through 15 into hex numbers. Back then, conversions made for each number had to be written in a
separate statement. Now, with the for statement, we can rewrite the program in Listing 5.5 in a very efficient way.
Listing 7.1 shows the rewritten version of the program.
TYPE
Listing 7.1. Converting 0 through 15 to hex numbers.
1: /* 07L01.c: Converting 0 through 15 to hex numbers */
2: #include
3:
4: main()
5: {
6: int i;
7:
8: printf("Hex(uppercase) Hex(lowercase) Decimal\n");
9: for (i=0; i<16;> 07L01
Hex(uppercase) Hex(lowercase) Decimal
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
A a 10
B b 11
C c 12
D d 13
E e 14
F f 15
C:\app>
ANALYSIS
Now, let's have a look at the code in Listing 7.1. As you know, line 2 includes the header file stdio.h for
the printf() function used later in the program.
Inside the body of the main() function, the statement in line 6 declares an integer variable, i. Line 8 displays the
headline of the output on the screen.
Lines 9_11 contain the for statement. Note that the first expression in the for statement is i=0, which is an assignment
expression that initializes the integer variable i to 0.
The second expression in the for statement is i<16, i="0;" i="0;" i="0;" i="0;" i="0," j="10;">0; i++, j--){
/* statement block */
}
Here, in the first expression field, the two integer variables, i and j, are initialized, respectively, with 0 and 10 when
the for statement is first encountered. Then, in the second field, the two relational expressions, i<10>0, are
evaluated and tested. If one of the relational expressions returns 0, the looping is stopped. After each iteration and the
statements in the statement block are executed successfully, i is increased by 1, j is reduced by 1 in the third
expression field, and the expressions i<10>0 are evaluated to determine whether to do one more looping.
Now, let's look at a real program. Listing 7.2 shows an example of using multiple expressions in the for statement.
TYPE
Listing 7.2. Adding multiple expressions to the for statement.
1: /* 07L02.c: Multiple expressions */
2: #include
3:
4: main()
5: {
6: int i, j;
7:
8: for (i=0, j=8; i<8; d =" %d\n" i="0;" i="0;"> 07L02
0 + 8 = 8
1 + 7 = 8
2 + 6 = 8
3 + 5 = 8
4 + 4 = 8
5 + 3 = 8
6 + 2 = 8
7 + 1 = 8
C:\app>
ANALYSIS
In Listing 7.2, line 6 declares two integer variables, i and j, which are used in a for loop.
In line 8, i is initialized with 0 and j is set to 8 in the first expression field of the for statement. The second expression
field contains a condition, i<8,>
3:
4: main()
5: {
6: int i, j;
7:
8: for (i=0, j=1; i<8; d =" %d\n"> 07L03
1 - 0 = 1
2 - 1 = 1
3 - 2 = 1
4 - 3 = 1
5 - 4 = 1
6 - 5 = 1
7 - 6 = 1
8 - 7 = 1
C:\app>
OUTPUT
In Listing 7.3, two integer variables, i and j, are declared in line 6.
ANALYSIS
Note that in line 8, there are two assignment expressions, i=0 and j=1, in the first expression field of the
for statement. These two assignment expressions initialize the i and j integer variables, respectively.
There is one relational expression, i<8,>
3:
4: main()
5: {
6: int c;
7:
8: printf("Enter a character:\n(enter x to exit)\n");
9: for ( c=' `; c != `x'; ) {
10: c = getc(stdin);
11: putchar(c);
12: }
13: printf("\nOut of the for loop. Bye!\n");
14: return 0;
15: }
OUTPUT
After running the executable, 07L04.exe, I enter characters, such as H, i, and the \n character (I have to
press the Enter key each time after I enter a character), which are all displayed back on the screen.
Finally, I enter x to exit from the infinite for loop. (Note that in the following copy from the screen, the
characters that I entered are in bold.)
C:\app> 07L04
Enter a character:
(enter x to exit)
H
Hii
xx
Out of the for loop. Bye!
C:\app>
ANALYSIS
In Listing 7.4, there is only one integer variable, c, declared in line 6. The printf() function in line 8
displays the message Enter a character: on one line on the screen, and another message, (enter x to exit),
on another line because there is a newline character (\n) added in the middle of the format string in the
printf() function.
In line 9, the integer variable c is initialized with the numeric value of the space character. Then, a condition is
evaluated in the second expression field of the for statement like this: c != `x', which means that the condition is met
if c does not contain the numeric value of x; otherwise, the condition is not met.
If the condition is met, the two statements in lines 10 and 11 will be executed over and over. The looping can last
forever until the user enters the character x. Then, the statement in line 13 prints out a good-bye message right after
the looping is terminated.
The while Loop
The while statement is also used for looping. Unlike the situation with the for statement, there is only one expression
field in the while statement.
The general form of the while statement is
while (expression) {
statement1;
statement2;
.
.
.
}
Here expression is the field of the expression in the while statement. The expression is evaluated first. If the
expression returns a nonzero value (normally 1), the looping continues; that is, the statements inside the statement
block are executed. After the execution, the expression is evaluated again. The statements are then executed one more
time if the expression still returns nonzero value. The process is repeated over and over until the expression returns 0.
You see that a statement block, surround by the braces { and }, follows the while keyword and the expression field.
Of course, if there is only one statement in the statement block, the braces can be discarded.
Now, let's look at an example of using the while statement. The program in Listing 7.5 is a modified version of the
one in Listing 7.4, but this one uses the while statement.
TYPE
Listing 7.5. Using a while loop.
1: /* 07L05.c: Using a while loop */
2: #include
3:
4: main()
5: {
6: int c;
7:
8: c = ` `;
9: printf("Enter a character:\n(enter x to exit)\n");
10: while (c != `x') {
11: c = getc(stdin);
12: putchar(c);
13: }
14: printf("\nOut of the while loop. Bye!\n");
15: return 0;
16: }
OUTPUT
The executable 07L05.exe can do a similar job as the executable 07L04.exe. The following is a copy
from the screen:
C:\app> 07L05
Enter a character:
(enter x to exit)
HH
iix
x
Out of the while loop. Bye!
C:\app>
ANALYSIS
You see that the output from the execution of the program in Listing 7.5 is similar to the one from Listing
7.4, except the while statement is used in lines 10_13 of Listing 7.5.
The char variable c is initialized with a space character in line 8. Unlike the for statement in Listing 7.4, the while
statement does not set c before the looping.
In line 10, the relational expression c != `x' is tested. If the expression returns 1, which means the relation still holds,
the statements in lines 11 and 12 are executed. The looping continues as long as the expression returns 1. If, however,
the user enters the character x, which makes the relational expression return 0, the looping stops.
The Infinite while Loop
You can also make a while loop infinite by putting 1 in the expression field, like this:
while (1) {
statement1;
statement2;
.
.
.
}
Because the expression always returns 1, the statements inside the statement block will be executed over and over—
that is, the while loop will continue forever. Of course, you can set certain conditions inside the while loop to break
the infinite loop as soon as the conditions are met.
The C language provides some statements, such as if and break statements, that you can use to set conditions and
break the infinite while loop if needed. Details on the if and break statements are covered in Hour 10, "Getting
Controls."
The do-while Loop
You may note that in the for and while statements, the expressions are set at the top of the loop. However, in this
section, you're going to see another statement used for looping,
do-while, which puts the expressions at the bottom of the loop. In this way, the statements controlled by the do-while
statement are executed at least once before the expression is tested. Note that statements in a for or while loop are not
executed at all if the condition expression does not hold in the for or while statement.
The general form for the do-while statement is
do {
statement1;
statement2;
.
.
.
} while (expression);
Here expression is the field for the expression that is evaluated in order to determine whether the statements inside the
statement block are to be executed one more time. If the expression returns a nonzero value, the do-while loop
continues; otherwise, the looping stops.
Note that the do-while statement ends with a semicolon, which is an important distinction from the if and while
statements.
The program in Listing 7.6 displays the characters A through G by using a do-while loop to repeat the printing and
adding.
TYPE
Listing 7.6. Using a do-while loop.
1: /* 07L06.c: Using a do-while loop */
2: #include
3:
4: main()
5: {
6: int i;
7:
8: i = 65;
9: do {
10: printf("The numeric value of %c is %d.\n", i, i);
11: i++;
12: } while (i<72);> 07L06
The numeric value of A is 65.
The numeric value of B is 66.
The numeric value of C is 67.
The numeric value of D is 68.
The numeric value of E is 69.
The numeric value of F is 70.
The numeric value of G is 71.
C:\app>
ANALYSIS
The statement in line 8 of Listing 7.6 initializes the integer variable i with 65. The integer variable is
declared in line 6.
Lines 9_12 contain the do-while loop. The expression i<72>
3:
4: main()
5: {
6: int i, j;
7:
8: for (i=1; i<=3; i++) { /* outer loop */ 9: printf("The start of iteration %d of the outer loop.\n", i); 10: for (j=1; j<=4; j++) /* inner loop */ 11: printf(" Iteration %d of the inner loop.\n", j); 12: printf("The end of iteration %d of the outer loop.\n", i); 13: } 14: return 0; 15: } OUTPUT The following result is obtained by running the executable file 07L07.exe: C:\app> 07L07
The start of iteration 1 of the outer loop.
Iteration 1 of the inner loop.
Iteration 2 of the inner loop.
Iteration 3 of the inner loop.
Iteration 4 of the inner loop.
The end of iteration 1 of the outer loop.
The start of iteration 2 of the outer loop.
Iteration 1 of the inner loop.
Iteration 2 of the inner loop.
Iteration 3 of the inner loop.
Iteration 4 of the inner loop.
The end of iteration 2 of the outer loop.
The start of iteration 3 of the outer loop.
Iteration 1 of the inner loop.
Iteration 2 of the inner loop.
Iteration 3 of the inner loop.
Iteration 4 of the inner loop.
The end of iteration 3 of the outer loop.
C:\app>
ANALYSIS
In Listing 7.7, two for loops are nested together. The outer for loop starts in line 8 and ends in line 13,
while the inner for loop starts in line 10 and ends in line 11.
The inner loop controls one statement that prints out the iteration number according to the numeric value of the
integer variable j. As you see in line 10, j is initialized with 1, and is increased by 1 after each looping (that is,
iteration). The execution of the inner loop stops when the value of j is greater than 4.
Besides the inner loop, the outer loop has two statements in lines 9 and 12, respectively. The printf() function in line 9
displays a message showing the beginning of an iteration from the outer loop. An ending message is sent out in line
12 to show the end of the iteration from the outer loop.
From the output, you can see that the inner loop is finished before the outer loop starts another iteration. When the
outer loop begins another iteration, the inner loop is encountered and run again. The output from the program in
Listing 7.7 clearly shows the execution orders of the inner and outer loops.
Summary
In this lesson you've learned the following:
 Looping can be used to perform the same set of statements over and over until specified conditions are met.
 Looping makes your program concise.
 There are three statements, for, while, and do-while, that are used for looping
 in C.
 There are three expression fields in the for statement. The second field contains the expression used as the
specified condition(s).
 The for statement does not end with a semicolon.
 The empty for( ; ; ) statement can be used to form an infinite loop.
 Multiple expressions, separated by commas, can be used in the for statement.
 There is only one expression field in the while statement, and the expression is used as the specified condition.
 The while statement does not end with a semicolon.
WARNING
Don't confuse the two relational operators (< j="1;" j="1;" j="0;" k="1;" j="65;" k =" 65;" k =" 100;" k =" 100;" i="0," j="1;" d =" %d\n" i="0," j="1;" d =" %d\n" size =" sizeof(int);">
3:
4: main()
5: {
6: char ch = ` `;
7: int int_num = 0;
8: float flt_num = 0.0f;
9: double dbl_num = 0.0;
10:
11: printf("The size of char is: %d-byte\n", sizeof(char));
12: printf("The size of ch is: %d-byte\n", sizeof ch );
13: printf("The size of int is: %d-byte\n", sizeof(int));
14: printf("The size of int_num is: %d-byte\n", sizeof int_num);
15: printf("The size of float is: %d-byte\n", sizeof(float));
16: printf("The size of flt_num is: %d-byte\n", sizeof flt_num);
17: printf("The size of double is: %d-byte\n", sizeof(double));
18: printf("The size of dbl_num is: %d-byte\n", sizeof dbl_num);
19: return 0;
20: }
OUTPUT
After this program is compiled and linked, an executable file, 08L01.exe, is created. The following is the
output printed on the screen after the executable is run from a DOS prompt on my machine:
C:\app> 08L01
The size of char is: 1-byte
The size of ch is: 1-byte
The size of int is: 2-byte
The size of int_num is: 2-byte
The size of float is: 4-byte
The size of flt_num is: 4-byte
The size of double is: 8-byte
The size of dbl_num is: 8-byte
C:\app>
ANALYSIS
Line 2 in Listing 8.1 includes the header file stdio.h for the printf() function used in the statements inside
the main() function body. Lines 6_9 declare a char variable (ch), an int variable (int_num), a float
variable (flt_num), and a double variable (dbl_num), respectively. Also, these four variables are
initialized. Note that in line 8, the initial value to flt_num is suffixed with f to specify float. (As you
learned in Hour 4, you can use f or F to specify the float type for a floating-point number.)
Lines 11 and 12 display the size of the char data type, as well as the char variable ch. Note that the sizeof operator is
used in both line 11 and line 12 to obtain the number of bytes the char data type or the variable ch can have. Because
the variable ch is not a keyword in C, the parentheses are discarded for the sizeof operator in line 12.
The first two lines in the output are printed out by executing the two statements in line 11 and 12, respectively. From
the output, you see that the size of the char data type is 1 byte long, which is the same as the size of the variable ch.
This is not surprising because the variable ch is declared as the char variable.
Likewise, lines 13 and 14 print out the sizes of the int data type and the int variable int_num by using the sizeof
operator. You see that the size of each is 2 bytes.
Also, by using the sizeof operator, lines 15_18 give the sizes of the float data type, the float variable flt_num, the
double data type, and the double variable dbl_num, respectively. The results in the output section show that the float
data type and the variable flt_num have the same size (4 bytes). The double data type and the variable dbl_num are
both 8 bytes long.
From the output you see that char uses 1 byte, while an int uses 2 bytes. Accordingly, while variables of type char
have been used to store integers, they cannot store integers of the same range as a variable of type int can.
Everything Is Logical
Now, it's time for you to learn about a new set of operators: logical operators.
There are three logical operators in the C language:
The logical AND operator (&&) evaluates the truth or falseness of pairs of expressions. If both expressions are true,
the logical AND operator returns 1. Otherwise, the operator returns 0.
However, the logical OR operator (||) returns 1 if at least one of the expressions is true. The || operator returns 0 if
both expressions are false.
Only one operand (or expression) can be taken by the logical negation operator (!). If the operand is true, the !
operator returns 0; otherwise, the operator returns 1.
The following three sections contain examples that show you how to use the three logical operators.
The Logical AND Operator (&&)
A general format of using the logical AND operator is:
exp1 && exp2
where exp1 and exp2 are two expressions evaluated by the AND operator.
We can have a table that shows the return values of the AND operator under the following conditions when exp1 and
exp2 return 1 or 0, respectively. See Table 8.1, which can be called the truth table of the AND operator.
Table 8.1. The values returned by the AND operator.
Listing 8.2 is an example of using the logical AND operator (&&).
TYPE
Listing 8.2. Using the logical AND operator (&&).
&& The logical AND operator
|| The logical OR operator
! The logical negation operator
NOTE
In C, if an expression or operator returns a nonzero value, the expression returns TRUE. If an expression
or operator returns 0, the expression returns FALSE. In other words, TRUE can be used to represent any
nonzero value returned by an expression or operator; FALSE is equivalent to 0.
exp1 exp2 Value Returned by &&
1 1 1
1 0 0
0 1 0
0 0 0
1: /* 08L02.c: Using the logical AND operator */
2: #include
3:
4: main()
5: {
6: int num;
7:
8: num = 0;
9: printf("The AND operator returns: %d\n",
10: (num%2 == 0) && (num%3 == 0));
11: num = 2;
12: printf("The AND operator returns: %d\n",
13: (num%2 == 0) && (num%3 == 0));
14: num = 3;
15: printf("The AND operator returns: %d\n",
16: (num%2 == 0) && (num%3 == 0));
17: num = 6;
18: printf("The AND operator returns: %d\n",
19: (num%2 == 0) && (num%3 == 0));
20:
21: return 0;
22: }
OUTPUT
After this program is compiled and linked, an executable file, 08L02.exe, is created. The following is the
output printed on the screen after the executable is run from a DOS prompt on my machine:
C:\app> 08L02
The AND operator returns: 1
The AND operator returns: 0
The AND operator returns: 0
The AND operator returns: 1
C:\app>
ANALYSIS
In Listing 8.2, an integer variable, num, is declared in line 6 and initialized for the first time
in line 8. Lines 9 and 10 print out the value returned by the logical AND operator in the
following expression:
(num%2 == 0) && (num%3 == 0)
Here you see two relational expressions, num%2 == 0 and num%3 == 0. In Hour 3, "The Essentials of C Programs,"
you learned that the arithmetic operator % can be used to obtain the remainder after its first operand is divided by the
second operand. Therefore, num%2 yields the remainder of num divided by 2. The relational expression num%2 == 0
returns 1 (TRUE) if the remainder is equal to 0—that is, the value of num can be divided evenly by 2. Likewise, if the
value of num can be divided by 3, the relational expression num%3 == 0 returns 1 as
well. Then, according to the truth table of the && operator (see Table 8.1), we know that the combination of the
logical AND operator (&&) and the two relational expressions yields 1 if the two relational expressions both return 1;
otherwise, it yields 0.
In our case, when num is initialized to 0 in line 8, both 0%2 and 0%3 yield remainders of 0 so that the two relational
expressions return TRUE. Therefore, the logical AND operator returns 1.
However, when num is assigned with the value of 2 or 3 as shown in lines 11 and 14, the logical AND operator in
line 13 or line 16 returns 0. The reason is that 2 or 3 cannot be divided by both 2 and 3.
Line 17 then assigns num the value of 6. Because 6 is a multiple of both 2 and 3, the logical
AND operator in line 19 returns 1, which is printed out by the printf() function in lines 18 and 19.
From the program in Listing 8.2, you see several single statements spanning into multiple lines. The output from the
program in Listing 8.2 shows the values returned by the AND operator when num is assigned with different values.
The Logical OR Operator (||)
As mentioned earlier, the logical OR operator returns 1 if at least one of the expressions is true. The || operator returns
0 if both expressions are false.
A general format of using the logical OR operator is:
exp1 || exp2
where exp1 and exp2 are two expressions evaluated by the OR operator.
Table 8.2 shows the truth table of the OR operator.
The program in Listing 8.3 shows how to use the logical OR operator (||).
TYPE
Listing 8.3. Using the logical OR operator (||).
1: /* 08L03.c: Using the logical OR operator */
2: #include
3:
4: main()
5: {
6: int num;
7:
8: printf("Enter a single digit that can be divided\nby both 2 and 3:\n");
9: for (num = 1; (num%2 != 0) || (num%3 != 0); )
10: num = getchar() - 48;
11: printf("You got such a number: %d\n", num);
12: return 0;
13: }
OUTPUT
The following is the output printed on the screen after the executable, 08L03.exe, is run from a DOS
prompt on my machine. The numbers in bold font are what I entered. (The Enter key is pressed after each
number is entered.) In the range of 0_9, 0 and 6 are the only two numbers that can be divided evenly by
both 2 and 3:
C:\app> 08L03
Enter a single digit that can be divided
by both 2 and 3:
23
45
6
You got such a number: 6
exp1 exp2 Value Returned by
||
1 1 1
1 0 1
0 1 1
0 0 0
C:\app>
ANALYSIS
In Listing 8.3, an integer variable, num, is declared in line 6. Line 8 of Listing 8.3 prints out a headline
asking the user to enter a single digit. Note that there is a newline character (\n) in the middle of the
headline message in the printf() function to break the message into two lines.
In line 9, the integer variable num is initialized in the first expression field of the for statement. The reason to
initialize num with 1 is that 1 is such a number that cannot be divided by either 2 nor 3. Thus, the for loop is
guaranteed to be executed at least once.
The key part of the program in Listing 8.3 is the logical expression in the for statement:
(num%2 != 0) || (num%3 != 0)
Here the relational expressions num%2 != 0 and num%3 != 0 are evaluated. According to the truth table of the ||
operator (see Table 8.2), we know that if one of the relational expression returns TRUE, i.e., the value of num cannot
be divided completely by either 2 or 3. Then the logical expression returns 1, which allows the for loop to continue.
The for loop stops only if the user enters a digit that can be divided by both 2 and 3. In other words, when both the
relational expressions return FALSE, the logical OR operator yields 0, which causes the termination of the for loop.
You can rewrite the program in Listing 8.3 with the if statement, too.
The Logical Negation Operator (!)
A general format of using the logical OR operator is:
!expression
where expression is an expression operated by the negation operator.
The truth table of the negation operator is shown in Table 8.3.
Table 8.3. The values returned by the ! operator.
TYPE
Now, let's take a look at the example, shown in Listing 8.4, that demonstrates how to use the logical
negation operator (!).
Listing 8.4. Using the logical negation operator (!).
1: /* 08L04.c: Using the logical negation operator */
2: #include
3:
4: main()
5: {
6: int num;
7:
8: num = 7;
9: printf("Given num = 7\n");
expression Value Returned
by !
1 0
0 1
10: printf("!(num <> 7) returns: %d\n", !(num > 7));
12: printf("!(num == 7) returns: %d\n", !(num == 7));
13: return 0;
14: }
OUTPUT
The following result is obtained by running the executable file 08L04.exe:
C:\app> 08L04
Given num = 7
!(num <> 7) returns: 1
!(num == 7) returns: 0
C:\app>
ANALYSIS
In line 8, note that an integer variable, num, is initialized with 7, which is then displayed by the printf()
function in line 9.
In line 10, the relational expression num <> 7) returns 1 in line 11.
Because num has the value of 7, the relational expression num == 7 is true; however, the
logical expression !(num == 7) in line 12 returns 0 due to the logical negation operator (!).
Manipulating Bits
In previous hours, you learned that computer data and files are made of bits (or bytes). There is even an operator in
C_the sizeof operator_that can be used to measure the number of bytes for data types.
In this section, you'll learn about a set of operators that enable you to access and manipulate specific bits.
There are six bit-manipulation operators in the C language:
The following two sections give explanations and examples of the bit-manipulation
operators.
Operator Description
& The bitwise AND operator
| The bitwise OR operator
^ The bitwise exclusive OR (XOR) operator
~ The bitwise complement operator
>> The right-shift operator
<<> 1 * 23 + 0 *22 + 0 * 21 + 0 * 20-> 23 -> 8 (decimal)
That is, the decimal vale of the binary number 1000 is 8.
If we want to convert a decimal number, for example 10, to its binary counterpart, we have the following process:
10 -> 23 + 21 -> 1 *23 + 0 * 22 + 1 *21 + 0 * 20 -> 1010 (binary)
Likewise, you can convert the rest of the decimal numbers in Table 8.4 to their binary counterparts, or vice versa.
Using Bitwise Operators
The general forms of the bitwise operators are as follows:
x & y
x | y
x ^ y
~x
Here x and y are operands.
The & operator compares each bit of x to the corresponding bit in y. If both bits are 1, 1 is placed at the same position
of the bit in the result. If one of the bits, or two of them, is 0, 0 is placed in the result.
Hex Binary Decimal
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15
For instance, the expression with two binary operands, 01 & 11, returns 01.
The | operator, however, places 1 in the result if either operand is 1. For example, the expression 01 | 11 returns 11.
The ^ operator places 1 in the result if either operand, but not both, is 1. Therefore, the expression 01 ^ 11 returns 10.
Finally, the ~ operator takes just one operand. This operator reverses each bit in the operand. For instance, ~01
returns 10.
Table 8.5 shows more examples of using the bitwise operators in decimal, hex, and binary formats (in the left three
columns). The corresponding results, in binary, hex, and decimal formats, are listed in the right three columns. The
hex numbers are prefixed with 0x.
Table 8.5. Examples of using bitwise operators.
TYPE
Note that the complementary value of 12 is 65523, because the unsigned integer data type (16-bit) has
the maximum number 65535. In other words, 65,523 is the result of subtracting 12 from 65,535. (The
unsigned data modifier is introduced in Hour 9, "Playing with Data Modifiers and Math Functions.")
The program in Listing 8.5 demonstrates the usage of the bitwise operators.
Listing 8.5. Using bitwise operators.
1: /* 08L05.c: Using bitwise operators */
2: #include
3:
4: main()
5: {
6: int x, y, z;
7:
8: x = 4321;
9: y = 5678;
10: printf("Given x = %u, i.e., 0X%04X\n", x, x);
11: printf(" y = %u, i.e., 0X%04X\n", y, y);
12: z = x & y;
13: printf("x & y returns: %6u, i.e., 0X%04X\n", z, z);
14: z = x | y;
15: printf("x | y returns: %6u, i.e., 0X%04X\n", z, z);
16: z = x ^ y;
17: printf("x ^ y returns: %6u, i.e., 0X%04X\n", z, z);
18: printf(" ~x returns: %6u, i.e., 0X%04X\n", ~x, ~x);
19: return 0;
20: }
OUTPUT
After the executable, 08L05.exe, is created and run from a DOS prompt, the following output is shown
on the screen:
C:\app> 08L05
Decimal Results
Expressions Hex Binary Decimal Hex Binary
12 & 10 0x0C & 0x0A 1100 &1010 8 0x08 1000
12 | 10 0x0C | 0x0A 1100 | 1010 14 0x0E 1110
12 ^ 10 0x0C ^ 0x0A 1100 ^ 1010 6 0x06 0110
~12 ~0x000C ~0000000000001100 65523 FFF3 1111111111110011
Given x = 4321, i.e., 0X10E1
y = 5678, i.e., 0X162E
x & y returns: 4128, i.e., 0X1020
x | y returns: 5871, i.e., 0X16EF
x ^ y returns: 1743, i.e., 0X06CF
~x returns: 61214, i.e., 0XEF1E
C:\app>
ANALYSIS
In Listing 8.5, three integer variables, x, y, and z, are declared in line 6. Lines 8 and 9 set x and y to 4321
and 5678, respectively. Lines 10 and 11 then print out the values of x and y in both decimal and hex
formats. The hex numbers are prefixed with 0X.
The statement in line 12 assigns the result of the operation made by the bitwise AND operator (&) with the variables
x and y. Then, line 13 displays the result in both decimal and hex formats.
Lines 14 and 15 perform the operation specified by the bitwise operator (|) and print out the result in both decimal and
hex formats. Similarly, lines 16 and 17 give the result of the operation made by the bitwise XOR operator (^).
Last, the statement in line 18 prints out the complementary value of x by using the bitwise complement operator (~).
The result is displayed on the screen in both decimal and hex formats.
Note that the unsigned integer format specifier with a minimum field width of 6, %6u, and the uppercase hex format
specifier with the minimum width of 4, %04X, are used in the printf() function. The unsigned integer data type (that
is, the non-negative integer data type) is chosen so that the complementary value of an integer can be shown and
understood easily. More details on the unsigned data modifier are introduced in Hour 9.
Using Shift Operators
There are two shift operators in C. The >> operator shifts the bits of an operand to the right; the <<>> y
x <<>> 2 expression tells the computer to shift 2 bits of the operand 8 to the right, which returns 2 in
decimal. The following:
8 >> 2 -> (1 * 23 + 0 *22 + 0 * 21 + 0 *20) >> 2
produces the following:
(0 * 23 + 0 * 22 + 1 *21 + 0 * 20) -> 0010 (binary) -> 2 (decimal).
Likewise, the 5 << x="1)" y="10)" x="1)" y="10)">
3:
4: main()
5: {
6: int x, y, z;
7:
8: x = 255;
9: y = 5;
10: printf("Given x = %4d, i.e., 0X%04X\n", x, x);
11: printf(" y = %4d, i.e., 0X%04X\n", y, y);
12: z = x >> y;
13: printf("x >> y returns: %6d, i.e., 0X%04X\n", z, z);
14: z = x <<> 08L06
Given x = 255, i.e., 0X00FF
y = 5, i.e., 0X0005
x >> y returns: 7, i.e., 0X0007
x <<>
ANALYSIS
Three integer variables, x, y, and z, are declared in line 6 of Listing 8.6. x is initial-ized with
255 in line 8; y is set to 5 in line 9. Then, lines 10 and 11 display the values of x and y on the screen.
The statement in line 12 shifts y bits of the operand x to the right, and then assigns the result to z. Line 13 prints out
the result of the shifting made in line 12. The result is 7 in decimal, or 0X0007 in hex.
Lines 14 and 15 shift the operand x to the left by y bits and display the result on the screen, too. The result of the leftshifting
is 8160 in decimal, or 0x1FE0 in hex.
TIP
The operation of the shift-right operator (>>) is equivalent to dividing by powers of 2. In other words,
the following:
x >> y
x / 2y
Here x is a non-negative integer.
On the other hand, shifting to the left is equivalent to multiplying by powers of 2; that is,
x <<> 0 ? `T' : `F' returns `T' if the value of x is greater than 0. Otherwise, the expression
returns `F'.
Listing 8.7 demonstrates the usage of the conditional operator in the C language.
TYPE
Listing 8.7. Using the conditional operator.
1: /* 08L07.c: Using the ?: operator */
2: #include
3:
4: main()
5: {
6: int x;
7:
8: x = sizeof(int);
9: printf("%s\n",
10: (x == 2) ? "The int data type has 2 bytes." : "int doesn't have 2
Âbytes.");
11: printf("The maximum value of int is: %d\n",
12: (x != 2) ? ~(1 <<> 08L07
The int data type has 2 bytes.
The maximum value of int is: 32767
C:\app>
ANALYSIS
In Listing 8.7, the size of the int data type is measured first in line 8, by using the sizeof operator and the
number of bytes assigned to the integer variable x.
Lines 9 and 10 contain one statement, in which the conditional operator (?:) is used to test whether the number of
bytes saved in x is equal to 2. (Here you see another example that a single statement can span multiple lines.) If the x
== 2 expression returns nonzero (that is, TRUE), the string of The int data type has 2 bytes. is printed out by the
printf() function in the statement. Otherwise, the second string, int doesn't have 2 bytes., is displayed on the screen.
In addition, the statement in lines 11 and 12 tries to find out the maximum value of the int data type on the current
machine. The x != 2 expression is evaluated first in the statement. If the expression returns nonzero (that is, the byte
number of the int data type is not equal to 2), the ~( <<>>), and the left-shift operator
(<<).  The conditional operator (?:) is the only operator in C that can take three operands. In next lesson you'll learn about the data type modifiers in the C language. Q&A Q Why do we need the sizeof operator? A The sizeof operator can be used to measure the sizes of all data types defined in C. When you write a portable C program that needs to know the size of an integer variable, it's a bad idea to hard-code the size as 16 or 32. The better way to tell the program the size of the variable is to use the sizeof operator, which returns the size of the integer variable at runtime. Q What's the difference between | and ||? A | is the bitwise OR operator that takes two operands. The | operator compares each bit of one operand to the corresponding bit in another operand. If both bits are 0, 0 is placed at the same position of the bit in the result. Otherwise, 1 is placed in the result. On the other hand, ||, the logical OR operator, requires two operands (or expressions). The operator returns 0 (that is, FALSE) if both its operands are false. Otherwise, a nonzero value (that is, TRUE) is returned by the || operator. Q Why is 1 <<>
65) ? "Retired" : "Not retired" tells the computer that if the value of age is greater than 65, the string of
Retired should be chosen; otherwise, Not retired is chosen.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. What do the (x=1) && (y=10) and (x=1) & (y=10) expressions return, respectively?
2. Given x = 96, y = 1, and z = 69, what does the expression !y ? x == z : y return?
3. What do the ~0011000000111001 and ~1100111111000110 expressions return?
4. Given x=9, what does (x%2==0)||(x%3==0) return? How about (x%2==0)&&(x%3==0)?
5. Is 8 >> 3 equivalent to 8 / 23? How about 1 << x =" 0xEFFF" y =" 0x1000," x =" 123" y =" 4,">> y expressions.
4. Write a program that shows the return values (in hex) of the 0xFFFF^0x8888, 0xABCD & 0x4567, and
0xDCBA | 0x1234 expressions.
5. Use the ?: operator and the for statement to write a program that keeps taking the characters entered by the user
until the character q is accounted. (Hint: Put the x!='q' ? 1 : 0 expression to the second field in the for
statement.)
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 9 - Playing with Data Modifiers and Math Functions
If at first you don't succeed, transform your data.
—Murphy's Laws of Computers
In Hour 4, "Data Types and Names in C," you learned about several data types, such as char, int, float, and double, in
the C language. In this hour, you'll learn about four data modifiers that enable you to have greater control over the
data. The C keywords for the four data modifiers are
 signed
 unsigned
 short
 long
You're also going to learn about several mathematical functions provided by the C language, such as
 The sin() function
 The cos() function
 The tan() function
 The pow() function
 The sqrt() function
Enabling or Disabling the Sign Bit
As you know, it's very easy to express a negative number in decimal. All you need to do is put a minus sign in front
of the absolute value of the number. But how does the computer represent a negative number in the binary format?
Normally, one bit can be used to indicate whether the value of a number represented in the binary format is negative.
This bit is called the sign bit. The following two sections introduce two data modifiers, signed and unsigned, that can
be used to enable or disable the sign bit.
The signed Modifier
For integers, the leftmost bit can be used as the sign bit. For instance, if the int data type is 16 bits long and the
rightmost bit is counted as bit 0, you can use bit 15 as a sign bit. When the sign bit is set to 1, the C compiler knows
that the value represented by the data variable is negative.
There are several ways to represent a negative value of the float or double data types. The implementations of the
float and double data types are beyond the scope of this book. You can refer to Kernighan and Ritchie's book The C
Programming Language for more details on the implementations of negative values of the float or double type.
The C language provides a data modifier, signed, that can be used to indicate to the compiler that the int or char data
type uses the sign bit. By default, the int data type is a signed quantity. But the ANSI standard does not require the
char data type be signed; it's up to the compiler vendors. Therefore, if you want to use a signed character variable, and
make sure the compiler knows it, you can declare the character variable like this:
signed char ch;
so that the compiler knows that the character variable ch is signed, which means the variable can take a value in the
range of -128 (that is, -27) to 127 (that is, 27_1).
(Remember that for an unsigned character variable, the range is 0 to 255; that is, 28_1.)
The unsigned Modifier
The C language also gives you the unsigned modifier, which can be used to tell the C compiler that no sign bit is
needed in the specified data type.
Like the signed modifier, the unsigned modifier is meaningful only to the int and char data types.
For instance, the declaration
unsigned int x;
tells the C compiler that the integer variable x can only assume positive values from 0 to 65535 (that is, 216_1), if the
int data type is 16 bits long.
In fact, unsigned int is equivalent to unsigned according to the ANSI standard. In other words, unsigned int x; is the
same as unsigned x;.
Also, the ANSI standard allows you to indicate that a constant is of type unsigned by suffixing u or U to the constant.
For instance,
unsigned int x, y;
x = 12345U;
y = 0xABCDu;
Here, the unsigned integer constants 12345U and 0xABCDu are assigned to variables x and y, respectively.
The program in Listing 9.1 is an example of using the signed and unsigned modifiers.
TYPE
Listing 9.1. Modifying data with signed and unsigned.
1: /* 09L01.c: Using signed and unsigned modifiers */
2: #include
3:
4: main()
5: {
6: signed char ch;
TIP
To represent a negative number in the binary format, you can first get its equivalent positive value's
binary format. Then you perform the complement operation on the binary, and finally, add one to the
complemented binary.
For instance, given a negative integer -12345, how can you represent it in the binary format?
First, you need to find the binary format for the positive integer 12345, which is 0011000000111001.
Then, you perform the complement operation on 0011000000111001; that is, ~0011000000111001, and
obtain the following:
1100111111000110
And finally, adding 1 to 1100111111000110 gives you 1100111111000111, which is the binary format
of the negative integer -12345.
7: int x;
8: unsigned int y;
9:
10: ch = 0xFF;
11: x = 0xFFFF;
12: y = 0xFFFFu;
13: printf("The decimal of signed 0xFF is %d.\n", ch);
14: printf("The decimal of signed 0xFFFF is %d.\n", x);
15: printf("The decimal of unsigned 0xFFFFu is %u.\n", y);
16: printf("The hex of decimal 12345 is 0x%X.\n", 12345);
17: printf("The hex of decimal -12345 is 0x%X.\n", -12345);
18: return 0;
19: }
On my machine, the executable file of the program in Listing 9.1 is named 09L01.exe. (Note that when you compile
the program in Listing 9.1, you'll see a warning message regarding the assignment statement ch = 0xFF; in line 10,
due to the fact that ch is declared as a signed char variable. You can ignore the warning message.)
The following is the output printed on the screen after I run the executable from a DOS prompt:
C:\app> 09L01
The decimal of signed 0xFF is -1
The decimal of signed 0xFFFF is -1.
The decimal of unsigned 0xFFFFu is 65535.
The hex of decimal 12345 is 0x3039.
The hex of decimal -12345 is 0xCFC7.
C:\app>
OUTPUT
As you see in Listing 9.1, line 6 declares a signed char variable, ch. The int variable x and the unsigned
int variable y are declared in lines 7 and 8, respectively. The three variables, ch, x, and y, are initialized
in lines 10_12. Note that in line 12, u is suffixed to 0xFFFF to indicate that the constant is an unsigned
integer.
ANALYSIS
The statement in line 13 displays the decimal value of the signed char variable ch. The output on the
screen shows that the corresponding decimal value of 0xFF is -1 for the signed char variable ch.
Lines 14 and 15 print out the decimal values of the int variable x (which is signed by default) and the unsigned int
variable y, respectively. Note that for the variable y, the unsigned integer format specifier %u is used in the printf()
function in line 15. (Actually, you might recall that %u was used to specify the unsigned int data type as the display
format in the previous hour.)
Based on the output, you see that 0xFFFF is equal to -1 for the signed int data type, and 65535 for the unsigned int
data type. Here, the integer data type is 16 bits long.
Lines 16 and 17 print out 0x3039 and 0xCFC7, which are the hex formats of the decimal values of 12345 and -12345,
respectively. According to the method mentioned in the last section, 0xCFC7 is obtained by adding 1 to the
complemented value of 0x3039.
Changing Data Sizes
Sometimes, you want to reduce the memory taken by variables, or you need to increase the storage space of certain
data types. Fortunately, the C language gives you the flexibility to modify sizes of data types. The two data modifiers,
short and long, are introduced in the following two sections.
The short Modifier
A data type can be modified to take less memory by using the short modifier. For instance, you can apply the short
modifier to an integer variable that is 32 bits long, which might reduce the memory taken by the variable to as little as
16 bits.
You can use the short modifier like this:
short x;
unsigned short y;
By default, a short int data type is a signed number. Therefore, in the short x; statement, x is a signed variable of short
integer.
The long Modifier
If you need more memory to keep values from a wider range, you can use the long modifier to define a data type with
increased storage space.
For instance, given an integer variable x that is 16 bits long, the declaration
long int x;
increases the size of x to 32 bits. In other words, after the modification, x is capable of holding a range of values from
-2147483648 (that is, -231) to 2147483647 (that is, 231_1).
The ANSI standard allows you to indicate that a constant has type long by suffixing l or L to the constant. For
instance:
long int x, y;
x = 123456789l;
y = 0xABCD1234L;
Here, the constants of the long int data type, 123456789l and 0xABCD1234L, are assigned to variables x and y,
respectively.
Also, you can declare a long integer variable simply like this:
long x;
long int x;
Listing 9.2 contains a program that can print out the numbers of bytes for different modified data types.
TYPE
Listing 9.2. Modifying data with short and long.
1: /* 09L02.c: Using short and long modifiers */
2: #include
3:
4: main()
5: {
6: printf("The size of short int is: %d.\n",
7: sizeof(short int));
8: printf("The size of long int is: %d.\n",
9: sizeof(long int));
10: printf("The size of float is: %d.\n",
11: sizeof(float));
12: printf("The size of double is: %d.\n",
13: sizeof(double));
14: printf("The size of long double is: %d.\n",
15: sizeof(long double));
16: return 0;
17: }
I obtain the following output printed on the screen after I run the executable 09L02.exe from a DOS prompt:
C:\app> 09L02
The size of short int is: 2.
The size of long int is: 4.
The size of float is: 4.
The size of double is: 8.
The size of long double is: 10.
C:\app>
OUTPUT
In Listing 9.2, the sizeof operator and printf() function are used to measure the sizes of the modified data
types and display the results on the screen.
For instance, lines 6 and 7 obtain the size of the short int data type and print out the number of the byte,
2, on the screen. From the output, you know that the short int data type is 16 bits (that is, 2 bytes) long on
my machine.
ANALYSIS
Likewise, lines 8 and 9 find the size of the long int data type is 4 bytes (that is, 32 bits) long, which is the
same length as the float data type obtained in lines 10 and 11.
Lines 12 and 13 obtain the size of the double data type, which is 8 bytes (that is, 64 bits) on my machine. Then, after
being modified by the long modifier, the size of the double data type is increased to 10 bytes (that is, 80 bits), which
is printed out by the printf() function in lines 14 and 15.
Adding h, l, or L to Format Specifiers
You can add h into the integer format specifier (like this: %hd, %hi, or %hu) to specify that the corresponding
number is a short int or unsigned short int.
On the other hand, using %ld or %Ld specifies that the corresponding datum is long int. %lu or %Lu is then used for
the long unsigned int data.
The program in Listing 9.3 shows the usage of %hd, %lu, and %ld.
TYPE
Listing 9.3. Using %hd, %ld, and %lu.
1: /* 09L03.c: Using %hd, %ld, and %lu specifiers */
2: #include
3:
4: main()
5: {
6: short int x;
7: unsigned int y;
8: long int s;
9: unsigned long int t;
10:
11: x = 0xFFFF;
12: y = 0xFFFFU;
13: s = 0xFFFFFFFFl;
14: t = 0xFFFFFFFFL;
15: printf("The short int of 0xFFFF is %hd.\n", x);
16: printf("The unsigned int of 0xFFFF is %u.\n", y);
17: printf("The long int of 0xFFFFFFFF is %ld.\n", s);
18: printf("The unsigned long int of 0xFFFFFFFF is %lu.\n", t);
19: return 0;
20: }
After the executable 09L03.exe is created and run from a DOS prompt, the following output is shown on the screen:
C:\app> 09L03
The short int of 0xFFFF is -1.
The unsigned int of 0xFFFF is 65535.
The long int of 0xFFFFFFFF is -1.
The unsigned long int of 0xFFFFFFFF is 4294967295
C:\app>
OUTPUT
There are four data types declared in Listing 9.3: the short int variable x, the unsigned int variable y, the
long int variable s, and the unsigned long int variable t. The four variables are initialized in lines 6_9.
ANALYSIS
To display the decimal values of x, y, s, and t, the format specifiers %hd, %u, %ld, and %lu are used,
respectively, in lines 15_18 to convert the corresponding hex numbers to decimal numbers. The output
from the program in Listing 9.3 shows that values contained by x, y, s, and t have been correctly
displayed on the screen.
Mathematical Functions in C
Basically, the math functions provided by the C language can be classified into three groups:
 Trigonometric and hyperbolic functions, such as acos(), cos(), and cosh().
 Exponential and logarithmic functions, such as exp(), pow(), and log10().
 Miscellaneous math functions, such as ceil(), fabs(), and floor().
You have to include the header file math.h in your C program before you can use any math functions defined in the
header file. Appendix B, "ANSI C Library Functions," lists all the math functions available in C.
The following two sections introduce several math functions and tell you how to use them in your programs.
Calling sin(), cos(), and tan()
You should appreciate that C gives you a set of functions to deal with trigonometric or hyperbolic calculations, if you
think those calculations are very tough.
For instance, given an angle x in radians, the sin(x) expression returns the sine of the angle.
The following formula can be used to convert the value of an angle in degrees into the value in radians:
radians = degree * (3.141593 / 180.0).
Here, 3.141593 is the approximate value of pi. If needed, you can use more decimal digits from pi.
Now, let's have a look at the syntax of the sin(), cos(), and tan() functions.
The syntax for the sin() function is
#include
double sin(double x);
Here, the double variable x contains the value of an angle in radians. The sin() function returns the sine of x in the
double data type.
The syntax for the cos() function is
#include
double cos(double x);
Here, the double variable x contains the value of an angle in radians. The cos() function returns the cosine of x in the
double data type.
The syntax for the tan() function is
#include
double tan(double x);
Here, the double variable x contains the value of an angle in radians. The tan() function returns the tangent of x in the
double data type.
Listing 9.4 demonstrates how to use the sin(), cos(), and tan() functions.
TYPE
Listing 9.4. Calculating trigonometric values with sin(), cos(), and tan().
1: /* 09L04.c: Using sin(), cos(), and tan() functions */
2: #include
3: #include
4:
5: main()
6: {
7: double x;
8:
9: x = 45.0; /* 45 degree */
10: x *= 3.141593 / 180.0; /* convert to radians */
11: printf("The sine of 45 is: %f.\n", sin(x));
12: printf("The cosine of 45 is: %f.\n", cos(x));
13: printf("The tangent of 45 is: %f.\n", tan(x));
14: return 0;
15: }
The following output is displayed on the screen when the executable 09L04.exe is executed:
C:\app> 09L04
The sine of 45 is: 0.707107.
The cosine of 45 is: 0.707107.
The tangent of 45 is: 1.000000.
C:\app>
OUTPUT
Note that the header file math.h is included in line 3, which is required by the C math functions.
ANALYSIS
The double variable x in Listing 9.4 is initialized with 45.0 in line 9. Here, 45.0 is the value of the angle
in degrees, which is converted into the corresponding radians in line 10.
Then, the statement in line 11 calculates the sine of x by calling the sin() function and prints out the result on the
screen. Similarly, line 12 obtains the cosine of x and shows it on the screen as well. Because x contains the value of a
45-degree angle, it's not surprising to see that both the sine and cosine values are the same, about 0.707107.
Line 13 gives the tangent value of x by using the tan() function. As you might know, the tangent of x is equal to the
sine of x divided by the cosine of x. Because the sine of a 45-degree angle is the same as the cosine of a 45-degree
angle, the tangent of a 45-degree angle is equal to 1. The result (in the floating-point format) of 1.000000, in the third
line of the listing's output, proves it.
You can declare a constant PI initialized to 3.141593, and another constant initialized to 180.0. Or, simply declare a
single constant initialized to the result of 3.141593/180.0. In Hour 23, "The C Preprocessor," you'll learn to use the C
preprocessor #define directive to do so.
Calling pow() and sqrt()
The pow() and sqrt() functions are two other useful math functions in C.
The syntax for the pow() function is
#include
double pow(double x, double y);
Here, the value of the double variable x is raised to the power of y. The pow() function returns the result in the double
data type.
The syntax for the sqrt() function is
#include
double sqrt(double x);
Here, the sqrt() function returns the non-negative square root of x in the double data type. The function returns an
error if x is negative.
In fact, if you set up the second argument in the pow() function to 0.5, and x contains a non-negative value, the two
expressions, pow(x, 0.5) and sqrt(x), are equivalent.
Now, take a look at how to call the pow() and sqrt() functions in the program shown in Listing 9.5.
TYPE
Listing 9.5. Applying the pow() and sqrt() functions.
1: /* 09L05.c: Using pow() and sqrt() functions */
2: #include
3: #include
4:
5: main()
6: {
7: double x, y, z;
8:
9: x = 64.0;
10: y = 3.0;
11: z = 0.5;
12: printf("pow(64.0, 3.0) returns: %7.0f\n", pow(x, y));
13: printf("sqrt(64.0) returns: %2.0f\n", sqrt(x));
14: printf("pow(64.0, 0.5) returns: %2.0f\n", pow(x, z));
15: return 0;
16: }
The following output is displayed on the screen after the executable 09L05.exe is executed:
C:\app> 09L05
pow(64.0, 3.0) returns: 262144
sqrt(64.0) returns: 8
pow(64.0, 0.5) returns: 8
C:\app>
OUTPUT
The three double variables in Listing 9.5, x, y, and z, are initialized with 64.0, 3.0, and 0.5, respectively,
in lines 9_11.
ANALYSIS
The pow() function in line 12 takes x and y and then calculates the value of x raised to the power of y.
Because the fractional part is all decimal digits of 0s, the format specifier %7.0f is used in the printf()
function to convert only the non-fractional part of the value. The result is shown on the screen as 262144.
In line 13, the non-negative square root of x is calculated by calling the sqrt() function. As in line 12, the format
specifier %2.0f is used in line 13 to convert the non-fractional part of the value returned from the sqrt() function,
because the fractional part consists of decimal digits of 0s. As you see in the output, the non-negative square root of x
is 8.
As I mentioned earlier, the pow(x, 0.5) expression is equivalent to the sqrt(x) expression. Thus, it's no surprise to see
that pow(x, z) in the statement of line 14 produces the same result as sqrt(x) does in line 13.
Summary
In this lesson you've learned the following:
 The signed modifier can be used to enable the sign bit for the char and int data types.
 All int variables in C are signed by default.
 The unsigned modifier can be used to disable the sign bit for the char and int data types.
 The memory space taken by a data variable can be reduced or increased by using the short, or long, data
modifier respectively.
 There is a set of C library functions, such as sin(), cos(), and tan(), that can be used to perform trigonometric or
hyperbolic computations.
 There is another group of math functions in C—for example, pow()—that can perform exponential and
logarithmic calculation.
 The sqrt() function returns a non-negative square root. The expression sqrt(x) is equivalent to the pow(x, 0.5)
expression, if x has a non-negative value.
 The header file math.h must be included in your C program if you call some math functions defined in the
header file.
In the next lesson you'll learn several very important control flow statements in C.
Q&A
Q Which bit can be used as the sign bit in an integer?
NOTE
All floating-point calculations, including both the float and double data types, are done in doubleprecision
arithmetic. That is, a float data variable must be converted to a double in order to carry on the
calculation. After the calculation, the double has to be converted back to a float before the result can be
assigned to the float variable. Therefore, a float calculation may take more time.
The main reason that C supports the float data type is to save memory space, because the double data
type takes twice as much memory space for storage as the float data type does.
A The leftmost bit can be used as the sign bit for an integer. For instance, assume the int data type is 16
bits long. If you count the bit position from right to left, and the first bit counted is bit 0, then bit 15 is the
leftmost bit that can be used as the sign bit.
Q What can the %lu format specifier do?
A The %lu format specifier can be used to convert the corresponding datum to the unsigned long int data
type. In addition, the %lu format specifier is equivalent to %Lu.
Q When do I use short and long?
A If you need to save memory space, and you know the value of an integer data variable stays within a
smaller range, you can try to use the short modifier to tell the C compiler to reduce the default memory
space assigned to the variable, for instance, from 32 bits to 16 bits.
On the other hand, if a variable has to hold a number that is beyond the current range of a data type, you
can use the long modifier to increase the storage space of the variable in order to hold the number.
Q Does the sin() function take a value in degrees or in radians?
A Like other trigonometric math functions in C, the sin() function takes a value in radians. If you have an
angle in degrees, you have to convert it into the form of radians. The formula is:
radians = degree * (3.141593 / 180.0).
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. Given an int variable x and an unsigned int variable y, as well as x = 0x8765 and y = 0x8765, is x equal to y?
2. Given that the int data type is 16 bits long, what is the hex format of the decimal number -23456?
3. Which format specifier, %ld or %lu, should be used to specify an unsigned long int variable?
4. What is the name of the header file you have to include if you're calling some C math functions from your C
program?
Exercises
1. Given the following statements,
int x;
unsigned int y;
x = 0xAB78;
y = 0xAB78;
write a program to display the decimal values of x and y on the screen.
2. Write a program to measure the sizes of short int, long int, and long double on your machine.
3. Give the binary representations of the following:
 512
 -1
 128
 -128
4. Write a program to display the decimal value given in quiz question 2 in the hex format. Does the result from
the program match your answer to that question?
5. Given an angle of 30 degrees, write a program to calculate its sine and tangent values.
6. Write a program to calculate the non-negative square root of 0x19A1.
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 10 - Getting Controls
It is harder to command than to obey.
—F. Nietzsche
In Hour 7, "Doing the Same Thing Over and Over," you learned to use the for, while, and do-while statements to do
the same things over and over. These three statements can be grouped into the looping category that is a part of the
control flow statements in C.
In this lesson you'll learn about the statements that belong to another group of control flow statements—conditional
branching (or jumping), such as
 The if statement
 The if-else statement
 The switch statement
 The break statement
 The continue statement
 The goto statement
Always Saying "if…"
If life were a straight line, it would be very boring. The same thing is true for programming. It would be too dull if the
statements in your program could only be executed in the order in which they appear.
In fact, an important task of a program is to instruct the computer to branch (that is, jump) to different portions of the
code and work on different jobs whenever the specified conditions are met.
However, in most cases, you don't know in advance what will come next. What you do know is that something is
bound to happen if certain conditions are met. Therefore, you can just write down tasks and conditions in the
program. The decisions of when to perform the tasks are made by the conditional branching statements.
In C, the if statement is the most popular conditional branching statement; it can be used to evaluate the conditions as
well as to make the decision whether the block of code controlled by the statement is going to be executed.
The general form of the if statement is
if (expression) {
statement1;
statement2;
.
.
.
}
Here expression is the conditional criterion. If expression is logical TRUE (that is, nonzero), the statements inside the
braces ({ and }), such as statement1 and statement2, are executed. If expression is logical FALSE (zero), then the
statements are skipped.
Note that the braces ({ and }) form a block of statements that is under the control of the if statement. If there is only
one statement inside the block, the braces can be ignored. The parentheses (( and )), however, must always be used to
enclose the conditional expression.
For instance, the following expression
if (x > 0)
printf("The square root of x is: %f\n", sqrt(x));
tells the computer that if the value of x is greater than zero (that is, positive), it should calculate the square root of x
by calling the sqrt() function, and then print out the result. Here the conditional criterion is the relational expression x
> 0, which returns 1 for true and 0 for false.
Listing 10.1 gives you another example of using the if statement.
TYPE
Listing 10.1. Using the if statement in decision making.
1: /* 10L01.c Using the if statement */
2: #include
3:
4: main()
5: {
6: int i;
7:
8: printf("Integers that can be divided by both 2 and 3\n");
9: printf("(within the range of 0 to 100):\n");
10: for (i=0; i<=100; i++){ 11: if ((i%2 == 0) && (i%3 == 0)) 12: printf(" %d\n", i); 13: } 14: return 0; 15: } OUTPUT After 10L01.exe, the executable of the program in Listing 10.1, is created and run from a DOS prompt, the following output is printed on the screen: C:\app> 10L01
Integers that can be divided by both 2 and 3
(within the range of 0 to 100):
0
6
12
18
24
30
36
42
48
54
60
66
72
78
84
90
96
C:\app>
ANALYSIS
As you see in Listing 10.1, line 6 declares an integer variable, i. Lines 8 and 9 print out two headlines.
Starting in line 10, the for statement keeps looping 101 times.
Within the for loop, the if statement in lines 11 and 12 evaluates the logical expression (i%2 == 0) && (i%3 == 0). If
the expression returns 1 (that is, the value of i can be divided by both 2 and 3 completely), the value of i is displayed
on the screen by calling the printf() function in line 12. Otherwise, the statement in line 12 is skipped.
Note that the braces ({ and }) are discarded in the if statement because there is only one statement under the control
of the statement.
The result shown on the screen gives all integers within the range of 0 to 100 that can be divided by both 2 and 3.
The if-else Statement
In the if statement, when the conditional expression is logical TRUE, the computer will jump to the statements
controlled by the if statement and execute them right away. If the expression is false, the computer will ignore those
statements controlled by the if statement.
From time to time, you will want the computer to execute some other specified statements when the conditional
expression of the if statement is logical FALSE. By doing so, you can use another conditional branching statement in
C—the if-else statement.
As an expansion of the if statement, the if-else statement has the following form:
if (expression) {
statement1;
statement2;
.
.
.
}
else {
statement_A;
statement_B;
.
.
.
}
Here if expression is logical TRUE, the statements controlled by if, including statement1 and statement2, are
executed. The statements, such as statement_A and statement_B, inside the statement block and following the else
keyword are executed if expression is not logical TRUE.
The program in Listing 10.2 shows how to use the if-else statement.
TYPE
Listing 10.2. Using the if-else statement.
1: /* 10L02.c Using the if-else statement */
2: #include
3:
4: main()
5: {
6: int i;
7:
8: printf("Even Number Odd Number\n");
9: for (i=0; i<10; 2 ="="">10L02
Even Number Odd Number
0 1
2 3
4 5
6 7
8 9
C:\app>
ANALYSIS
Line 6 of Listing 10.2 declares an integer variable, i. The printf() function in line 8 displays a headline on
the screen.
The integer variable i is initialized in the first expression field of the for statement in line 9. Controlled by the for
statement, the if-else statement in lines 10_13 is executed 10 times. According to the if-else statement, the printf()
function in line 11 prints out even numbers if the relational expression i%2 == 0 in line 10 returns 1 (that is, TRUE).
If the relational expression returns 0 (that is, FALSE), the printf() function controlled by the else keyword in line 12
outputs odd numbers to the standard output.
Because the if-else statement is treated as a single statement, the braces { and } are not needed to form a block of
statement in the for statement. Likewise, there are no braces used in the if-else statement because the if and else
keywords each control a single statement, respectively, in lines 11 and 13.
Note that the minimum width of 14 is specified in the printf() function in line 13, so the output of the odd numbers is
listed to the right side of the even numbers, as you can see in the output section. Because the program in Listing 10.2
checks numbers in a range of 0 to 9, the output shows that 0, 2, 4, 6, and 8 are even numbers, and 1, 3, 5, 7, and 9 are
odd ones.
Nested if Statements
As you saw in the previous sections, one if statement enables a program to make one decision. In many cases, a
program has to make a series of decisions. To enable it to do so, you can use nested if statements.
Listing 10.3 demonstrates the usage of nested if statements.
TYPE
Listing 10.3. Using nested if statements.
1: /* 10L03.c Using nested if statements */
2: #include
3:
4: main()
5: {
6: int i;
7:
8: for (i=-5; i<=5; i++){ 9: if (i > 0)
10: if (i%2 == 0)
11: printf("%d is an even number.\n", i);
12: else
13: printf("%d is an odd number.\n", i);
14: else if (i == 0)
15: printf("The number is zero.\n");
16: else
17: printf("Negative number: %d\n", i);
18: }
19: return 0;
20: }
OUTPUT
After running the executable file 10L03.exe, I obtain the following output:
C:\app>10L03
Negative number: -5
Negative number: -4
Negative number: -3
Negative number: -2
Negative number: -1
The number is zero.
1 is an odd number.
2 is an even number.
3 is an odd number.
4 is an even number.
5 is an odd number.
C:\app>
ANALYSIS
Listing 10.3 contains a for loop, starting in line 8 and ending in line 18. According to the expressions of
the for statement in line 8, any tasks controlled by the for statement are executed up to 11 times.
First, a decision has to be made based on the return value of the relational expression i > 0 in the if statement of line
9. The i > 0 expression is used to test whether the value of i is positive or negative (including zero.) If the return value
is 1, the computer jumps to the second (that is, nested) if statement in line 10.
Note that line 10 contains another relational expression, i%2 == 0, which tests whether the integer variable i is even
or odd. Therefore, the second decision of displaying even numbers or odd numbers has to be made according to the
return value of the second relational expression, i%2 == 0. The printf() function in line 11 prints out an even number
if the return value is 1. Otherwise, the statement in line 13 is executed, and an odd number is shown on the screen.
The computer branches to line 14 if the i > 0 expression returns 0; that is, if the value of i is not greater than 0. In line
14, another if statement is nested within an else phrase, and the relational expression i == 0 is evaluated. If i == 0 is
true, which means i contains the value of zero, the string of The number is zero. is displayed on the screen.
Otherwise, the value of i is negative, according to the value returned by the i > 0 expression. The statement in line 17
then outputs the negative number to the standard output.
As you can see in the example, the value of i is within the range of 5 to -5. Thus, -5, -4, -3, -2, and -1 are printed out
as negative numbers. In addition, the odd numbers 1, 3, and 5, as well as the even numbers 2 and 4, are also printed
out.
The switch Statement
In the last section, you saw that nested if statements are used when there is more than one decision to be made. The
nested if statements will become very complex if there are many decisions that need to be made, however.
Sometimes, the programmer will have problems following the complex if statements.
Fortunately there is another statement in C, the switch statement, that you can use to make unlimited decisions or
choices based on the value of a conditional expression and specified cases.
The general form of the switch statement is
switch (expression) {
case expression1:
statement1;
case expression2:
statement2;
.
.
.
default:
statement-default;
}
Here the conditional expression, expression, is evaluated first. If the return value of expression is equal to the constant
expression expression1, the statement statement1 is executed. If the value of expression is the same as the value of
expression2, statement2 is executed. If, however, the value of expression is not equal to any values of the constant
expressions labeled by the case keyword, the statement (statement-default) following the default keyword is executed.
You have to use the case keyword to label each case. The default keyword is recommended to be used for the default
case. Note that no constant expressions are identical in the switch statement.
The program in Listing 10.4 gives you an example of using the switch statement. The program also demonstrates an
important feature of the switch statement.
TYPE
Listing 10.4. Using the switch statement.
1: /* 10L04.c Using the switch statement */
2: #include
3:
4: main()
5: {
6: int day;
7:
8: printf("Please enter a single digit for a day\n");
9: printf("(within the range of 1 to 3):\n");
10: day = getchar();
11: switch (day){
12: case `1':
13: printf("Day 1\n");
14: case `2':
15: printf("Day 2\n");
16: case `3':
17: printf("Day 3\n");
18: default:
19: ;
20: }
21: return 0;
22: }
OUTPUT
If I run the executable file 10L04.exe and enter 3, I obtain the following output:
C:\app>10L04
Please enter a single digit for a day
(within the range of 1 to 3):
3
Day 3
C:\app>
ANALYSIS
As you can see in line 6, an int variable, day, is declared; it is assigned the input entered by the user in
line 10.
In line 11, the value of the integer variable day is evaluated in the switch statement. If the value is equal to one of the
values of the constant expressions, the computer starts to execute statements from there. The constant expressions are
labeled by prefixing case in front of them.
For instance, I entered 3 and then pressed the Enter key. The numeric value of 3 is assigned to day in line 10. Then,
after finding a case in which the value of the constant expression matches the value contained by day, the computer
jumps to line 17 to execute the printf() function and display Day 3 on the screen.
Note that under the default label in Listing 10.4, there is an empty (that is, null) statement ending with semicolon (;)
in line 19. The computer does nothing with the empty statement.
However, if I enter 1 from my keyboard and then press the Enter key, I get the following output:
C:\app>10L04
Please enter a single digit for a day
(within the range of 1 to 3):
1
Day 1
Day 2
Day 3
C:\app>
OUTPUT
From the output, you can see that the statement controlled by the selected case, case 1, and the statements
controlled by the rest of the cases are executed, because Day 1, Day 2, and Day 3 are displayed on the
screen. Likewise, if I enter 2 from my keyboard, I have Day2 and Day3 shown on the screen.
This is an important feature of the switch statement: The computer continues to execute the statements following the
selected case until the end of the switch statement.
You're going to learn how to exit from the switch construct in the next section.
The break Statement
You can add a break statement at the end of the statement list following every case label, if you want to exit the
switch construct after the statements within a selected case are executed.
The program in Listing 10.5 does a similar job as the one in Listing 10.4, but this time, the break statement is used.
TYPE
Listing 10.5. Adding the break statement.
1: /* 10L05.c Adding the break statement */
2: #include
3:
4: main()
5: {
6: int day;
7:
8: printf("Please enter a single digit for a day\n");
9: printf("(within the range of 1 to 7):\n");
10: day = getchar();
11: switch (day){
12: case `1':
13: printf("Day 1 is Sunday.\n");
14: break;
15: case `2':
16: printf("Day 2 is Monday.\n");
17: break;
18: case `3':
19: printf("Day 3 is Tuesday.\n");
20: break;
21: case `4':
22: printf("Day 4 is Wednesday.\n");
23: break;
24: case `5':
25: printf("Day 5 is Thursday.\n");
26: break;
27: case `6':
28: printf("Day 6 is Friday.\n");
29: break;
30: case `7':
31: printf("Day 7 is Saturday.\n");
32: break;
33: default:
34: printf("The digit is not within the range of 1 to 7.\n");
35: break;
36: }
37: return 0;
38: }
OUTPUT
With the help from the break statement, I can run the executable file 10L05.exe and only obtain the
output of the selected case:
C:\app>10L05
Please enter a single digit for a day
(within the range of 1 to 7):
1
Day 1 is Sunday.
C:\app>
ANALYSIS
This program has seven case labels followed by the constant expressions of `1', `2', `3', `4', `5', `6', and
`7', respectively. (See lines 12, 15, 18, 21, 24, 27, and 30.)
In each case, there is a statement followed by a break statement. As mentioned, the break statements help to exit the
switch construct after the statement in a selected case is executed.
For example, after the int variable day is assigned the value of 1 and evaluated in the switch statement, the case with
`1' is selected, and the statement in line 13 is executed. Then, the break statement in line 14 is executed, which breaks
the control of the switch statement and returns the control to the next statement outside the switch construct. In
Listing 10.5, the next statement is the return statement in line 37, which ends the main function.
The printf() function in line 13 outputs a string of Day 1 is Sunday. on the screen.
Note that in a switch statement, braces are not needed to group the statements within an individual case into a
statement block.
Breaking an Infinite Loop
You can also use the break statement to break an infinite loop. As you saw in Hour 7, the following for and while
loops are all infinite loops:
for (;;){
statement1;
statement2;
.
.
.
}
while (1){
statement1;
statement2;
.
.
.
}
The program in Listing 10.6 shows an example of using the break statement in an infinite while loop.
TYPE
Listing 10.6. Breaking an infinite loop.
1: /* 10L06.c: Breaking an infinite loop */
2: #include
3:
4: main()
5: {
6: int c;
7:
8: printf("Enter a character:\n(enter x to exit)\n");
9: while (1) {
10: c = getc(stdin);
11: if (c == `x')
12: break;
13: }
14: printf("Break the infinite while loop. Bye!\n");
15: return 0;
16: }
OUTPUT
The following is the result I got after running the executable file (10L06.exe) on my machine:
C:\app>10L06
Enter a character:
(enter x to exit)
H
Ix
Break the infinite while loop. Bye!
C:\app>
ANALYSIS
There is an infinite while loop in Listing 10.6, which starts in line 9 and ends in line 13. Within the
infinite loop, the characters the user entered are assigned, one at a time, to the integer variable c. (See line
10.)
The relational expression c == `x' in the if statement (see line 11) is evaluated each time during the looping. If the
expression returns 0 (that is, the user does not enter the letter x), the looping continues. Otherwise, the break
statement in line 12 is executed, which causes the computer to jump out of the infinite loop and start executing the
next statement, which is shown in line 14.
You can see in the sample output, the while loop continues until I have entered the letter x, which causes the infinite
loop to be broken and a piece of message, Break the infinite while loop. Bye!, to be displayed on the screen.
The continue Statement
Instead of breaking a loop, there are times when you want to stay in a loop but skip over some statements within the
loop. To do this, you can use the continue statement provided by C. The continue statement causes execution to jump
to the top of the loop immediately.
You should be aware that using the continue statement, as well as the break statement, may make your program hard
to debug.
For example, Listing 10.7 demonstrates how to use the continue statement in a loop doing sums.
TYPE
Listing 10.7. Using the continue statement.
1: /* 10L07.c: Using the continue statement */
2: #include
3:
4: main()
5: {
6: int i, sum;
7:
8: sum = 0;
9: for (i=1; i<8; i="="3)" i="="5))">10L07
The sum of 1, 2, 4, 6, and 7 is: 20
C:\app>
ANALYSIS
In Listing 10.7, we want to calculate the sum of the integer values of 1, 2, 4, 6, and 7. Because the
integers are almost consecutive, a for loop is built in lines 9_13. The statement in line 12 sums all
consecutive integers from 1 to 7 (except for 3 and 5, which aren't in the listing and are skipped in the for
loop).
By doing so, the expression (i==3) || (i==5) is evaluated in the if statement of line 10. If the expression returns 1 (that
is, the value of i is equal to either 3 or 5), the continue statement in line 11 is executed, which causes the sum
operation in line 12 to be skipped, and another iteration to be started at the beginning of the for loop. In this way, we
obtain the sum of the integer values of 1, 2, 4, 6, and 7, but skip 3 and 5, automatically by using one for loop.
After the for loop, the value of sum, 20, is displayed on the screen by the printf() function in the statement of line 14.
The goto Statement
I feel that this book would not be not complete without mentioning the goto statement, although I do not recommend
that you use the goto statement unless it's absolutely necessary. The main reason that the goto statement is
discouraged is because its usage may make the C program unreliable and hard to debug.
The following is the general form of the goto statement:
labelname:
statement1;
statement2;
.
.
.
goto labelname;
Here labelname is a label name that tells the goto statement where to jump. You have to place labelname in two
places: One is at the place where the goto statement is going to jump (note that a colon must follow the label name),
and the other is the place following the goto keyword. You have to follow the same rules to make a label name as you
name a variable or function.
Also, the place for the goto statement to jump to can appear either before or after the statement.
Summary
In this lesson you've learned the following:
 An important task of a program is to instruct the computer to jump to a different portion of the code according
to the specified branch conditions.
 The if statement is a very important statement for conditional branching in C.
 The if statement can be nested for making a series of decisions in your program.
 The if-else statement is an expansion of the if statement.
 The switch statement helps you to keep your program more readable when there are more than just a couple
decisions to be made in your code.
 The case and default keywords, followed by a colon (:) and an integral value, are used in the switch statement
as labels.
 The break statement can be used to exit the switch construct or a loop (usually, an infinite loop).
 The continue statement is used to let you stay within a loop while skipping over some statements.
 The goto statement enables the computer to jump to some other spot in your computer. Using this statement is
not recommended because it may cause your program to be unreliable and hard to debug.
In the next lesson you'll learn about a very important concept—pointers.
Q&A
Q How many expressions are there in the if statement?
A The if statement takes only one expression to hold the conditional criteria. When the expression is true
(that is, the conditions are met), the statements controlled by the if statement are executed. Otherwise, the
next statement following the if statement block is executed.
Q Why is the if-else statement an expansion of the if statement?
A When the conditional expression in the if statement is false, the program control flow is returned back
to the original track. However, when the conditional expression in the if-else statement is false, the
program control flow branches to the statement block under the else keyword and returns to its original
track after the statements controlled by else are executed. In other words, the if statement allows a single
statement block to be executed or skipped entirely, whereas the if-else statement executes one of the two
statement blocks under the control of the if-else statement.
Q Why do you normally need to add the break statement into the switch statement?
A When one of the cases within the switch statement is selected, the program control will branch to the
case and execute all statements within the selected case and the rest of the cases that follow it. Therefore,
you might get more results than you expected. To tell the computer to execute only the statements inside
a selected case, you can put a break statement at the end of the case so that the program control flow will
exit the switch construct after the statements within the case are executed.
Q What can the continue statement do inside a loop?
A When the continue statement inside a loop is executed, the program control is branched back to the
beginning of the loop so that another iteration can be started. Inside the loop, any statements following
the continue statement will be skipped over each time if the continue statement is executed.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. Given x = 0, will the arithmetic operations inside the following if statement be performed?
if (x != 0)
y = 123 / x + 456;
2. Given x = 4, y = 2, and operator = `-', what is the final value of x after the following switch statement is
executed?
switch (operator){
case `+': x += y;
case `-': x -= y;
case `*': x *= y;
case `/': x /= y;
default: break;
}
3. Similarly to in question 2, using x = 4, y = 2, and operator = `-', what is the final value of x after the following
switch statement is executed?
switch (operator){
case `+': x += y; break;
case `-': x -= y; break;
case `*': x *= y; break;
case `/': x /= y; break;
default: break;
}
4. What is the value of the integer variable x after the following code is executed?
x = 1;
for (i=2; i<10; 3 ="="" 6 ="="" x =" 7;" y =" &x;">
3:
4: main()
5: {
6: char c;
7: int x;
8: float y;
9:
10: printf("c: address=0x%p, content=%c\n", &c, c);
11: printf("x: address=0x%p, content=%d\n", &x, x);
12: printf("y: address=0x%p, content=%5.2f\n", &y, y);
13: c = `A';
14: x = 7;
15: y = 123.45;
16: printf("c: address=0x%p, content=%c\n", &c, c);
17: printf("x: address=0x%p, content=%d\n", &x, x);
18: printf("y: address=0x%p, content=%5.2f\n", &y, y);
19: return 0;
20: }
After the executable (11L01.exe) of this program is created and run from a DOS prompt, the following output is
displayed on the screen (note that you might get a different result, depending on your computer and operating
system):
OUTPUT
C:\app> 11L01
c: address=0x1AF4, content=@
x: address=0x1AF2, content=-32557
y: address=0x1AF6, content=0.00
c: address=0x1AF4, content=A
x: address=0x1AF2, content=7
y: address=0x1AF6, content=123.45
C:\app>
As you can see in Listing 11.1, there are three variables, c, x, and y, declared in lines 6_8, respectively.
ANALYSIS
The statement in line 10 displays the address (that is, the left value) and the content (that is, the right value) of the
character variable c on the screen. Here the &c expression returns the address of c.
Note that the format specifier %p is used in the printf() function of line 10 for displaying the address returned from
&c.
Likewise, lines 11 and 12 print out the addresses of x and y, as well as the contents of x and y.
From the first part of the output, you see that the addresses (in hex format) of c, x, and y are 0x1AF4, 0x1AF2, and
0x1AF6. Because these three variables have not been initialized yet, the contents contained in their memory locations
are what is left there from the last memory writing.
However, after the initializations that are carried on in lines 13_15, the memory slots reserved for the three variables
have the contents of the initial values. Lines 16_18 display the addresses and contents of c, x, and y after the
initialization.
You can see in the second part of the output, the contents of c, x, and y are now `A', 7, and 123.45, respectively, with
the same memory addresses.
Declaring Pointers
As mentioned at the beginning of this lesson, a pointer is a variable, which means that a pointer has a left value and a
right value as well. However, both the left and right values are addresses. The left value of a pointer is used to refer to
the pointer itself, whereas the right value of a pointer, which is the content of the pointer, is the address of another
variable.
NOTE
The format specifier %p used in the printf() function is supported by the ANSI standard. If, somehow,
your compiler does not support %p, you can try to use %u or %lu in the printf() function to convert and
print out a left value (that is, an address).
Also, the addresses printed out by the examples in this lesson are obtained by running the examples on
my machine. The values may be different from what you can get by running the examples on your
machine. This is because the address of a variable may vary from one type of computer to another.
The general form of a pointer declaration is
data-type *pointer-name;
Here data-type specifies the type of data to which the pointer points. pointer-name is the name of the pointer variable,
which can be any valid variable name in C.
Note that right before the pointer name is an asterisk (*), which indicates that the variable is a pointer. When the
compiler sees the asterisk in the declaration, it makes a note in its symbol table so that the variable can be used as a
pointer.
The following shows different types of pointers:
char *ptr_c; /* declare a pointer to a character */
int *ptr_int; /* declare a pointer to an integer */
float *ptr_flt; /* declare a pointer to a floating-point */
The program in Listing 11.2 demonstrates how to declare pointers and assign values to them.
TYPE
Listing 11.2. Declaring and assigning values to pointers.
1: /* 11L02.c: Declaring and assigning values to pointers */
2: #include
3:
4: main()
5: {
6: char c, *ptr_c;
7: int x, *ptr_x;
8: float y, *ptr_y;
9:
10: c = `A';
11: x = 7;
12: y = 123.45;
13: printf("c: address=0x%p, content=%c\n", &c, c);
14: printf("x: address=0x%p, content=%d\n", &x, x);
15: printf("y: address=0x%p, content=%5.2f\n", &y, y);
16: ptr_c = &c;
17: printf("ptr_c: address=0x%p, content=0x%p\n", &ptr_c, ptr_c);
18: printf("*ptr_c => %c\n", *ptr_c);
19: ptr_x = &x;
20: printf("ptr_x: address=0x%p, content=0x%p\n", &ptr_x, ptr_x);
21: printf("*ptr_x => %d\n", *ptr_x);
22: ptr_y = &y;
23: printf("ptr_y: address=0x%p, content=0x%p\n", &ptr_y, ptr_y);
24: printf("*ptr_y => %5.2f\n", *ptr_y);
25: return 0;
26: }
OUTPUT
I get the following output displayed on the screen after running the executable 11L02.exe from a DOS prompt on my
machine:
C:\app> 11L02
c: address=0x1B38, content=A
x: address=0x1B36, content=7
y: address=0x1B32, content=123.45
ptr_c: address=0x1B30, content=0x1B38
*ptr_c => A
ptr_x: address=0x1B2E, content=0x1B36
*ptr_x => 7
ptr_y: address=0x1B2C, content=0x1B32
*ptr_y => 123.45
C:\app>
ANALYSIS
In Listing 11.2, there are three variables, c, x, and y, and three pointer variables, ptr_c, ptr_x, and ptr_y, declared in
lines 6_8, respectively.
The statements in lines 10_12 initialize the three variables c, x, and y. Then, lines 13_15 print out the addresses as
well as the contents of the three variables.
In line 16, the left value of the character variable c is assigned to the pointer variable ptr_c. The output made by the
statement in line 17 shows that the pointer variable ptr_c contains the address of c. In other words, the content (that is,
the right value) of ptr_c is the address (that is, the left value) of c.
Then in line 18, the value referred to by the pointer *ptr_c is printed out. The output proves that the pointer *ptr_c
does point to the memory location of c.
Line 19 assigns the left value of the integer x to the integer pointer variable ptr_x. The statements in lines 20 and 21
print out the left value and right value of the pointer variable ptr_x, as well as the value referred to by the pointer
*ptr_x.
Similarly, the left value of the float variable y is assigned to the float pointer variable ptr_y in line 22. To prove that
ptr_y contains the address of y, and *ptr_y gives the content held by y, lines 23 and 24 print out the right values of
ptr_y and *ptr_y, respectively.
The statements in lines 16, 19, and 22 show you how to assign the value of a variable
to another—in an indirect way. In other words, the left value of a variable can be assigned to another variable so that
the latter can be used as a pointer variable to obtain the right value of the former. In this case, the variable name and
the pointer refer to the same memory location. Accordingly, if either the variable name or the pointer is used in an
expression to change the contents of the memory location, the contents of the memory location has changed for the
other.
Figure 11.1. The memory image of variables and their pointers.
To help you understand the indirection of assigning values, Figure 11.1 demonstrates the memory image of the
relationships between c and ptr_c, x and ptr_x, and y and ptr_y, based on the output obtained on my machine.
The Dereference Operator (*)
You've seen the asterisk (*) in the declaration of a pointer. In C, the asterisk is called the dereference operator when it
is used as a unary operator. (Sometimes, it's also called the indirection operator.) The value of a variable can be
referenced by the combination of the * operator and its operand, which contains the address of the variable.
For instance, in the program shown in Listing 11.2, after the address of the character variable c is assigned to the
pointer variable ptr_c, the expression *ptr_c refers to the value contained by c. Therefore, you can use the *ptr_c
expression, instead of calling the variable c directly, to obtain the value of c.
Likewise, given an integer variable x and x = 1234, you can declare an integer pointer variable, ptr_x, for instance,
and assign the left value (address) of x to ptr_x—that is, ptr_x = &x. Then, the expression *ptr_x returns 1234, which
is the right value (content) of x.
Null Pointers
A pointer is said to be a null pointer when its right value is 0. Remember, a null pointer can never point to valid data.
To set a null pointer, simply assign 0 to the pointer variable. For example:
char *ptr_c;
int *ptr_int;
ptr_c = ptr_int = 0;
Here ptr_c and ptr_int become null pointers after the integer value of 0 is assigned to them.
You'll see applications of null pointers used in control-flow statements and arrays later in this book.
Updating Variables via Pointers
As you learned in the previous section, as long as you link up a variable to a pointer variable, you can obtain the value
of the variable by using the pointer variable. In other words, you can read the value by pointing to the memory
location of the variable and using the dereferencing operator.
TYPE
This section shows you that you can write a new value to the memory location of a variable using a pointer that
contains the left value of the variable. Listing 11.3 gives an example.
Listing 11.3. Changing variable values via pointers.
1: /* 11L03.c: Changing values via pointers */
2: #include
3:
4: main()
5: {
6: char c, *ptr_c;
7:
8: c = `A';
9: printf("c: address=0x%p, content=%c\n", &c, c);
10: ptr_c = &c;
WARNING
Don't confuse the dereference operator with the multiplication operator, although they share the same
symbol, *.
The dereference operator is a unary operator, which takes only one operand. The operand contains the
address (that is, left value) of a variable.
On the other hand, the multiplication operator is a binary operator that requires two operands to perform
the operation of multiplication.
11: printf("ptr_c: address=0x%p, content=0x%p\n", &ptr_c, ptr_c);
12: printf("*ptr_c => %c\n", *ptr_c);
13: *ptr_c = `B';
14: printf("ptr_c: address=0x%p, content=0x%p\n", &ptr_c, ptr_c);
15: printf("*ptr_c => %c\n", *ptr_c);
16: printf("c: address=0x%p, content=%c\n", &c, c);
17: return 0;
18: }
OUTPUT
After running the executable 11L03.exe from a DOS prompt on my machine, I get the following output displayed on
the screen:
ANALYSIS
C:\app> 11L03
c: address=0x1828, content=A
ptr_c: address=0x1826, content=0x1828
*ptr_c => A
ptr_c: address=0x1826, content=0x1828
*ptr_c => B
c: address=0x1828, content=B
C:\app>
A char variable, c, and a char pointer variable, ptr_c, are declared in line 6 of List-ing 11.3.
The variable c is initialized with `A' in line 8, which is printed out, along with the address of the variable, by the
printf() function in line 9.
Then, in line 10, the pointer variable ptr_c is assigned the left value (address) of c. It's not surprising to see the output
printed out by the statements in lines 11 and 12, where the right value of ptr_c is the left value of c, and the pointer
*ptr_c points to the right value of c.
In line 13 the expression *ptr_c = `B' asks the computer to write `B' to the location pointed to by the pointer *ptr_c.
The output printed by the statement in line 15 proves that the content of the memory location pointed to by *ptr_c is
updated. The statement in line 14 prints out the left and right values of the pointer variable ptr_c and shows that these
values remain the same.
As you know, *ptr_c points to where the character variable c resides. Therefore, the expression *ptr_c = `B' actually
updates the content (that is, the right value) of the variable c to `B'. To prove this, the statement in line 16 displays the
left and right values of c on the screen. Sure enough, the output shows that the right value of c has been changed.
Pointing to the Same Thing
TYPE
A memory location can be pointed to by more than one pointer. For example, given that
c = `A' and that ptr_c1 and ptr_c2 are two character pointer variables, ptr_c1 = &c and ptr_c2 = &c set the two
pointer variables to point to the same location in the memory.
The program in Listing 11.4 shows another example of pointing to the same thing with several pointers.
Listing 11.4. Pointing to the same thing with more than one pointer.
1: /* 11L04.c: Pointing to the same thing */
2: #include
3:
4: main()
5: {
6: int x;
7: int *ptr_1, *ptr_2, *ptr_3;
8:
9: x = 1234;
10: printf("x: address=0x%p, content=%d\n", &x, x);
11: ptr_1 = &x;
12: printf("ptr_1: address=0x%p, content=0x%p\n", &ptr_1, ptr_1);
13: printf("*ptr_1 => %d\n", *ptr_1);
14: ptr_2 = &x;
15: printf("ptr_2: address=0x%p, content=0x%p\n", &ptr_2, ptr_2);
16: printf("*ptr_2 => %d\n", *ptr_2);
17: ptr_3 = ptr_1;
18: printf("ptr_3: address=0x%p, content=0x%p\n", &ptr_3, ptr_3);
19: printf("*ptr_3 => %d\n", *ptr_3);
20: return 0;
21: }
OUTPUT
The following output is displayed on the screen by running the executable 11L04.exe from a DOS prompt on my
machine (note that you might get different address values if you run the program on your machine):
C:\app> 11L04
x: address=0x1838, content=1234
ptr_1: address=0x1834, content=0x1838
*ptr_1 => 1234
ptr_2: address=0x1836, content=0x1838
*ptr_2 => 1234
ptr_3: address=0x1832, content=0x1838
*ptr_3 => 1234
C:\app>
ANALYSIS
As shown in Listing 11.4, line 6 declares an integer variable, x, and line 7 declares three integer pointer variables,
ptr_1, ptr_2, and ptr_3.
The statement in line 10 prints out the left and right values of x. On my machine, the left value (address) of x is
0x1838. The right value (content) of x is 1234, which is the initial value assigned to x in line 9.
Line 11 assigns the left value of x to the pointer variable ptr_1 so that ptr_1 can be used to refer to the right value of
x. To make sure that the pointer variable ptr_1 now contains the address of x, line 12 prints out the right value of
ptr_1, along with its left value. The output shows that ptr_1 does hold the address of x, 0x1838. Then, line 13 prints
out the value 1234, which is referred to by the *ptr_1 expression. Note that the asterisk * in the expression is the
dereference operator.
In line 14, the *ptr_2 = &x expression assigns the left value of x to another pointer variable, ptr_2; that is, the pointer
variable ptr_2 is now linked with the address of x. The statement in line 16 displays the integer 1234 on the screen by
using the dereference operator * and its operand, ptr_2. In other words, the memory location of x is referred to by the
second pointer *ptr_2.
In line 17, the pointer variable ptr_3 is assigned with the right value of ptr_1. Because ptr_1 now holds the address of
x, the expression ptr_3 = ptr_1 is equivalent to ptr_3 = &x. Then, from the output made by the statements in lines 18
and 19, you see the integer 1234 again on the screen. This time the integer is referred to by the third pointer, *ptr_3.
Summary
In this lesson you've learned the following:
 A pointer is a variable whose value is used to point to another variable.
 A variable declared in C has two values: the left value and the right value.
 The left value of a variable is the address; the right value is the content of the variable.
 The address-of operator (&) can be used to obtain the left value (address) of a variable.
 The asterisk (*) in a pointer declaration tells the compiler that the variable is a pointer variable.
 The dereference operator (*) is a unary operator; as such, it requires only one operand.
 The *ptr_name expression returns the value pointed to by the pointer variable ptr_name, where ptr_name can
be any valid variable name in C.
 If the right value of a pointer variable is 0, the pointer is a null pointer. A null pointer cannot point to valid data.
 You can update the value of a variable referred by a pointer variable.
 Several pointers can point to the same location of a variable in the memory.
In the next lesson you'll learn about an aggregate type—an array, which is closely related to pointers in C.
Q&A
Q What are the left and right values?
A The left value refers to the address of a variable, and the right value refers to the content stored in the
memory location of a variable. There are two ways to get the right value of a variable: use the variable
name directly, or use the left value of the variable to refer to where the right value resides. The second
way is also called the indirect way.
Q How can you obtain the address of a variable?
A By using the address-of operator, &. For instance, given an integer variable x, the &x expression
returns the address of x. To print out the address of x, you can use the %p format specifier in the printf()
function.
Q What is the concept of indirection in terms of using pointers?
A Before this hour, the only way you knew for reading from or writing to a variable was to invoke the
variable directly. For instance, if you wanted to write a decimal, 16, to an integer variable x, you could
call the statement x = 16;.
As you learned in this hour, C allows you to access a variable in another way—using pointers. Therefore,
to write 16 to x, you can first declare an integer pointer (ptr) and assign the left value (address) of x to
ptr—that is, ptr = &x;. Then, instead of executing the statement x = 16;, you can use another statement:
*ptr = 16;
Here the pointer *ptr refers to the memory location reserved by x, and the content stored in the memory
location is updated to 16 after the statement is executed. So, you see, making use of pointers to access the
memory locations of variables is a way of indirection.
Q Can a null pointer point to valid data?
A No. A null pointer cannot point to valid data. This is so because the value contained by a null pointer is
0. You'll see examples of using null pointers in arrays, strings, or memory allocation later in the book.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. How can you obtain the left value of a character variable ch?
2. In the following expressions, does the asterisk (*) act as a dereference operator or as a multiplication operator?
 *ptr
 x * y
 y *= x + 5
 *y *= *x + 5
3. Given that x = 10, the address of x is 0x1A38, and ptr_int = &x, what will ptr_int and *ptr_int return,
respectively?
4. Given that x = 123, and ptr_int = &x after the execution of *ptr_int = 456, what does x contain?
Exercises
1. Given three integer variables, x = 512, y = 1024, and z = 2048, write a program to print out their left values as
well as their right values.
2. Write a program to update the value of the double variable flt_num from 123.45 to 543.21 by using a double
pointer.
3. Given a character variable ch and ch = `A', write a program to update the value of ch to decimal 66 by using a
pointer.
4. Given that x=5 and y=6, write a program to calculate the multiplication of the two integers and print out the
result, which is saved in x, all in the way of indirection (that is, using pointers).
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 12 - Storing Similar Data Items
Gather up the fragments that remain, that nothing be lost.
—John 6:12
In last hour's lesson you learned about pointers and the concept of indirection. In this lesson you'll learn about arrays,
which are collections of similar data items and are closely related to pointers. The main topics covered in this lesson
are
 Single-dimension arrays
 Indexing arrays
 Pointers and arrays
 Character arrays
 Multidimensional arrays
 Unsized arrays
What Is an Array?
You now know how to declare a variable with a specified data type, such as char, int, float, or double. In many cases,
you have to declare a set of variables that have the same data type. Instead of declaring them individually, C allows
you to declare a set of variables of the same data type collectively as an array.
An array is a collection of variables that are of the same data type. Each item in an array is called an element. All
elements in an array are referenced by the name of the array and are stored in a set of consecutive memory slots.
Declaring Arrays
The following is the general form to declare an array:
data-type Array-Name[Array-Size];
Here data-type is the type specifier that indicates what data type the declared array will be. Array-Name is the name
of the declared array. Array-Size defines how many elements the array can contain. Note that the brackets ([ and ])
are required in declaring an array. The bracket pair ([ and ]) is also called the array subscript operator.
For example, an array of integers is declared in the following statement,
int array_int[8];
where int specifies the data type of the array whose name is array_int. The size of the array is 8, which means that the
array can store eight elements (that is, integers in this case).
In C, you have to declare an array explicitly, as you do for other variables, before you can
use it.
Indexing Arrays
After you declare an array, you can access each of the elements in the array separately.
For instance, the following declaration declares an array of characters:
char day[7];
You can access the elements in the array of day one after another.
The important thing to remember is that all arrays in C are indexed starting at 0. In other words, the index to the first
element in an array is 0, not 1. Therefore, the first element in the array of day is day[0]. Because there are 7 elements
in the day array, the last element is day[6], not day[7].
The seven elements of the array have the following expressions: day[0], day[1], day[2], day[3], day[4], day[5], and
day[6].
Because these expressions reference the elements in the array, they are sometimes called array element references.
Initializing Arrays
With the help of the array element references, you can initialize each element in an array.
For instance, you can initialize the first element in the array of day, which was declared in the last section, like this:
day[0] = `S';
Here the numeric value of S is assigned to the first element of day, day[0].
Likewise, the statement day[1] = `M'; assigns `M' to the second element, day[1], in the array.
The second way to initialize an array is to initialize all elements in the array together. For instance, the following
statement initializes an integer array, arInteger:
int arInteger[5] = {100, 8, 3, 365, 16};
Here the integers inside the braces ({ and }) are assigned to the corresponding elements of the array arInteger. That is,
100 is given to the first element (arInteger[0]), 8 to the second element (arInteger[1]), 3 to the third (arInteger[2]), and
so on.
Listing 12.1 gives another example of initializing arrays.
TYPE
Listing 12.1. Initializing an array.
1: /* 12L01.c: Initializing an array */
2: #include
3:
4: main()
5: {
6: int i;
7: int list_int[10];
8:
9: for (i=0; i<10;>12L01
list_int[0] is initialized with 1.
list_int[1] is initialized with 2.
list_int[2] is initialized with 3.
list_int[3] is initialized with 4.
list_int[4] is initialized with 5.
list_int[5] is initialized with 6.
list_int[6] is initialized with 7.
list_int[7] is initialized with 8.
list_int[8] is initialized with 9.
list_int[9] is initialized with 10.
C:\app>
ANALYSIS
As you can see in Listing 12.1, there is an integer array, called list_int, which is declared in line 7. The array list_int
can contain 10 elements.
Lines 9_12 make up a for loop that iterates 10 times. The statement in line 10 initializes list_int[i], the ith element of
the array list_int, with the value returned from the i + 1 expression.
Line 11 then prints out the name of the element, list_int[i], and the value assigned to the element.
The Size of an Array
As mentioned earlier in this lesson, an array consists of consecutive memory locations. Given an array, like this:
data-type Array-Name[Array-Size];
you can then calculate the total bytes of the array by the following expression:
sizeof(data-type) * Array-Size
Here data-type is the data type of the array; Array-Size specifies the total number of elements the array can take. The
result returned by the expression is the total number of bytes the array takes.
Another way to calculate the total bytes of an array is simpler; it uses the following expression:
sizeof(Array-Name)
Here Array-Name is the name of the array.
The program in Listing 12.2 shows how to calculate the memory space taken by an array.
TYPE
Listing 12.2. Calculating the size of an array.
1: /* 12L02.c: Total bytes of an array */
2: #include
3:
4: main()
5: {
6: int total_byte;
7: int list_int[10];
8:
9: total_byte = sizeof (int) * 10;
10: printf( "The size of int is %d-byte long.\n", sizeof (int));
11: printf( "The array of 10 ints has total %d bytes.\n", total_byte);
12: printf( "The address of the first element: 0x%x\n", &list_int[0]);
13: printf( "The address of the last element: 0x%x\n", &list_int[9]);
14: return 0;
15: }
OUTPUT
After running the executable 12L02.exe, I have the following output printed on my screen:
ANALYSIS
C:\app>12L02
The size of int is 2-byte long.
The array of 10 ints has total 20 bytes
The address of the first element: 0x1806
The address of the last element: 0x%1818
C:\app>
Note that you might get different address values when you run the program in Listing 12.2 on your machine.
However, the difference between the address of the first element and the address of the last element should be the
same as the one obtained from the output on my machine.
In Listing 12.2, there is an integer array, list_int, which is declared in line 7. The total memory space taken by the
array is the result of multiplying the size of int and the total number of elements in the array. As declared in this
example, there are a total of 10 elements in the array list_int.
The statement in line 10 prints out the size of int on my machine. You can see from the output that each integer
element in the array takes 2 bytes. Therefore, the total memory space (in bytes) taken by the array is 10 * 2. In other
words, the statement in line 9 assigns the value of 20, returned by the sizeof (int) * 10 expression, to the integer
variable total_byte. Line 11 then displays the value contained by the total_byte variable on the screen.
To prove that the array does take the consecutive memory space of 20 bytes, the address of the first element in the
array is printed out by the statement in line 12. Note that the ampersand (&), which was introduced as the address-of
operator in Hour 11, "An Introduction to Pointers," is used in line 12 to obtain the address of the first element, list_int
[0], in the array. Here the address of the first element is the start address of the array. From the output, you can see
that the address of the list_int[0] element is 0x1806 on my machine.
Then, the &list_int[9] expression in line 13 returns the address of the last element in the array, which is 0x1818 on
my machine. Thus, the distance between the last element and the first element is 0x1818_0x1806, or 18 bytes long.
As mentioned earlier in the book, hexadecimal is a 16-based numbering system. We know that 0x1818 minus 0x1806
produces 0x0012 (that is, 0x12). Then 0x12 in hexadecimal is equal to 1*16 + 2 that yields 18 in decimal.
Because each element takes 2 bytes, the total number of bytes taken by the array list_int is indeed 20 bytes. You can
calculate it another way: The distance between the last element and the first element is 18 bytes. The total number of
bytes taken by the array should be counted from the very first byte in the first element to the last byte in the last
element. Therefore, the total number bytes taken by the array is equal to 18 plus 2, that is 20 bytes.
Figure 12.1 shows you the memory space taken by the array list_int.
Figure 12.1. The memory space taken by the array list_int.
Arrays and Pointers
As I mentioned earlier in this hour, pointers and arrays have a close relationship in C. In fact, you can make a pointer
that refers to the first element of an array by simply assigning the array name to the pointer variable. If an array is
referenced by a pointer, the elements in the array can be accessed with the help of the pointer.
For instance, the following statements declare a pointer and an array, and assign the address of the first element to the
pointer variable:
char *ptr_c;
char list_c[10];
ptr_c = list_c;
Because the address of the first element in the array list_c is the beginning address of the array, the pointer variable
ptr_c is actually now referencing the array via the beginning address.
Listing 12.3 demonstrates how to reference an array with a pointer.
TYPE
Listing 12.3. Referencing an array with a pointer.
1: /* 12L03.c: Referencing an array with a pointer */
2: #include
3:
4: main()
5: {
6: int *ptr_int;
7: int list_int[10];
8: int i;
9:
10: for (i=0; i<10; ptr_int =" list_int;" ptr_int =" &list_int[0];">12L03
The start address of the array: 0x1802
The value of the first element: 1
The address of the first element: 0x1802
The value of the first element: 1
C:\app>
In Listing 12.3, an integer pointer variable, ptr_int, is declared in line 6. Then, an integer array, list_int, which is
declared in line 7, is initialized by the list_int[i] = i + 1 expression in a for loop. (See lines 10 and 11.)
The statement in line 12 assigns the address of the first element in the array to the pointer variable ptr_int. To do so,
the name of the array list_int is simply placed on the right side of the assignment operator (=) in line 12.
Line 13 displays the address assigned to the pointer variable ptr_int. The output shows that 0x1802 is the start address
of the array. (You might get a different address on your machine.) The *ptr_int expression in line 14 returns the value
referenced by the pointer. This value is the value contained by the first element of the array, which is the initial value,
1, given in the for loop. You can see that the output from the statement in line 14 shows the value correctly.
The statement in line 15 is equivalent to the one in line 12, which assigns the address of the first element to the
pointer variable. Lines 16 and 17 then print out the address and the value kept by the first element, 0x1802 and 1,
respectively.
In Hour 16, "Applying Pointers," you'll learn to access an element of an array by incrementing or decrementing a
pointer.
Displaying Arrays of Characters
This subsection focuses on arrays of characters. On most machines, the char data type takes one byte. Therefore, each
element in a character array is one byte long. The total number of elements in a character array is the total number of
bytes the array takes in the memory.
More importantly in C, a character string is defined as a character array whose last element is the null character (\0).
Hour 13, "Manipulating Strings," introduces more details about strings.
In Listing 12.4, you see various ways to display an array of characters on the screen.
TYPE
Listing 12.4. Printing out an array of characters.
1: /* 12L04.c: Printing out an array of characters */
2: #include
3:
4: main()
5: {
6: char array_ch[7] = {`H', `e', `l', `l', `o', `!', `\0'};
7: int i;
8:
9: for (i=0; i<7; i="0;">12L04
array_ch[0] contains: H
array_ch[1] contains: e
array_ch[2] contains: l
array_ch[3] contains: l
array_ch[4] contains: o
array_ch[5] contains: !
array_ch[6] contains:
Put all elements together(Method I):
Hello!
Put all elements together(Method II):
Hello!
C:\app>
As you can see from Listing 12.4, a character array, array_ch, is declared and initialized in line 6. Each element in the
character array is printed out by the printf() function in a for loop shown in lines 9 and 10. There are a total of seven
elements in the array; they contain the following character constants: `H', `e', `l', `l', `o', `!', and `\0'.
There are two ways to display all characters in the array, and to treat them as a character string.
Lines 12_14 show the first way, which fetches each individual element, array_ch[i], consecutively in a loop, and
prints out one character next to another by using the character format specifier %c in the printf() function in line 14.
The second way is simpler. You tell the printf() function where to find the first element to start with. Also, you need
to use the string format specifier %s in the printf() function as shown in line 17. Note that the array_ch expression in
line 17 contains the address of the first element in the array—that is, the start address of the array.
You may be wondering how the printf() function knows where the end of the character array is. Do you remember
that the last element in the character array array_ch is a \0 character? It's this null character that marks the end of the
character array. As I mentioned earlier, a character array ended with a null character is called a character string in C.
The Null Character (\0)
The null character (\0) is treated as one character in C; it is a special character that marks the end of a string.
Therefore, when functions like printf() act on a character string, they process one character after another until they
encounter the null character. (You'll learn more about strings in Hour 13.)
The null character (\0), which is always evaluated as FALSE, can also be used for a logical test in a control-flow
statement. Listing 12.5 gives an example of using the null character in a for loop.
TYPE
Listing 12.5. Stopping printing at the null character.
1: /* 12L05.c: Stopping at the null character */
2: #include
3:
4: main()
5: {
6: char array_ch[15] = {`C', ` `,
7: `i', `s', ` `,
8: `p', `o', `w', `e', `r',
9: `f', `u', `l', `!', `\0'};
10: int i;
11: /* array_ch[i] in logical test */
12: for (i=0; array_ch[i] != `\0'; i++)
13: printf("%c", array_ch[i]);
14: return 0;
15: }
OUTPUT
By running the executable 12L05.exe, I obtain the following output:
ANALYSIS
C:\app>12L05
C is powerful!
C:\app>
In Listing 12.5, a character array, array_ch, is declared and initialized with
the characters (including the space characters) from the string C is powerful!, in lines 6_9.
Note that the last element in the array contains the null character (\0), which is needed later in a for loop.
The for loop in lines 12 and 13 tries to print out each element in the array array_ch to show the string C is powerful!
on the screen. So in the first expression field of the for statement (loop), the integer variable i, which is used as the
index to the array, is initialized with 0.
Then, the expression in the second field, array_ch[i] != `\0', is evaluated. If the expression returns logical TRUE, the
for loop iterates; otherwise, the loop stops. Starting at the first element in the array, the array_ch[i] expression keeps
returning TRUE until the null character is encountered. Therefore, the for loop can put all characters of the array on
the screen, and stop printing right after the array_ch[i] returns logical FALSE. In fact, you can simplify the array_ch
[i] != `\0' expression in the second field of the for statement to array_ch[i] because `\0' is evaluated as FALSE
anyway.
Multidimensional Arrays
So far, all the arrays you've seen have been one-dimensional arrays, in which the dimension sizes are placed within a
pair of brackets ([ and ]).
In addition to one-dimensional arrays, the C language also supports multidimensional arrays. You can declare arrays
with as many dimensions as your compiler allows.
The general form of declaring a N-dimensional array is
data-type Array-Name[Array-Size1][Array-Size2]. . .
[Array-SizeN];
where N can be any positive integer.
Because the two-dimensional array, which is widely used, is the simplest form of the multidimensional array, let's
focus on two-dimensional arrays in this section. Anything you learn from this section can be applied to arrays of more
than two dimensions, however.
For example, the following statement declares a two-dimensional integer array:
int array_int[2][3];
Here there are two pairs of brackets that represent two dimensions with a size of 2 and 3 integer elements,
respectively.
You can initialize the two-dimensional array array_int in the following way:
TYPE
array_int[0][0] = 1;
array_int[0][1] = 2;
array_int[0][2] = 3;
array_int[1][0] = 4;
array_int[1][1] = 5;
array_int[1][2] = 6;
which is equivalent to the statement
int array_int[2][3] = {1, 2, 3, 4, 5, 6};
Also, you can initialize the array_int array in the following way:
int array_int[2][3] = {{1, 2, 3}, {4, 5, 6}};
Note that array_int[0][0] is the first element in the two-dimensional array array_int; array_int[0][1] is the second
element in the array; array_int[0][2] is the third element; array_int[1][0] is the fourth element; array_int[1][1] is the
fifth element; and array_int[1][2] is the sixth element in the array.
The program in Listing 12.6 shows a two-dimensional integer array that is initialized and printed out on the screen.
Listing 12.6. Printing out a two-dimensional array.
OUTPUT
1: /* 12L06.c: Printing out a 2-D array */
2: #include
3:
4: main()
5: {
6: int two_dim[3][5] = {1, 2, 3, 4, 5,
7: 10, 20, 30, 40, 50,
8: 100, 200, 300, 400, 500};
9: int i, j;
10:
11: for (i=0; i<3; j="0;">12L06
1 2 3 4 5
10 20 30 40 50
100 200 300 400 500
C:\app>
As you can see in Listing 12.6, there is a two-dimensional integer array, two_dim, declared and initialized in lines
6_8.
In lines 11_15, two for loops are nested together. The outer for loop increments the integer variable i and prints out
the newline character \n in each iteration. Here the integer variable i is used as the index to the first dimension of the
array, two_dim.
The inner for loop in lines 13 and 14 prints out each element, represented by the two_dim[i][j] expression, by
incrementing the index to the second dimension of the array. Therefore, I obtain output like the following
1 2 3 4 5
10 20 30 40 50
100 200 300 400 500
after the two nested for loops are run successfully.
Unsized Arrays
As you've seen, the size of a dimension is normally given during the declaration of an array. It means that you have to
count each element in an array. It could be tedious to do so, though, especially if there are many elements in an array.
The good news is that the C compiler can actually calculate a dimension size of an array automatically if an array is
declared as an unsized array. For example, when the compiler sees the following unsized array:
int list_int[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90};
it will create an array big enough to store all the elements.
TYPE
Likewise, you can declare a multidimensional unsized array. However, you have to specify all but the leftmost (that
is, the first) dimension size. For instance, the compiler can reserve enough memory space to hold all elements in the
following two-dimensional unsized array:
char list_ch[][2] = {
`a', `A',
`b', `B',
`c', `C',
`d', `D',
`e', `E',
`f', `F',
`g', `G'};
The program in Listing 12.7 initializes a one-dimensional character unsized array and a two-dimensional unsized
integer array, and then measures the memory spaces taken for storing the two arrays.
Listing 12.7. Initializing unsized arrays.
1: /* 12L07.c: Initializing unsized arrays */
2: #include
3:
OUTPUT
4: main()
5: {
6: char array_ch[] = {`C', ` `,
7: `i', `s', ` `,
8: `p', `o', `w', `e', `r',
9: `f', `u', `l', `!', `\0'};
10: int list_int[][3] = {
11: 1, 1, 1,
12: 2, 2, 8,
13: 3, 9, 27,
14: 4, 16, 64,
15: 5, 25, 125,
16: 6, 36, 216,
17: 7, 49, 343};
18:
19: printf("The size of array_ch[] is %d bytes.\n", sizeof (array_ch));
20: printf("The size of list_int[][3] is %d bytes.\n", sizeof (list_int));
21: return 0;
22: }
ANALYSIS
The following output is obtained by running the executable 12L07.exe:
C:\app>12L07
The size of array_ch[] is 15 bytes.
The size of list_int[][3] is 42 bytes.
C:\app>
A character unsized array, array_ch, is declared and initialized in lines 6_9. In
lines 10_17, a two-dimensional unsized integer array, list_int, is declared and initialized too.
The statement in line 19 measures and prints out the total memory space (in bytes) taken by the array array_ch. The
result shows that the unsized character array is assigned 15 bytes of memory to hold all its elements after compiling.
When you calculate the total number of the elements in the character array manually, you find that there are indeed 15
elements. Because each character takes one byte of memory, the character array array_ch takes a total of 15 bytes
accordingly.
Likewise, the statement in line 20 gives the total number of bytes reserved in the memory for the unsized twodimensional
integer array list_int. Because there are a total of 21 integer elements in the array, and an integer takes 2
bytes, the compiler should allocate 42 bytes for the integer array list_int. The result printed out by the printf()
function in line 20 proves that there are 42 bytes reserved in the memory for the two-dimensional integer array. (If the
size of int or char is different on your machine, you may get different values for the sizes of the arrays in the program
of Listing 12.7.)
Summary
In this lesson you've learned the following:
Page 185
 An array is a collection of variables that are of the same data type.
 In C, the index to an array starts at 0.
 You can initialize each individual element of an array after the declaration of the array, or you can place all
initial values into a data block surrounded by { and } during the declaration of an array.
 The memory storage taken by an array is determined by the product of the size of the data type and the
dimensions of the array.
 A pointer is said to refer to an array when the address of the first element in the array is assigned to the pointer.
The address of the first element in an array is also called the start address of the array.
 To assign the start address of an array to a pointer, you can either put the combination of the address-of
operator (&) and the first element name of the array, or simply use the array name, on the right side of an
assignment operator (=).
 A character array is considered a character string in C if the last element in the array contains a null character
(\0).
 The null character (\0) marks the end of a string. C functions, such as printf(), will stop processing the string
when the null character is encountered.
 C supports multidimensional arrays, too. A pair of brackets (the array subscript operator—[ and ]) indicates a
dimension.
 The compiler can automatically calculate the memory space needed by an unsized array.
In the next lesson you'll learn more about strings in C.
Q&A
Q Why do you need to use arrays?
A In many cases, you need to declare a set of variables that are of the same data type. Instead of
declaring each variable separately, you can declare all variables collectively in the format of an array.
Each variable, as an element of the array, can be accessed either through the array element reference or
through a pointer that references the array.
Q What is the minimum index in an array?
A In C, the minimum index of a one-dimensional array is 0, which marks the first element of the array.
For instance, given an integer array,
int array_int[8];
the first element of the array is array_int[0].
Likewise, for a multidimensional array, the minimum index of each dimension starts at 0.
Q How do you reference an array by using a pointer?
A You can use a pointer to reference an array by assigning the start address of an array to the pointer. For
example, given a pointer variable ptr_ch and a character array array_ch, you can use one of the following
statements to reference the array by the pointer:
ptr_ch = array_ch;
ptr_ch = &array_ch[0];
Q What can the null character do?
A The null character (\0) in C can be used to mark the end of a string. For instance, the printf() function
puts the next character on the screen when the null character is encountered. Also, the null character
always returns FALSE in a logical test.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the Workshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. What does the following statement do?
int array_int[4] = {12, 23, 9, 56};
2. Given an array, int data[3], what's wrong with the following initialization?
data[1] = 1;
data[2] = 2;
data[3] = 3;
3. How many dimensions do the following arrays have?
 char array1[3][19];
 int array2[];
 float array3[][8][16];
 char array4[][80];
4. What's wrong with the following declaration?
char list_ch[][] = {
`A', `a',
`B', `b',
`C', `c',
`D', `d',
`E', `e'};
Exercises
1. Given this character array:
char array_ch[5] = {`A', `B', `C', `D', `E'};
write a program to display each element of the array on the screen.
2. Rewrite the program in exercise 1, but this time use a for loop to initialize the character array with `a', `b', `c',
`d', and `e', and then print out the value of each element in the array.
3. Given this two-dimensional unsized array:
char list_ch[][2] = {
`1', `a',
`2', `b',
`3', `c',
`4', `d',
`5', `e',
`6', `f'};
write a program to measure the total bytes taken by the array, and then print out all elements of the array.
4. Rewrite the program in Listing 12.5. This time put a string of characters, I like C!, on the screen.
5. Given the following array:
double list_data[6] = {
1.12345,
2.12345,
3.12345,
4.12345,
5.12345};
use the two equivalent ways taught in this lesson to measure the total memory space taken by the array, and
then display the results on the screen.
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 13 - Manipulating Strings
I have made this letter longer than usual, because I lack the time to make it short.
—B. Pascal
In the last hour's lesson you learned how to use arrays to collect variables of the same type. You also learned that a
character string is actually a character array ended with a null character \0. In this lesson you'll learn more about
strings and C functions that can be used to manipulate strings. The following topics are covered:
 Declaring a string
 The length of a string
 Copying strings
 Reading strings with scanf(
 The gets() and puts() functions
Declaring Strings
This section teaches you how to declare and initialize strings, as well as the difference between string constants and
character constants. First, let's review the definition of a string.
What Is a String?
As introduced in Hour 12, "Storing Similar Data Items," a string is a character array terminated by a null character
(\0).
For instance, a character array, array_ch, declared in the following statement, is considered a character string:
char array_ch[7] = {`H', `e', `l', `l', `o', `!', `\0'};
In C, the null character can be used to mark the end of a string, or to return logical FALSE. C treats \0 as one
character. Each character in a string takes only 1 byte.
A series of characters enclosed in double quotes ("") is called a string constant. The C compiler can automatically add
a null character (\0) at the end of a string constant to indicate the end of the string.
For example, the character string "A character string." is considered a string constant; so is "Hello!".
Initializing Strings
As taught in the last lesson, a character array can be declared and initialized like this:
char arr_str[6] = {`H', `e', `l', `l', `o', `!'};
Here the array arr_str is treated as a character array. However, if you add a null character (\0) into the array, you can
have the following statement:
char arr_str[7] = {`H', `e', `l', `l', `o', `!', `\0'};
Here the array arr_str is expanded to hold seven elements; the last element contains a null character. Now, the
character array arr_str is considered a character string because of the null character that is appended to the array.
You can also initialize a character array with a string constant. For example, the following statement initializes a
character array, str, with a string constant, "Hello!":
char str[7] = "Hello!";
The compiler can automatically append a null character (\0) to the end of the array, and treat the character array as a
character string. Note that the size of the array is specified to hold up to seven elements, although the string constant
has only six characters enclosed in double quotes. The extra space is reserved for the null character that the compiler
will add later.
You can declare an unsized character array if you want the compiler to calculate the total number of elements in the
array. For instance, the following statement
char str[] = "I like C.";
initializes an unsized character array, str, with a string constant. Later, when the compiler sees the statement, it will
figure out the total memory space needed to hold the string constant plus an extra null character added by the
compiler itself.
If you like, you can also declare a char pointer and then initialize the pointer with a string constant. The following
statement is an example:
char *ptr_str = "I teach myself C.";
String Constants Versus Character Constants
As you know, a string constant is a series of characters enclosed in double quotes (" "). On the other hand, a character
constant is a character enclosed in single quotes (` `).
When a character variable ch and a character array str are initialized with the same character,
x, such as the following,
char ch = `x';
char str[] = "x";
1 byte is reserved for the character variable ch, and two bytes are allocated for the character array str. The reason that
an extra byte is needed for str is that the compiler has to append a null character to the array.
WARNING
Don't specify the size of a character array as too small. Otherwise, it cannot hold a string constant plus
an extra null character. For instance, the following declaration is considered illegal:
char str[4] = "text";
Note that many C compilers will not issue a warning or an error message on this incorrect declaration.
The runtime errors that could eventually arise as a result could be very difficult to debug. Therefore, it's
your responsibility to make sure you specify enough space for a string.
The following statement is a correct one, because it specifies the size of the character array str that is big
enough to hold the string constant plus an extra null character:
char str[5] = "text";
Another important thing is that a string is interpreted as a char pointer. Therefore, you can assign a character string to
a pointer variable directly, like this:
char *ptr_str;
ptr_str = "A character string.";
However, you can not assign a character constant to the pointer variable, as shown in the following:
ptr_str = `x'; /* It's wrong. */
In other words, the character constant `x' contains a right value, and the pointer variable ptr_str expects a left value.
But C requires the same kind of values on both sides of an assignment operator =.
It's legal to assign a character constant to a dereferenced char pointer like this:
char *ptr_str;
*ptr_str = `x';
Now the values on both sides of the = operator are of the same type.
The program in Listing 13.1 demonstrates how to initialize, or assign character arrays with string constants.
TYPE
Listing 13.1. Initializing strings.
1: /* 13L01.c: Initializing strings */
2: #include
3:
4: main()
5: {
6: char str1[] = {`A', ` `,
7: `s', `t', `r', `i', `n', `g', ` `,
8: `c', `o', `n', `s', `t', `a', `n', `t', `\0'};
9: char str2[] = "Another string constant";
10: char *ptr_str;
11: int i;
12:
13: /* print out str2 */
14: for (i=0; str1[i]; i++)
15: printf("%c", str1[i]);
16: printf("\n");
17: /* print out str2 */
18: for (i=0; str2[i]; i++)
19: printf("%c", str2[i]);
20: printf("\n");
21: /* assign a string to a pointer */
22: ptr_str = "Assign a string to a pointer.";
23: for (i=0; *ptr_str; i++)
24: printf("%c", *ptr_str++);
25: return 0;
26: }
OUTPUT
The following output is displayed on the screen after the executable 13L01.exe of the program in Listing 13.1 is
created and run from a DOS prompt:
ANALYSIS
C:\app>13L01
A string constant
Another string constant
Assign a string to a pointer.
C:\app>
As you can see from Listing 13.1, there are two character arrays, str1 and str2, that are declared and initialized in lines
6_9. In the declaration of str1, a set of character constants, including a null character, is used to initialize the array.
For str2, a string constant is assigned to the array in line 9. The compiler will append a null character to str2 later.
Note that both str1 and str2 are declared as unsized arrays for which the compiler can automatically figure out how
much memory is needed. The statement in line 10 declares a char pointer variable, ptr_str.
The for loop in lines 14 and 15 then prints out all the elements in str1. Because the last element contains a null
character (\0) that is evaluated as FALSE, the str1[i] expression is used in the second field of the for statement. The
str1[i] expression returns logical TRUE for each element in str1 except the last one holding the null character. After
the execution of the for loop, the string A string constant is shown on the screen.
Likewise, another for loop in lines 18 and 19 displays the string constant assigned to str2 by putting every element of
the array on the screen. Because the compiler appends a null character to the array, the str2[i] expression is evaluated
in the for statement. The for loop stops iterating when str2[i] returns a logical FALSE. By that time, the content of the
string constant, Another string constant, has already been displayed on the screen.
The statement in line 22 assigns a string constant, "Assign a string to a pointer.", to the char pointer variable ptr_str.
Also, a for loop is used to print out the string constant by putting every item in the string on the screen (see lines 23
and 24). Note that the dereferenced pointer *ptr_str is used to refer to one of the characters in the string constant.
When the null character appended to the string is encountered, *ptr_str returns logical FALSE, which causes the
iteration of the for loop to stop. In line 24, the *ptr_str++ expression indicates that the dereferenced pointer moves to
the next character of the string after the current character referred to by the pointer is fetched. In Hour 16, "Applying
Pointers," you'll learn more about pointer arithmetic.
How Long Is a String?
Sometimes, you need to know how many bytes are taken by a string. In C, you can use a function called strlen() to
measure the length of a string.
The strlen() Function
Let's have a look at the syntax of the strlen() function.
The syntax for the strlen() function is
#include
size_t strlen(const char *s);
Here s is a char pointer variable. The return value from the function is the number of bytes. size_t is a data type
defined in the string.h header file. The size of the data type depends on the particular computer system. Note that
string.h has to be included in your program before you can call the strlen() function.
Listing 13.2 gives an example of using the strlen() function to measure string lengths.
TYPE
Listing 13.2. Measuring string lengths.
1: /* 13L02.c: Measuring string length */
2: #include
3: #include
4:
5: main()
6: {
7: char str1[] = {`A', ` `,
8: `s', `t', `r', `i', `n', `g', ` `,
9: `c', `o', `n', `s', `t', `a', `n', `t', `\0'};
10: char str2[] = "Another string constant";
11: char *ptr_str = "Assign a string to a pointer.";
12:
13: printf("The length of str1 is: %d bytes\n", strlen(str1));
14: printf("The length of str2 is: %d bytes\n", strlen(str2));
15: printf("The length of the string assigned to ptr_str is: %d bytes\n",
16: strlen(ptr_str));
17: return 0;
18: }
OUTPUT
I get the following output by running the executable 13L02.exe of the program in Listing 13.2 from a DOS prompt:
ANALYSIS
C:\app>13L02
The length of str1 is: 17 bytes
The length of str2 is: 23 bytes
The length of the string assigned to ptr_str is: 29 bytes
C:\app>
In Listing 13.2, two char arrays, str1 and str2, and one pointer variable, ptr_str, are declared and initialized in lines
7_11, respectively.
Then, the statement in line 13 obtains the length of the string constant held by str1, and prints out the result on the
screen. From the result, you can see that the null character (\0) contained by the last element of str1 is not counted by
the strlen() function.
In lines 14_16, the lengths of the string constants referenced by str2 and ptr_str are measured and shown on the
screen. The results indicate that the strlen() function does not count the null characters appended to the two string
constants by the compiler, either.
Copying Strings with strcpy()
If you want to copy a string from one array to another, you can copy each item of the first array to the corresponding
element in the second array, or you can simply call the C function strcpy() to do the job for you.
The syntax for the strcpy() function is
#include
char *strcpy(char *dest, const char *src);
Here the content of the string src is copied to the array referenced by dest. The strcpy() function returns the value of
src if it is successful. The header file string.h must be included in your program before the strcpy() function is called.
The program in Listing 13.3 demonstrates how to copy a string from one array to another by either calling the strcpy()
function or by doing it yourself.
TYPE
Listing 13.3. Copying strings.
1: /* 13L03.c: Copying strings */
2: #include
3: #include
4:
5: main()
6: {
7: char str1[] = "Copy a string.";
8: char str2[15];
9: char str3[15];
10: int i;
11:
12: /* with strcpy() */
13: strcpy(str2, str1);
14: /* without strcpy() */
15: for (i=0; str1[i]; i++)
16: str3[i] = str1[i];
17: str3[i] = `\0';
18: /* display str2 and str3 */
19: printf("The content of str2: %s\n", str2);
20: printf("The content of str3: %s\n", str3);
21: return 0;
22: }
OUTPUT
After the executable 13L03.exe is created and run, the following output is shown on the screen:
ANALYSIS
C:\app>13L03
The content of str2: Copy a string.
The content of str3: Copy a string.
C:\app>
Three char arrays, str1, str2, and str3, are declared in Listing 13.3. In addition, str1 is initialized with a string constant,
"Copy a string.", in line 7.
The statement in line 13 calls the strcpy() function to copy the content of str1 (including the null character appended
by the compiler) to the array referenced by str2.
Lines 15_17 demonstrate another way to copy the content of str1 to an array referenced by str3. To do so, the for loop
in lines 15 and 16 keeps copying characters of str1 to the corresponding elements in str3 one after another, until the
null character (\0) appended by the compiler is encountered. When the null character is encountered, the str1[i]
expression used as the condition of the for statement in line 15 returns logical FALSE, which in turn causes the loop
to stop.
Because the for loop does not copy the null character from str1 to str3, the statement in line 17 appends a null
character to the array referenced by str3. In C, it's very important to make sure that an array that is used to store a
string has a null character as its last element.
To prove that the string constant referenced by str1 has been copied to str2 and str3 successfully, the contents held by
str2 and str3 are displayed on the screen. Note that the string format specifier %s and the start addresses of str2 and
str3 are invoked in the printf() function in lines 19 and 20 to print out all characters, except the null character, stored
in str2 or str3. The results displayed on the screen show that str2 and str3 have the exact same content as str1.
Reading and Writing Strings
Now let's focus on how to read or write strings with the standard input and output streams—that is, stdin and stdout.
In C, there are several functions you can use to deal with string reading or writing. The following subsections
introduce some of the functions.
The gets() and puts() Functions
The gets() function can be used to read characters from the standard input stream.
The syntax for the gets() function is
#include
char *gets(char *s);
Here the characters read from the standard input stream are stored in the character array identified by s. The gets()
function stops reading, and appends a null character \0 to the array, when a newline or end-of-file (EOF) is
encountered. The function returns s if it concludes successfully. Otherwise, a null pointer is returned.
The puts() function can be used to write characters to the standard output stream (that is, stdout).
The syntax for the puts() function is
#include
int puts(const char *s);
Here s refers to the character array that contains a string. The puts() function writes the
string to the stdout. If the function is successful, it returns 0. Otherwise, a nonzero value is returned.
The puts() function appends a newline character to replace the null character at the end of a character array.
Both the gets() and puts() functions require the header file stdio.h. In Listing 13.4, you can see the application of the
two functions.
TYPE
Listing 13.4. Using the gets() and puts() functions.
1: /* 13L04.c: Using gets() and puts() */
2: #include
3:
4: main()
5: {
6: char str[80];
7: int i, delt = `a' - `A';
8:
9: printf("Enter a string less than 80 characters:\n");
10: gets( str );
11: i = 0;
12: while (str[i]){
13: if ((str[i] >= `a') && (str[i] <= `z')) 14: str[i] -= delt; /* convert to upper case */ 15: ++i; 16: } 17: printf("The entered string is (in uppercase):\n"); 18: puts( str ); 19: return 0; 20: } ANALYSIS After running the executable 13L04.exe, I enter a line of characters from the keyboard and have the characters (all in uppercase) shown on the screen: OUTPUT C:\app>13L04
Enter a string less than 80 characters:
This is a test.
The entered string is (in uppercase):
THIS IS A TEST.
C:\app>
The program in Listing 13.4 accepts a string of characters entered from the keyboard (that is, stdin), and then converts
all lowercase characters to uppercase ones. Finally, the modified string is put back to the screen.
In line 6, a character array (str) is declared that can hold up to 80 characters. The gets() function in line 10 reads any
characters the user enters from the keyboard until the user presses the Enter key, which is interpreted as a newline
character. The characters read in by the gets() function are stored into the character array indicated by str. The
newline character is not saved into str. Instead, a null character is appended to the array as a terminator.
The while loop in lines 12_15 has a conditional expression, str[i]. The while loop keeps iterating as long as str[i]
returns logical TRUE. Within the loop, the value of each character represented by str[i] is evaluated in line 13, to find
out whether the character is a lowercase character within the range of a through z. If the character is one of the
lowercase characters, it is converted into uppercase by subtracting the value of an int variable, delt, from its current
value in line 14. The delt variable is initialized in line 7 by the value of the `a' - `A' expression, which is the difference
between a lowercase character and its uppercase counterpart. In other words, by subtracting the difference of `a' and
`A' from the lower case integer value, we obtain the uppercase integer value.
Then the puts() function in line 18 outputs the string with all uppercase characters to stdout, which leads to the screen
by default. A newline character is appended by the puts() function to replace the null character at the end of the string.
Using %s with the printf() Function
We've used the printf() function in many program examples in this book. As you know, many format specifiers can
be used with the printf() function to specify different display formats for numbers of various types.
For instance, you can use the string format specifier, %s, with the printf() function to display a character string saved
in an array on the screen. (See the example in Listing 13.3.)
In the next section, the scanf() function is introduced as a way to read values of various data types with different
format specifiers, including the format specifier %s.
The scanf() Function
The scanf() function provides another way to read strings from the standard input stream. Moreover, this function can
actually be used to read various types of input data. The formats of arguments to the scanf() function are quite similar
to those used in the printf() function.
The syntax for the scanf() function is
#include
int scanf(const char *format, …);
Here various format specifiers can be included inside the format string referenced by the char pointer variable format.
If the scanf() function concludes successfully, it returns the num-ber of data items read from the stdin. If an error
occurs, the scanf() function returns EOF (end-of-file).
Note that using the string format specifier %s causes the scanf() function to read characters until a space, a newline, a
tab, a vertical tab, or a form feed is encountered. Characters read by the scanf() function are stored into an array
referenced by the corresponding argument. The array should be big enough to store the input characters.
A null character is automatically appended to the array after the reading.
The program in Listing 13.5 shows how to use various format specifiers with the scanf() function.
TYPE
Listing 13.5. Using the scanf() function with various format specifiers.
1: /* 13L05.c: Using scanf() */
2: #include
3:
4: main()
5: {
6: char str[80];
7: int x, y;
8: float z;
9:
10: printf("Enter two integers separated by a space:\n");
11: scanf("%d %d", &x, &y);
12: printf("Enter a floating-point number:\n");
13: scanf("%f", &z);
14: printf("Enter a string:\n");
15: scanf("%s", str);
16: printf("Here are what you've entered:\n");
17: printf("%d %d\n%f\n%s\n", x, y, z, str);
18: return 0;
19: }
OUTPUT
The following output is a sample displayed on the screen after I run the executable 13L05.exe and enter data (which
appears in bold) from my keyboard:
ANALYSIS
C:\app>13L05
Enter two integers separated by a space:
10 12345
Enter a floating-point number:
1.234567
Enter a string:
Test
Here are what you've entered:
10 12345
1.234567
Test
C:\app>
In Listing 13.5, there are one char array (str), two int variables (x and y), and a float variable (z) declared in lines 6_8.
Then, the scanf() function in line 11 reads in two integers entered by the user and saves them into the memory
locations reserved for the integer variables x and y. The statement in line 13 reads and stores a floating-point number
into z. Note that the format specifiers, %d and %f, are used to specify proper formats for entered numbers in lines 11
and 13.
Line 15 reads a series of characters entered by the user with the scanf() function by using the format specifier %s, and
then saves the characters, plus a null character as the terminator, into the array pointed to by str.
To prove that the scanf() function reads all the numbers and characters entered by the user, the printf() function in line
17 displays the contents saved in x, y, z, and str on the screen. Sure enough, the result shows that the scanf() does a
good job.
One thing you need to be aware of is that the scanf() function doesn't actually start reading the input until the Enter
key is pressed. Data entered from the keyboard is placed in an input buffer. When the Enter key is pressed, the scanf()
function looks for its input in the buffer. You'll learn more about buffered input and output in Hour 21, "Disk File
Input and Output: Part I."
Summary
In this lesson you've learned the following:
 A string is a character array with a null character as the terminator at the last element.
 A string constant is a series of characters enclosed by double quotes.
 The C compiler automatically appends a null character to the array that has been initialized by a string constant.
 You cannot assign a string constant to a dereferenced char pointer.
 The strlen() function can be used to measure the length of a string. This function does not count the null
character in the last element.
 You can copy a string from one array to another by calling the C function strcpy().
 The gets() function can be used to read a series of characters. This function stops reading when the newline
character or end-of-file (EOF) is encountered. A null character is attached to the array that stores the characters
automatically after the reading.
 The puts() function sends all characters, except the null character, in a string to the stdout, and appends a
newline character to the output.
 You can read different data items with the scanf() function by using various format specifiers.
In the next lesson you'll learn about the concepts of scope and storage in C.
Q&A
Q What is a string? How do you know its length?
A In C, a string is a character array terminated by a null character. Whenever a null character is
encountered in a string, functions, such as puts() or strcpy(), will stop printing or copying the next
character.
The C function strlen() can be used to measure the length of a string. If it is successful, the strlen()
function returns the total number of bytes taken by the string; however, the null character in the string is
not counted.
Q What are the main differences between a string constant and a character constant?
A A string constant is a series of characters enclosed by double quotes, while a character constant is a
single character surrounded by single quotes. The compiler will append a null character to the array that
is initialized with a string constant. Therefore, an extra byte has to be reserved for the null character. On
the other hand, a character constant takes only 1 byte in the memory.
Q Does the gets() function save the newline character from the standard input stream?
A No. The gets() function keeps reading characters from the standard input stream until a newline
character or end-of-file is encountered. Instead of saving the newline character, the gets() function
appends a null character to the array that is referenced by the argument to the gets() function.
Q What types of data can the scanf() function read?
A Depending on the format specifiers indicated in the function, the scanf() function can read various
types of data, such as a series of characters, integers, or floating-point numbers. Unlike gets(), scanf()
stops reading the current input item (and moves to the next input item, if there is one) when it encounters
a space, a newline, a tab, a vertical tab, or a form feed.
Workshop
To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish
the exercises provided in the W orkshop before you move to the next lesson. The answers and hints to the questions
and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises."
Quiz
1. In the following list, which statements are legal?
 char str1[5] = "Texas";
 char str2[] = "A character string";
 char str3[2] = "A";
 char str4[2] = "TX";
2. Given a char pointer variable ptr_ch, are the following statements legal?
 *ptr_ch = `a';
 ptr_ch = "A character string";
 ptr_ch = `x';
 *ptr_ch = "This is Quiz 2.";
3. Can the puts() function print out the null character in a character array?
4. Which format specifier do you use with the scanf() function to read in a string, and which one do you use to
read a floating-point number?
Exercises
1. Given a character array in the following statement,
char str1[] = "This is Exercise 1.";
write a program to copy the string from str1 to another array, called str2.
2. Write a program to measure the length of a string by evaluating the elements in the character array one by one.
To prove you get the right result, you can use the strlen() function to measure the same string again.
3. Rewrite the program in Listing 13.4. This time, convert all uppercase characters to their lowercase counterparts.
4. Write a program that uses the scanf() function to read in two integers entered by the user, adds the two integers,
and then prints out the sum on the screen.
Previous | Table of Contents | Next
Sams Teach Yourself C in 24 Hours
Previous | Table of Contents | Next
Hour 14 - Scope and Storage Classes in C
Nobody owns anything and all anyone has is the use of his presumed possessions.
—P. Wylie
In the previous hours, you've learned how to declare variables of different data types, as well as to initialize and use
those variables. It's been assumed that you can access variables from anywhere. Now, the question is: Can we declare
variables that are accessible only to certain portions of a program? In this lesson you'll learn about the scope and
storage classes of data in C. The main topics covered in this lesson are
 Block scope
 Function scope
 File scope
 Program scope
 The auto specifier
 The static specifier
 The register specifier
 The extern specifier
 The const modifier
 The volatile modifier
Hiding Data
To solve a complex problem in practice, the programmer normally breaks the problem into smaller pieces and deals
with each piece of the problem by writing one or two functions (or routines). Then, all the functions are put together
to form a complete program that can be used to solve the complex problem.
In the complete program, there might be variables that have to be shared by all the functions. On the other hand, the
use of some other variables may be limited to only certain functions. That is, the visibility of those variables is
limited, and values assigned to those variables are hidden from many functions.
Limiting the scope of variables is very useful when several programmers are working on different pieces of the same
program. If they limit the scope of their variables to their pieces of code, they do not have to worry about conflicting
with variables of the same name used by others in other parts of the program.
In C, you can declare a variable and indicate its visibility level by designating its scope. Thus, variables with local
scope can only be accessed within the block in which they are declared.
The following sections teach you how to declare variables with different scopes.
Block Scope
In this section, a block refers to any sets of statements enclosed in braces ({ and }). A variable declared within a block
has block scope. Thus, the variable is active and accessible from its declaration point to the end of the block.
Sometimes, block scope is also called local scope.
For example, the variable i declared within the block of the following main function has block scope:
int main()
{
int i; /* block scope */
.
.
.
return 0;
}
Usually, a variable with block scope is called a local variable.
Nested Block Scope
You can also declare variables within a nested block. If a variable declared in the outer block shares the same name
with one of the variables in the inner block, the variable within the outer block is hidden by the one within the inner
block for the scope of the inner block.
Listing 14.1 gives an example of variable scopes in nested blocks.
TYPE
Listing 14.1. Printing out variables with different scope levels.
1: /* 14L01.c: Scopes in nested block */
2: #include
3:
4: main()
5: {
6: int i = 32; /* block scope 1*/
7:
8: printf("Within the outer block: i=%d\n", i);
9:
10: { /* the beginning of the inner block */
11: int i, j; /* block scope 2, int i hides the outer int i*/
12:
13: printf("Within the inner block:\n");
14: for (i=0, j=10; i<=10; i++, j--) 15: printf("i=%2d, j=%2d\n", i, j); 16: } /* the end of the inner block */ 17: printf("Within the outer block: i=%d\n", i); 18: return 0; 19: } The following output is displayed on the screen after the executable (14L01.exe) of the program in Listing 14.1 is created and run from a DOS prompt: OUTPUT C:\app>14L01
Within the outer block: i=32
Within the inner block:
i= 0, j=10
i= 1, j= 9
i= 2, j= 8
i= 3, j= 7
i= 4, j= 6
i= 5, j= 5
i= 6, j= 4
i= 7, j= 3
i= 8, j= 2
i= 9, j= 1
i=10, j= 0
Within the outer block: i=32
C:\app>
ANALYSIS
The purpose of the program in Listing 14.1 is to show you the different scopes of variables in nested blocks. As you
can see, there are two nested blocks in Listing 14.1. The integer variable i declared in line 6 is visible within the outer
block enclosed by the braces ({ and }) in lines 5 and 19. Another two integer variables, i and j, declared in line 11, are
visible only within the inner block from line 10 to line 16.
Although the integer variable i within the outer block has the same name as one of the integer variables within the
inner block, the two integer variables can not be accessed at the same time due to their different scopes.
To prove this, line 8 prints out the value, 32, contained by i within the outer block for the first time. Then, the for loop
in lines 14 and 15 displays 10 pairs of values assigned to i and j within the inner block. At this point, there is no sign
showing that the integer variable i within the outer block has any effects on the one within the inner block. When the
inner block is exited, the variables within the inner block are no longer accessible.
Finally, the statement in line 17 prints out the value of i within the outer block again to find out whether the value has
been changed due to the integer variable i within the inner block. The result shows that these two integer variables
hide from each other, and no conflict occurs.
Function Scope
Function scope indicates that a variable is active and visible from the beginning to the end of a function.
In C, only the goto label has function scope. For example, the goto label, start, shown in the following code portion
has function scope:
int main()
{
int i; /* block scope */
.
.
.
start: /* A goto label has function scope */
.
.
.
goto start; /* the goto statement */
.
.
.
return 0;
}
Here the label start is visible from the beginning to the end of the main() function. Therefore, there should not be
more than one label having the same name within the main() function.
Program Scope
A variable is said to have program scope when it is declared outside a function. For instance, look at the following
code:
int x = 0; /* program scope */
float y = 0.0; /* program scope */
int main()
{
int i; /* block scope */
.
.
.
return 0;
}
Here the int variable x and the float variable y have program scope.
Variables with program scope are also called global variables, which are visible among different files. These files are
the entire source files that make up an executable program. Note that a global variable is declared with an initializer
outside a function.
The program in Listing 14.2 demonstrates the relationship between variables with program scope and variables with
block scope.
TYPE
Listing 14.2. The relationship between program scope and block scope.
1: /* 14L02.c: Program scope vs block scope */
2: #include
3:
4: int x = 1234; /* program scope */
5: double y = 1.234567; /* program scope */
6:
7: void function_1()
8: {
9: printf("From function_1:\n x=%d, y=%f\n", x, y);
10: }
11:
12: main()
13: {
14: int x = 4321; /* block scope 1*/
15:
16: function_1();
17: printf("Within the main block:\n x=%d, y=%f\n", x, y);
18: /* a nested block */
19: {
20: double y = 7.654321; /* block scope 2 */
21: function_1();
22: printf("Within the nested block:\n x=%d, y=%f\n", x, y);
23: }
24: return 0;
25: }
I have the following output shown on the screen after the executable 14L02.exe is created and run from a DOS
prompt:
OUTPUT
C:\app>14L02
From function_1:
x=1234, y=1.234567
Within the main block:
x=4321, y=1.234567
From function_1:
x=1234, y=1.234567
Within the nested block:
x=4321, y=7.654321
C:\app>
ANALYSIS
As you can see in Listing 14.2, there are two global variables, x and y, with program scope; they are declared in lines
4 and 5.
In lines 7_10, a function, called function_1(), is declared. (More details about function declarations and prototypes
are taught in the next hour.) The function_1() function contains only one statement; it prints out the values held by
both x and y. Because there is no variable declaration made for x or y within the function block, the values of the
global variables x and y are used for the statement inside the function. To prove this, the function_1() function is
called twice in lines 16 and 21, respectively, from two nested blocks. The output shows that the values of the two
global variables x and y are passed to printf() enclosed in the function_1() function body.
Then, line 14 declares another integer variable, x, with block scope, which can replace the global variable x within the
block of the main() function. The result made by the statement in line 17 shows that the value of x is the value of the
local variable x with block scope, while the value of y is still that of the global variable y.
There is a nested block in lines 19 and 23, within which another double variable y, with block scope, is declared and
initialized. Like the variable x within the main() block, this variable, y, within the nested block replaces the global
variable y. The statement in line 22 puts the values of the local variables x and y on the screen.
Before I introduce file scope, let's talk about the storage class specifiers.
The Storage Class Specifiers
In C, the storage class of a variable refers to the combination of its spatial and temporal regions.
You've learned about scope, which specifies the spatial region of a variable. Now, let's focus on duration, which
indicates the temporal region of a variable.
There are four specifiers and two modifiers that can be used to indicate the duration of a variable. These specifiers
and modifiers are introduced in the following sections.
The auto Specifier
The auto specifier indicates that the memory location of a variable is temporary. In other words, a variable's reserved
space in the memory can be erased or relocated when the variable is out of its scope.
Only variables with block scope can be declared with the auto specifier. The auto keyword is rarely used, however,
because the duration of a variable with block scope is temporary by default.
The static Specifier
TIP
Since a global variable is visible among different source files of a program, using global variables
increases your program's complexity, which in turn makes your program hard to maintain or debug.
Generally, it's not recommended that you declare and use global variables, unless it's very necessary.
For instance, you can declare a global variable whose value is used but never changed by several
subroutines in your program. (In Hour 23, "The C Preprocessor," you'll learn to use the #define directive
to define constants that are used in many places in a program.)
The static specifier, on the other hand, can be applied to variables with either block scope or program scope. When a
variable within a function is declared with the static specifier, the variable has a permanent duration. In other words,
the memory storage allocated for the variable is not destroyed when the scope of the variable is exited, the value of
the variable is maintained outside the scope, and if execution ever returns to the scope of the variable, the last value
stored in the variable is still there.
For instance, in the following code portion:
int main()
{
int i; /* block scope and temporary duration */
static int j; /* block scope and permanent duration */
.
.
return 0;
}
the integer variable i has temporary duration by default. But the other integer variable, j, has permanent duration due
to the storage class specifier static.
The program in Listing 14.3 shows the effect of the static specifier on variables.
TYPE
Listing 14.3. Using the static specifier.
1: /* 14L03.c: Using the static specifier */
2: #include
3: /* the add_two function */
4: int add_two(int x, int y)
5: {
6: static int counter = 1;
7:
8: printf("This is the function call of %d,\n", counter++);
9: return (x + y);
10: }
11: /* the main function */
12: main()
13: {
14: int i, j;
15:
16: for (i=0, j=5; i<5;>14L03
This is the function call of 1,
the addition of 0 and 5 is 5.
This is the function call of 2,
the addition of 1 and 4 is 5.
This is the function call of 3,
the addition of 2 and 3 is 5.
This is the function call of 4,
the addition of 3 and 2 is 5.
This is the function call of 5,
the addition of 4 and 1 is 5.
C:\app>
ANALYSIS
The purpose of the program in Listing 14.3 is to call a function to add two integers and then print out the result
returned by the function on the screen. The function is called several times. A counter is set to keep track of how
many times the function has been called.
This function, called add_two(), is declared in lines 4_10. There are two int arguments, x and y, that are passed to the
function, and the addition of the two arguments is returned in line 9. Note that there is an integer variable, counter,
that is declared with the static specifier in line 6. Values stored by counter are retained because the duration of the
variable is permanent. In other words, although the scope of counter is within the block of the add_two() function, the
memory location of counter and value saved in the location are not changed after the add_two() function is called and
the execution control is returned back to the main() function.
Therefore, the counter variable is used as a counter to keep the number of calls received by the add_two() function. In
fact, the statement of the printf() function in line 8 prints out the value saved by the counter variable each time the
add_two() function is called. In addition, counter is incremented by one each time after the printf() function is
executed.
The for loop, declared in lines 16_18 within the main() function, calls the add_two() function five times. The values
of the two integer variables, i and j, are passed to the add_two() function for the operation of addition. Then, the
return value from the add_two() function is displayed on the screen by the printf() function in lines 17 and 18.
From the output, you can see that the value saved by counter is indeed incremented by one each time the add_two()
function is called, and is retained after the function exits because the integer variable counter is declared with static.
Note that counter is only initialized once when the add_two() function is called for the first time.
File Scope and the Hierarchy of Scopes
In the first part of this hour, I mentioned three of the four types of scopes: block scope, function scope, and program
scope. It's time now to introduce the fourth scope—file scope.
In C, a global variable declared with the static specifier is said to have file scope. A variable with file scope is visible
from its declaration point to the end of the file. Here the file refers to the program file that contains the source code.
Most large programs consist of several program files.
The following portion of source code shows variables with file scope:
int x = 0; /* program scope */
static int y = 0; /* file scope */
static float z = 0.0; /* file scope */
int main()
{
int i; /* block scope */
.
.
.
return 0;
}
Here the int variable y and the float variable z both have file scope.
Figure 14.1 shows the hierarchy of the four scopes. As you can see, a variable with block scope is the most limited
and is not visible outside the block within which the variable is
Figure 14.1. The hierarchy of the four scopes.
declared. On the other hand, a variable with program scope is visible within all files, functions, and other blocks that
make up the program.
The register Specifier
The word register is borrowed from the world of computer hardware. Each computer has a certain number of registers
to hold data and perform arithmetic or logical calculations. Because registers are located within the CPU (central
processing unit) chip, it's much quicker to access a register than a memory location. Therefore, storing variables in
registers may help to speed up your program.
The C language provides you with the register specifier. You can apply this specifier to variables when you think it's
necessary to put the variables into the computer registers.
However, the register specifier only gives the compiler a suggestion. In other words, a variable specified by the
register keyword is not guaranteed to be stored in a register. The compiler can ignore the suggestion if there is no
register available, or if some other restrictions have to apply.
It's illegal to take the address of a variable that is declared with the register specifier because the variable is intended
to be stored in a register, not in the memory.
In the following portion of code, the integer variable i is declared with the register specifier:
int main()
{
/* block scope with the register specifier */
register int i;
. . .
for (i=0; i