Beginning C: From Beginner to Pro
()
About this ebook
Learn how to program using C, beginning from first principles and progressing through step-by-step examples to become a competent, C-language programmer. All you need are this book and any of the widely available C compilers, and you'll soon be writing real C programs.
You’ll discover that C is a foundation language that every programmer ought to know. Beginning C is written by renowned author Ivor Horton and expert programmer German Gonzalez-Morris. This book increases your programming expertise by guiding you through the development of fully working C applications that use what you've learned in a practical context. You’ll also be able to strike out on your own by trying the exercises included at the end of each chapter. At the end of the book you'll be confident in your skills with all facets of the widely-used and powerful C language.
What You Will Learn
- Discover the C programming language Program using C starting with first steps, then making decisions
- Use loops, arrays, strings, text, pointers, functions, I/O, and more Code applications with strings and text
- Structure your programs efficiently Work with data, files, facilities, and more
Who This Book Is For
Those new to C programming who may or may not have some prior programming experience.
Related to Beginning C
Related ebooks
Beginning C++17: From Novice to Professional Rating: 0 out of 5 stars0 ratingsExploring C++20: The Programmer's Introduction to C++ Rating: 0 out of 5 stars0 ratingsPractical Shader Development: Vertex and Fragment Shaders for Game Developers Rating: 0 out of 5 stars0 ratingsLearn C++ for Game Development Rating: 0 out of 5 stars0 ratingsC++ Programming Cookbook Rating: 0 out of 5 stars0 ratingsObjective-C Programming Nuts and bolts Rating: 0 out of 5 stars0 ratingsHands-On Julia Programming: An Authoritative Guide to the Production-Ready Systems in Julia Rating: 0 out of 5 stars0 ratingsDesign Patterns in C#: A Hands-on Guide with Real-world Examples Rating: 0 out of 5 stars0 ratingsRegex Quick Syntax Reference: Understanding and Using Regular Expressions Rating: 0 out of 5 stars0 ratingsProgramming 101: The How and Why of Programming Revealed Using the Processing Programming Language Rating: 0 out of 5 stars0 ratings.NET IL Assembler Rating: 0 out of 5 stars0 ratingsPro Cryptography and Cryptanalysis: Creating Advanced Algorithms with C# and .NET Rating: 0 out of 5 stars0 ratingsNNG Reference Manual, Second Edition Rating: 0 out of 5 stars0 ratingsMastering AndEngine Game Development Rating: 0 out of 5 stars0 ratingsPractical C++20 Financial Programming: Problem Solving for Quantitative Finance, Financial Engineering, Business, and Economics Rating: 0 out of 5 stars0 ratingsWPF in Action with Visual Studio 2008: Covers Visual Studio 2008 Service Pack 1 and .NET 3.5 Service Pack 1! Rating: 0 out of 5 stars0 ratingsConceptive C Rating: 0 out of 5 stars0 ratingsVisual Studio Code Distilled: Evolved Code Editing for Windows, macOS, and Linux Rating: 3 out of 5 stars3/5Optimizing Visual Studio Code for Python Development: Developing More Efficient and Effective Programs in Python Rating: 0 out of 5 stars0 ratingsComputer Graphics Programming in OpenGL With C++ (Edition 3): Mastering 3D Graphics and Animation Techniques Rating: 0 out of 5 stars0 ratingsC# Deconstructed: Discover how C# works on the .NET Framework Rating: 0 out of 5 stars0 ratingsMastering C++ Network Automation Rating: 0 out of 5 stars0 ratingsWindows Presentation Foundation 4.5 Cookbook Rating: 0 out of 5 stars0 ratingsLearn C++ by Example: Covers versions 11 to 23 Rating: 0 out of 5 stars0 ratingsSimultaneous multithreading A Complete Guide Rating: 0 out of 5 stars0 ratingsC++20 Recipes: A Problem-Solution Approach Rating: 0 out of 5 stars0 ratingsIntroducing Algorithms in C: A Step by Step Guide to Algorithms in C Rating: 0 out of 5 stars0 ratingsCommon Lisp A Complete Guide Rating: 1 out of 5 stars1/5
Programming For You
Excel 101: A Beginner's & Intermediate's Guide for Mastering the Quintessence of Microsoft Excel (2010-2019 & 365) in no time! Rating: 0 out of 5 stars0 ratingsExcel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5SQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5SQL All-in-One For Dummies Rating: 3 out of 5 stars3/5Grokking Algorithms: An illustrated guide for programmers and other curious people Rating: 4 out of 5 stars4/5HTML in 30 Pages Rating: 5 out of 5 stars5/5JavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/5HTML & CSS: Learn the Fundaments in 7 Days Rating: 4 out of 5 stars4/5Linux: Learn in 24 Hours Rating: 5 out of 5 stars5/5PYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5Python: For Beginners A Crash Course Guide To Learn Python in 1 Week Rating: 4 out of 5 stars4/5Beginning Programming with C++ For Dummies Rating: 4 out of 5 stars4/5C# Programming from Zero to Proficiency (Beginner): C# from Zero to Proficiency, #2 Rating: 0 out of 5 stars0 ratingsPython QuickStart Guide: The Simplified Beginner's Guide to Python Programming Using Hands-On Projects and Real-World Applications Rating: 0 out of 5 stars0 ratingsC Programming For Beginners: The Simple Guide to Learning C Programming Language Fast! Rating: 5 out of 5 stars5/5SQL: For Beginners: Your Guide To Easily Learn SQL Programming in 7 Days Rating: 5 out of 5 stars5/5Learn PowerShell in a Month of Lunches, Fourth Edition: Covers Windows, Linux, and macOS Rating: 5 out of 5 stars5/5Coding with JavaScript For Dummies Rating: 0 out of 5 stars0 ratings
Reviews for Beginning C
0 ratings0 reviews
Book preview
Beginning C - German Gonzalez-Morris
© German Gonzalez-Morris and Ivor Horton 2020
G. Gonzalez-Morris, I. HortonBeginning Chttps://doi.org/10.1007/978-1-4842-5976-4_1
1. Programming in C
German Gonzalez-Morris¹ and Ivor Horton²
(1)
Santiago, Chile
(2)
STRATFORD UPON AVON, UK
C is a powerful and compact computer language that allows you to write programs that specify exactly what you want your computer to do. You’re in charge: you create a program, which is just a set of instructions, and your computer will follow them.
Programming in C isn’t difficult, as you’re about to find out. I’m going to teach you all the fundamentals of C programming in an enjoyable and easy-to-understand way, and by the end of this chapter, you’ll have written your first few C programs. It’s as easy as that!
In this chapter, you’ll learn
What the C language standard is
What the standard library is
How to create C programs
How C programs are organized
How to write your own program to display text on the screen
The C Language
C is remarkably flexible. It has been used for developing just about everything you can imagine by way of a computer program, from accounting applications to word processing and from games to operating systems. It is not only the basis for more advanced languages, such as C++, it is also used currently for developing mobile phone apps in the form of Objective C. Objective C is standard C with a thin veneer of object-oriented programming capability added and too many new devices/microcontrollers, such as Raspberry Pi and Arduino. C is easy to learn because of its compactness. Thus, C is an ideal first language if you have ambitions to be a programmer. You’ll acquire sufficient knowledge for practical application development quickly and easily.
The C language is defined by an international standard, and the latest is currently defined by the C17 (ISO/IEC 9899:2018), which is a bug fix version for C11 more than new features (for instance, it deprecates ATOMIC_VAR_INIT). The current standard is commonly referred to as C17 or C18—the informal names of this version. This occurs because it was finished in 2017, but published in 2018. It is known that GCC uses C17 as a parameter to target this new version. Nevertheless, the aforementioned is not declared in the standard, and the language that I describe in this book conforms to C17 or can be considered C11 with several solved issues. You need to be aware that some elements of the language as defined by C17 are optional. This implies that a C compiler that conforms to the C17 standard may not implement everything in the standard. (A compiler is just a program that converts your program written in terms you understand into a form your computer understands.) I will identify any language feature in the book that is optional so far as C17 is concerned, just so you are aware that it is possible that your compiler may not support it. We will use C11/C17 as a synonym in the book.
It is also possible that a C17 compiler may not implement all of the language features mandated by the C17 standard; in particular, only the newest compilers have C11/C17 compatibility at 100 percent. It takes time to implement new language capabilities, so compiler developers will often take an incremental approach to implementing them. This provides another reason why a program may not work. Having said that, I can confirm from my own experience that the most common reason for things not working in a C program, at least 99.9 percent of the time, is that a mistake has been made.
The Standard Library
The standard library for C is also specified within the C17 standard. The standard library defines constants, symbols, and functions that you frequently need when writing a C program. It also provides some optional extensions to the basic C language. Machine-dependent facilities such as input and output for your computer are implemented by the standard library in a machine-independent form. This means that you write data to a disk file in C in the same way on your PC as you would on any other kind of computer, even though the underlying hardware processes are quite different. The standard functionality that the library contains includes capabilities that most programmers are likely to need, such as processing text strings or math calculations. This saves you an enormous amount of effort that would be required to implement such things yourself.
The standard library is specified in a set of standard files called header files . Header files always have names with the extension .h. To make a particular set of standard features available in your C program file, you just include the appropriate standard header file in a way that I’ll explain later in this chapter. Every program you write will make use of the standard library. A summary of the header files that make up the standard library is in Appendix E.
At the beginning, there was the C POSIX library that implemented many features for ANSI C. One of those libraries is pthreads that today is obsolete and implemented in the standard library. Other POSIX libraries (ISO/IEC 9945 (POSIX)) are in the road map for C2x for future releases.
Learning C
If you are completely new to programming, there are some aspects of C that you do not need to learn, at least not the first time around. These are capabilities that are quite specialized or used relatively infrequently. I have put all these together in Chapter 14 so you will learn about them when you are comfortable with the rest.
Although the code for all the examples is available via the Download Source Code link located at www.apress.com/9781484259757, I recommend that you type in all the examples in the book, even when they are very simple. Keying stuff in makes it less likely that you will forget things later. Don’t be afraid to experiment with the code. Making mistakes is very educational in programming. The more mistakes you make early on, the more you are likely to learn.
Creating C Programs
There are four fundamental stages, or processes, in the creation of any C program:
Editing
Compiling
Linking
Executing
You’ll soon know all these processes like the back of your hand because you’ll be carrying them out so often. First, I’ll explain what each process is and how it contributes to the development of your C program.
Editing
Editing is the process of creating and modifying C source code—the name given to the program instructions you write. Some C compilers come with a specific editor program that provides a lot of assistance in managing your programs. In fact, an editor often provides a complete environment for writing, managing, developing, and testing your programs. This is sometimes called an integrated development environment (IDE) .
You can also use a general-purpose text editor to create your source files, but the editor must store the code as plain text without any extra formatting data embedded in it. Don’t use a word processor such as Microsoft Word; word processors aren’t suitable for producing program code because of the extra formatting information they store along with the text. In general, if you have a compiler system with an editor included, it will provide a lot of features that make it easier to write and organize your source programs. There will usually be automatic facilities for laying out the program text appropriately and color highlighting for important language elements, which not only makes your code more readable but also provides a clear indicator when you make errors when keying in such words.
If you’re working with Linux, the most common text editor is the Vim editor. Alternately, you might prefer to use the GNU Emacs editor. With Microsoft Windows, you could use one of the many freeware and shareware programming editors. These will often provide help in ensuring your code is correct, with syntax highlighting and autoindenting. There is also a version of Emacs for Microsoft Windows. The vi and Vim editors from the UNIX environment are available for Windows too, and you could even use Notepad++ (http://notepad-plus-plus.org/).
Of course, you can also purchase one of the professionally created programming development environments that support C, such as those from JetBrains or Microsoft(there is a free Community Edition), in which case you will have very extensive editing capabilities. Before parting with your cash though, it’s a good idea to check that the level of C that is supported conforms to the current C standard, C17. With some of the products out there that are primarily aimed at C++ developers, C has been left behind somewhat.
Compiling
The compiler converts your source code into machine language and detects and reports errors in the compilation process. The input to this stage is the file you produce during your editing, which is usually referred to as a source file .
The compiler can detect a wide range of errors that are due to invalid or unrecognized program code, as well as structural errors where, for example, part of a program can never be executed. The output from the compiler is known as object code, and it is stored in files called object files , which usually have names with the extension .obj in the Microsoft Windows environment or .o in the Linux/UNIX environment. The compiler can detect several different kinds of errors during the translation process, and most of these will prevent the object file from being created.
The result of a successful compilation is a file with the same name as that used for the source file, but with the .o or .obj extension.
If you’re working in UNIX, at the command line, the standard command to compile your C programs will be cc (or the GNU’s Not UNIX [GNU] compiler, which is .gcc). You can use it like this:
cc -c myprog.c
where myprog.c is the name of the source file that contains the program you want to compile. Note that if you omit the -c flag, your program will automatically be linked as well. The result of a successful compilation will be an object file.
Most C compilers will have a standard compile option, whether it’s from the command line (such as cc myprog.c) or a menu option from within an IDE (where you’ll find a Compile menu option). Compiling from within an IDE is generally much easier than using the command line.
Compilation is a two-stage process. The first stage is called the preprocessing phase , during which your code may be modified or added to, and the second stage is the actual compilation that generates the object code (this second stage does assembly underneath; GCC and other compilers have options for these steps, but most of the time, it is not necessary). Your source file can include preprocessing macros, which you use to add to or modify the C program statements. Don’t worry if this doesn’t make complete sense now. It will come together for you as the book progresses.
Linking
The linker combines the object modules generated by the compiler from source code files, adds required code modules from the standard library supplied as part of C, and welds everything into an executable whole. The linker also detects and reports errors, for example, if part of your program is missing or a nonexistent library component is referenced.
In practice, a program of any significant size will consist of several source code files, from which the compiler generates object files that need to be linked. A large program may be difficult to write in one working session, and it may be impossible to work with as a single file. By breaking it up into a number of smaller source files that each provide a coherent part of what the complete program does, you can make the development of the program a lot easier. The source files can be compiled separately, which makes eliminating simple typographical errors a bit easier. Furthermore, the whole program can usually be developed incrementally. The set of source files that make up the program will usually be integrated under a project name, which is used to refer to the whole program.
Program libraries support and extend the C language by providing routines to carry out operations that aren’t part of the language. For example, libraries contain routines that support operations such as performing input and output, calculating a square root, comparing two character strings, or obtaining date and time information.
A failure during the linking phase means that once again you have to go back and edit your source code. Success, on the other hand, will produce an executable file, but this does not necessarily mean that your program works correctly. In a Microsoft Windows environment, the executable file will have an .exe extension; in UNIX, there will be no such extension, but the file will be of an executable type. Many IDEs have a build option, which will compile and link your program in a single operation.
Executing
The execution stage is where you run your program, having completed all the previous processes successfully. Unfortunately, this stage can also generate a wide variety of error conditions that can include producing the wrong output, just sitting there and doing nothing, or perhaps crashing your computer for good measure. In all cases, it’s back to the editing process to check your source code.
Now for the good news: This is also the stage where if your program works, you get to see your computer doing exactly what you told it to do! In UNIX and Linux, you can just enter the name of the file that has been compiled and linked to execute the program. In most IDEs, you’ll find an appropriate menu command that allows you to run or execute your compiled program. This Run or Execute option may have a menu of its own, or you may find it under the Compile menu option. In Windows, you can run the .exe file for your program as you would any other executable.
The processes of editing, compiling, linking, and executing are essentially the same for developing programs in any environment and with any compiled language. Figure 1-1 summarizes how you would typically pass through processes as you create your own C programs.
../images/311070_6_En_1_Chapter/311070_6_En_1_Fig1_HTML.pngFigure 1-1.
Creating and executing a program
Creating Your First Program
We’ll step through the processes of creating a simple C program, from entering the program source code to executing it. Don’t worry if what you type doesn’t mean much to you at this stage—I’ll explain everything as we go along.
Try it out: An Example C Program
Run your editor and type in the following program exactly as it’s written. Be careful to use the punctuation exactly as you see here. Make sure you enter the brackets that are on the fourth and last lines as braces—the curly ones {}, not the square brackets [ ] or the parentheses ()—it really does matter. Also, make sure you put the forward slashes the right way (/), as later you’ll be using the backslash (\) as well. Don’t forget the semicolon (;):
/* Program 1.1 Your Very First C Program - Displaying Hello World */
#include
int main(void)
{
printf(Hello world!
);
return 0;
}
When you’ve entered the source code, save the program as hello.c. You can use whatever name you like instead of hello, but the extension must be .c. This extension is the common convention when you write C programs and identifies the contents of the file as C source code. Most compilers will expect the source file to have the extension .c, and if it doesn’t, the compiler may refuse to process it.
Next, you’ll compile your program as I described in the Compiling
section previously in this chapter and then link the pieces necessary to create an executable program, as discussed in the Linking
section. Compiling and linking are often carried out in a single operation, in which case it is usually described as a build operation. When the source code has been compiled successfully, the linker will add code from the standard libraries that your program needs and create the single executable file for your program.
Finally, you can execute your program. Remember that you can do this in several ways. There is the usual method of double-clicking the .exe file from Windows Explorer if you’re using Windows, but you will be better off opening a command-line window and typing in the command to execute it because the window showing the output will disappear when execution is complete. You can run your program from the command line in all operating system environments. Just start a command-line session, change the current directory to the one that contains the executable file for your program, and then enter the program name to run it.
If everything worked without producing any error messages, you’ve done it! This is your first program, and you should see the following output:
Hello world!
Editing Your First Program
You could try altering the same program to display something else. For example, you could edit the program to read like this:
/* Program 1.2 Your Second C Program */
#include
int main(void)
{
printf(\"If at first you don't succeed, try, try, try again!\"
);
return 0;
}
The output from this version will be
If at first you don't succeed, try, try, try again!
The \" sequence that appears at the beginning and end of the text to be displayed is called an escape sequence , and there are several different escape sequences. Here, \ is a special way of including a double quote in the text to be output. This is necessary because double quotes (the straight kind, not curly quotes) are used to indicate where a character string begins and ends. The escape sequences cause a double quote to appear at the beginning and end of the output. If you didn’t use the escape sequences, not only would the double quote characters not appear in the output but the program would not compile. You’ll learn all about escape sequences in the
Control Characters" section later in this chapter.
You can try recompiling the program, relinking it, and running it again once you have altered the source code. With a following wind and a bit of luck, you have now edited your first program. You’ve written a program using the editor, edited it, and compiled, linked, and executed it.
Dealing with Errors
To err is human, so there’s no need to be embarrassed about making mistakes. Fortunately, computers don’t generally make mistakes, and they’re actually very good at indicating where we’ve slipped up. Sooner or later, your compiler is going to present you with a list (sometimes a list that’s longer than you want) of the mistakes that are in your source code. You’ll usually get an indication of the statements that are in error. When this happens, you must return to the editing stage, find out what’s wrong with the incorrect code, and fix it.
Keep in mind that one error can result in error messages for subsequent statements that may actually be correct. This usually happens with statements that refer to something that is supposed to be defined by a statement containing an error. Of course, if a statement that defines something has an error, then what was supposed to be defined won’t be.
Let’s step through what happens when your source code is incorrect by creating an error in your program. Edit your second program example, removing the semicolon (;) at the end of the line with printf() in it, as shown here:
/* Program 1.2 Your Second C Program */
#include
int main(void)
{
printf(\"If at first you don't succeed, try, try, try again!\"
)
return 0;
}
If you now try to compile this program, you’ll see an error message that will vary slightly depending on which compiler you’re using. A typical error message is as follows:
Syntax error : expected ';' but found 'return'
HELLO.C - 1 error(s), 0 warning(s)
Here, the compiler is able to determine precisely what the error is and where. There really should be a semicolon at the end of that printf() line. As you start writing your own programs, you’ll probably get a lot of errors during compilation that are caused by simple punctuation mistakes. It’s so easy to forget a comma or a bracket or to just press the wrong key. Don’t worry about this; a lot of experienced programmers make exactly the same mistakes—even after years of practice.
As I said earlier, just one mistake can sometimes result in a whole stream of abuse from your compiler, as it throws you a multitude of different things that it doesn’t like. Don’t get put off by the number of errors reported. After you consider the messages carefully, the basic approach is to go back and edit your source code to fix at least the first error, because that may have triggered other errors, and ignore the errors you can’t understand. Then have another go at compiling the source file. With luck, you’ll get fewer errors the next time around.
To correct your example program, just go back to your editor and reenter the semicolon. Recompile, check for any other errors, and your program is fit to be run again.
Dissecting a Simple Program
Now that you’ve written and compiled your first program, let’s go through another that’s very similar and see what the individual lines of code do. Have a look at this program:
/* Program 1.3 Another Simple C Program - Displaying a Quotation */
#include
int main(void)
{
printf(Beware the Ides of March!
);
return 0;
}
This is virtually identical to your first program. Even so, the practice is good, so use your editor to enter this example and see what happens when you compile and run it. If you type it in accurately, compile it, and run it, you should get the following output:
Beware the Id.es of March!
Comments
Look at the first line of code in the preceding example:
/* Program 1.3 Another Simple C Program - Displaying a Quotation */
This isn’t actually part of the program code, in that it isn’t telling the computer to do anything. It’s simply a comment, and it’s there to remind you, or someone else reading your code, what the program does. Anything between /* and */ is treated as a comment. As soon as your compiler finds /* in your source file, it will simply ignore anything that follows (even if the text looks like program code) until it finds a matching */ that marks the end of the comment. This may be on the same line, or it can be several lines further on. If you forget to include the matching */, everything following /* will be ignored. Here’s how you could use a single comment to identify the author of the code and to assert your copyright:
/*
* Written by Ivor Horton
* Copyright 2012
*/
You can also embellish comments to make them stand out:
/*******************************************
* This is a very important comment *
* so please read this. *
*******************************************/
You can add a comment at the end of a line of code using a different notation, like this:
printf(Beware the Ides of March!
); // This line displays a quotation
Everything following two forward slashes on a line is ignored by the compiler. This form of comment is less cluttered than the previous notation, especially when the comment is on a single line.
You should try to get into the habit of documenting your programs, using comments as you go along. Your programs will, of course, work without comments, but when you write longer programs, you may not remember what they do or how they work. Put in enough comments to ensure that a month from now you (and any other programmer) can understand the aim of the program and how it works.
Let’s add some more comments to the program:
/* Program 1.3 Another Simple C Program - Displaying a Quotation */
#include
int main(void) // This identifies the function main()
{ // This marks the beginning of main()
printf(Beware the Ides of March!
); // This line outputs a quotation
return 0; // This returns control to the operating system
} // This marks the end of main()
You can see that using comments can be a very useful way of explaining what’s going on in the program. You can place comments wherever you want in your program, and you can use them to explain the general objectives of the code as well as the specifics of how the code works.
Preprocessing Directives
Look at the following line of code:
#include
This is not strictly part of the executable program, but it is essential in this case—in fact, the program won’t work without it. The symbol # indicates this is a preprocessing directive , which is an instruction to your compiler to do something before compiling the source code. The compiler handles these directives during an initial preprocessing phase before the compilation process starts. There are quite a few preprocessing directives, and there are usually some at the beginning of the program source file, but they can be anywhere.
In this case, the compiler is instructed to include
in your program the contents of the file with the name stdio.h. This file is called a header file , because it’s usually included at the head of a program source file. In this case, the header file defines information about some of the functions that are provided by the standard C library; but, in general, header files specify information that the compiler uses to integrate any predefined functions or other global objects within a program. You’ll be creating your own header files for use with your programs. In this case, because you’re using the printf() function from the standard library, you have to include the stdio.h header file. This is because stdio.h contains the information that the compiler needs to understand what printf() means, as well as other functions that deal with input and output. As such, its name, stdio, is short for standard input/output. All header files in C have file names with the extension .h. You’ll use other standard header files later in the book.
Note
Header file names are case sensitive on some systems, so you should always write them in lowercase in #include directives.
Every C compiler that conforms to the C11 standard will have a set of standard header files supplied with it. These header files primarily contain declarations relating to standard library functions and macros that are available with C. Although all C compilers that conform with the standard will support the same basic set of capabilities and will have the same set of mandatory standard header files available, there are standard header files that are optional, and in some cases extra library functions can be provided with a particular compiler that may not be available with other compilers that will typically provide functionality specific to the type of computer on which the compiler runs.
Note
All the standard header files are listed in Appendix E.
Defining the main() Function
The next five statements define the function main() :
int main(void) // This identifies the function main()
{ // This marks the beginning of main()
printf(Beware the Ides of March!
); // This line outputs a quotation
return 0; // This returns control to the operating system
} // This marks the end of main()
A function is just a named block of code between braces that carries out some specific set of operations. Every C program consists of one or more functions, and every C program must contain a function called main()—the reason being that a program always starts execution from the beginning of this function. So imagine that you’ve created, compiled, and linked a file called progname.exe. When you execute this program, the operating system executes the function main() for the program.
The first line of the definition for the function main() is as follows:
int main(void) // This identifies the function main()
This defines the start of main(). Notice that there is no semicolon at the end of the line. The first line identifying this as the function main() has the word int at the beginning. What appears here defines the type of value to be returned by the function, and the word int signifies that main() returns an integer value. The integer value that is returned when the execution of main() ends represents a code that is returned to the operating system that indicates the program state. You end execution of main() and specify the value to be returned in this statement:
return 0; // This returns control to the operating system
This is a return statement that ends execution of main() and returns the value 0 to the operating system. You return a zero value from main() to indicate that the program terminated normally; a nonzero value would indicate an abnormal return, which means things did not proceed as they should have when the program ended.
The parentheses that immediately follow the name of the function main enclose a definition of what information is to be transferred to main() when it starts executing. In this example, there’s the word void between the parentheses, and this signifies that no data can be transferred to main(). Later, you’ll see how data are transferred to main() and to other functions in a program.
The main() function can call other functions, which in turn may call further functions, and so on. For every function that’s called, you have the opportunity to pass some information to it within the parentheses that follow its name. A function will stop execution when a return statement in the body of the function is reached, and control will then transfer to the calling function (or the operating system in the case of the function main()). In general, you define a function so that either it does return a value or it does not. When a function does return a value, the value is always of a specific type. In the case of main(), the value that is returned is of type int, which is an integer.
Keywords
In C, a keyword is a word with special significance, so you must not use keywords for any other purpose in your program. For this reason, keywords are also referred to as reserved words . In the preceding example, int is a keyword, and void and return are also keywords. C has several keywords, and you’ll become familiar with more of them as you learn more of the language. You’ll find a complete list of C keywords in Appendix C.
The Body of a Function
The general structure of the function main() is illustrated in Figure 1-2.
../images/311070_6_En_1_Chapter/311070_6_En_1_Fig2_HTML.pngFigure 1-2.
Structure of the function main()
The function body is the bit between the opening and closing braces that follows the line where the function name appears. The function body contains all the statements that define what the function does. The example main() function has a very simple function body consisting of just two statements:
{ // This marks the beginning of main()
printf(Beware the Ides of March!
); // This line outputs a quotation
return 0; // This returns control to the operating system
} // This marks the end of main()
Every function must have a body, although the body can be empty and just consist of the opening and closing braces without any statements between them. In this case, the function will do nothing.
You may wonder what use a function that does nothing is. Actually, this can be very useful when you’re developing a program that will have many functions. You can declare the set of (empty) functions that you think you’ll need to write to solve the problem at hand, which should give you an idea of the programming that needs to be done, and then gradually create the program code for each function. This technique helps you to build your program in a logical and incremental manner.
Note
You can see that I’ve aligned the braces one below the other in Program 1.3 and indented the statements between them. I’ve done this to make it clear where the block of statements that the braces enclose starts and finishes. Statements between braces are usually indented by a fixed amount—usually two or more spaces—so that the braces stand out. This is good programming style, because it allows the statements within a block to be readily identified.
There are other styles for arranging braces in code, for example:
int main(void) {
printf(Beware the Ides of March!
); // This line outputs a quotation
return 0;
}
Tip
With whatever style you use to arrange your source code, the most important thing is to apply it consistently.
Outputting Information
The body of the main() function in the example includes a statement that calls the printf() function :
printf(Beware the Ides of March!
); // This line outputs a quotation
As I’ve said, printf() is a standard library function, and it outputs information to the command line (actually the standard output stream, which is the command line by default) based on what appears between the parentheses that immediately follow the function name. In this case, the call to the function displays the simple piece of Shakespearean advice that appears between the double quotes; a string of characters between double quotes like this is called a string literal . Notice that this line does end with a semicolon.
Function Arguments
Items enclosed between the parentheses following a function name, as with the printf() function in the previous statement, are called arguments , and they specify data that are to be passed to the function. When there is more than one argument to a function, they must be separated by commas.
In the previous example, the argument to the function is the text string between double quotes. If you don’t like the quotation that is specified here, you could display something else by simply including your own choice of words enclosed within double quotes inside the parentheses. For instance, you might prefer a line from Macbeth:
printf(Out, damned Spot! Out I say!
);
Try using this in the example. When you’ve modified the source code, you need to compile and link the program again before executing it.
Note
As with all executable statements in C (as opposed to defining or directive statements), the printf() line must have a semicolon at the end. A very common error when you first start programming in C is to forget the semicolon.
Control Characters
You could alter the program to display two sentences on separate lines using a single printf() statement. Try typing in the following code:
// Program 1.4 Another Simple C Program - Displaying a Quotation
#include
int main(void)
{
printf(My formula for success?\nRise early, work late, strike oil.\n
);
return 0;
}
The output from this program looks like this:
My formula for success?
Rise early, work late, strike oil.
Look at the printf() statement. After the first sentence and at the end of the text, you’ve inserted the characters \n. The combination \n is another escape sequence that represents a newline character. This causes the output cursor to move to the next line, so any subsequent output will start on a new line.
The backslash (\) is always of special significance in a text string because it indicates the start of an escape sequence. The character following the backslash indicates what character the escape sequence represents. In the case of \n, it’s n for newline, but there are plenty of other possibilities. Because a backslash itself is of special significance, you need a way to specify a backslash in a text string. To do this, you simply use two backslashes: \\.
Type in the following program:
// Program 1.5 Another Simple C Program - Displaying Great Quotations
#include
int main(void)
{
printf(\"It is a wise father that knows his own child.\"\nShakespeare\n
);
return 0;
}
The output displays the following text:
It is a wise father that knows his own child.
Shakespeare
The double quotes are output because you use escape sequences for them in the string. Shakespeare appears on the next line because there is a \n escape sequence following the \".
You can use the \a escape sequence in an output string to sound a beep to signal something interesting or important. Enter and run the following program:
// Program 1.6 A Simple C Program – Important
#include
int main(void)
{
printf(Be careful!!\n\a
);
return 0;
}
The output of this program is sound and vision. Listen closely, and you should hear the beep through the speaker in your computer.
Be careful!!
The \a sequence represents the bell
character. Table 1-1 shows all the escape sequences that you can use.
Table 1-1.
Escape Sequences
Try displaying different lines of text on the screen and alter the spacing within that text. You can put words on different lines using \n, and you can use \t to space the text. You’ll get a lot more practice with these as you progress through the book.
Trigraph Sequences
In general, you can use a question mark directly in a string. The \? escape sequence only exists because there are nine special sequences of characters called trigraph sequences that are three-character sequences for representing each of the characters #, [,], \, ^, ~, \, {, and }:
These are there for when it is necessary to write C code in the International Organization for Standardization (ISO) invariant code set, which does not have these characters. This is unlikely to apply to you. You can completely forget about all this unless you want to write a statement such as
printf(What??!\n
);
The output produced by this statement will be
What|
The trigraph ??! will be converted to |. To get the output you intended, you need to write the statement as
printf(What?\?!\n
);
Now the trigraph sequence does not appear because the second question mark is specified by its escape sequence. Your compiler may well issue a warning when you use a trigraph sequence because usually it is unintended. In modern compilers, such as GCC, a warning would be in the output, avoiding the wrong trigraph misinterpretation, and also can be forced with argument –Wtrigraphs:
program1_08.c:7:15: warning: trigraph ??! ignored, use -trigraphs to enable [-Wtrigraphs]
The Preprocessor
In the example, I explained how you use a preprocessing directive to include the contents of a header file into your source file. The preprocessing phase of compilation can do much more than this. As well as directives, your source file can contain macros. A macro is an instruction to the preprocessor to add to or modify the C statements in the program. A macro can be something as simple as defining a symbol, such as INCHES_PER_FOOT to be replaced by 12 wherever the symbol appears. The directive to do this is
#define INCHES_PER_FOOT 12
With this directive at the beginning of your source file, wherever INCHES_PER_FOOT appears in the code, it will be replaced by 12, for example:
printf(There are %d inches in a foot.\n
, INCHES_PER_FOOT);
After preprocessing, this statement will be
printf(There are %d inches in a foot.\n
, 12);
INCHES_PER_FOOT no longer appears because the symbol has been replaced by the string specified in the #define directive. This will happen for every instance of the symbol in the source file.
A macro can also be quite complicated, with significant amounts of code being added to a source file depending on specified conditions. I won’t go into this further here. I will discuss preprocessor macros in detail in Chapter 13. You will meet some macros before that, and I’ll explain them in context when they appear.
Developing Programs in C
The process for developing a program in C may not be obvious if you’ve never written a program before. It’s very similar to many other situations in life where it just isn’t clear how you’re going to achieve your objective when you first start out. Normally you begin with a rough idea of what you want to achieve, but you need to translate this into a more precise specification of what you want. Once you’ve reached this more precise specification, you can work out the series of steps that will lead to your final objective. Having the idea that you want to build a house just isn’t enough. You need to know what kind of house you want, how large it’s going to be, what kinds of materials you have to build it with, and where you want to build it. You will also want to know how long it’s going to take and the likely cost. This kind of detailed planning is also necessary when you want to write a program. Let’s go through the basic steps that you need to follow when you’re writing a program. The house analogy is useful, so I’ll work with it for a while.
Understanding the Problem
The first step is to get a clear idea of what you want to do. It would be lunacy to start building your house before you had established what facilities it should provide: how many bedrooms, how many bathrooms, how big it’s going to be, and so on. All these things affect the cost in terms of materials and the work involved in building the house. Generally it comes down to a compromise that best meets your needs within the constraints of the money, the workforce, and the time that’s available for you to complete the project.
It’s the same with developing a program of any size. Even for a relatively straightforward problem, you need to know what kind of input to expect, how the input is to be processed, and what kind of output is required—and how it’s going to look. The input could be entered with the keyboard, but it might also involve data from a disk file or information obtained over a telephone line or a network. The output could simply be displayed on the screen, or it could be printed; perhaps it might involve writing a new disk file updating an existing file.
For more complex programs, you’ll need to look at many more aspects of what the program is going to do. A clear definition of the problem that your program is going to solve is an essential part of understanding the resources and effort that are going to be needed for the creation of a finished product. Considering these details also forces you to establish whether the project is actually feasible. A lack of precision and detail in the specifications for a new program has often resulted in a project taking much longer and costing much more than planned. There are many instances of projects being abandoned for this reason.
Detailed Design
To get the house built, you’ll need detailed plans. These plans enable the construction workers to do their jobs, and the plans describe in detail how the house will go together—the dimensions, the materials to use, and so on. You’ll also need a plan of what is to be done and when. For example, you’ll want the foundation dug before the walls are built, so the plan must involve segmenting the work into manageable units to be performed in a logical sequence.
It’s the same with a program. You need to specify what the program does by dividing it into a set of well-defined and manageable chunks that are reasonably self-contained. You also need to detail the way in which these chunks connect, as well as what information each chunk will need when it executes. This will enable you to develop the logic of each chunk relatively independently from the rest of the program. If you treat a large program as one huge process that you try to code as a single chunk, chances are that you’ll never get it to work.
Implementation
Given the detailed design of a house, the work can begin. Each group of construction workers will need to complete its part of the project at the right time. Each stage will need to be inspected to check that it’s been done properly before the next stage begins. Omitting these checks could easily result in the whole house collapsing.
Of course, if a program is large and you are writing it all yourself, you’ll write the source code one unit at a time. As one part is completed, you can write the code for the next. Each part will be based on the detailed design specifications, and you’ll verify that each piece works, as much as you can, before proceeding. In this way, you’ll gradually progress to a fully working program that does everything you originally intended.
A large programming project usually involves a team of programmers. The project is divided into relatively self-contained units that can be allocated among the members of the team. This allows several units of code to be developed concurrently. The interface between one unit of code and the rest of the program must be precisely defined if the units are going to connect together as a whole.
Testing
The house is complete, but there are a lot of things that need to be tested: the drainage, the water and electricity supplies, the heating, and so on. Any one of these areas can have problems that the contractors need to go back and fix. This is sometimes an iterative process, in which problems with one aspect of the house can be the cause of things going wrong somewhere else.
The mechanism with a program is similar. Each of your program modules—the pieces that make up your program—will need to be tested individually. When they don’t work properly, you need to debug them. Debugging is the process of finding and correcting errors in your program. This term is said to have originated in the days when finding the errors in a program involved tracing where the information went and how it was processed inside the computer by using the circuit diagram for the machine. The story goes that in one instance it was discovered that a computer program error was caused by an insect shorting part of a circuit in the computer. The problem was caused by a bug. Subsequently, the term bug was used to refer to any error in a program.
With a simple program, you can often find an error simply by inspecting the code. In general, though, the process of debugging usually involves using a debugger that inserts code temporarily for working out what happened when things go wrong. This includes breakpoints where execution pauses to allow you to inspect values in your code. You can also step through a program a statement at a time. If you don’t have a debugger, you can add extra program code to produce output that will enable you to check what the sequence of events is and what intermediate values are produced when a program executes. With a large program, you’ll also need to test the program modules in combination because, although the individual modules may work, there’s no guarantee that they’ll work together! The jargon for this phase of program development is integration testing .
Functions and Modular Programming
The word function has appeared a few times so far in this chapter with reference to main(), printf(), function body, and so on. Let’s explore what functions are in a little more depth and why they’re important.
Most programming languages, including C, provide a way of breaking up a program into segments, each of which can be written more or less independently of the others. In C, these segments are called functions . The program code in the body of one function is insulated from that of other functions (although they are called functions, this is an imperative/procedural and not functional language). A function will have a specific interface to the outside world in terms of how information is transferred to it and how results generated by the function are transmitted back from it. This interface is specified in the first line of the function, where the function name appears.
Figure 1-3 shows a simple example of a program to analyze baseball scores that is composed of four functions.
../images/311070_6_En_1_Chapter/311070_6_En_1_Fig3_HTML.pngFigure 1-3.
Modular programming
Each of the four functions does a specific, well-defined job. Overall control of the sequence of operations in the program is managed by one module, main(). There is a function to read and check the input data and another function to do the analysis. Once the data have been read and analyzed, a fourth function has the task of outputting the team and player rankings.
Segmenting a program into manageable chunks is a very important aspect to programming, so let’s go over the reasons for doing this:
It allows each function to be written and tested separately. This greatly simplifies the process of getting the total program to work.
Several separate functions are easier to handle and understand than one huge function.
Libraries are just sets of functions that people tend to use all the time. Because they’ve been prewritten and pretested, you know that they work, so you can use them without worrying about their code details. This will accelerate your program development by allowing you to concentrate on your own code, and it’s a fundamental part of the philosophy of C. The richness of the libraries greatly amplifies the power of the language.
You can accumulate your own libraries of functions that are applicable to the sort of programs that you’re interested in. If you find yourself writing a particular function frequently, you can write a generalized version of it to suit your needs and build this into your own library. Then, whenever you need to use that particular function, you can simply use your library version.
In the development of large programs, which can vary from a few thousand to millions of lines of code, development can be undertaken by teams of programmers, with each team working with a defined subgroup of the functions that make up the whole program.
You’ll learn about C functions in greater detail in Chapter 8. Because the structure of a C program is inherently functional, you’ve already been introduced to one of the standard library functions in one of this chapter’s earliest examples: the function printf().
Note
In some other programming languages, the term method is used to refer to a self-contained unit of code. Thus, method means essentially the same as function.
Try it out: An Example C Program
You can try an example that puts into practice what you’ve learned so far. First, have a look at the following code and see whether you can understand what it does without running it. Then type it in and compile, link, and run it and see what happens:
// Program 1.7 A longer program
#include
int main(void)
{
printf(Hi there!\n\n\nThis program is a bit
);
printf( longer than the others.
);
printf(\nBut really it's only more text.\n\n\n\a\a
);
printf(Hey, wait a minute!! What was that???\n\n
);
printf(\t1.\tA bird?\n
);
printf(\t2.\tA plane?\n
);
printf(\t3.\tA control character?\n
);
printf(\n\t\t\b\bAnd how will this look when it prints out?\n\n
);
return 0;
}
The output will be as follows:
Hi there!
This program is a bit longer than the others.
But really it's only more text.
Hey, wait a minute!! What was that???
1. A bird?
2. A plane?
3. A control character?
And how will this look when it prints out?
How It Works
The program looks a little bit complicated, but this is only because the text strings between parentheses include a lot of escape sequences. Each text string is bounded by a pair of double quotes. The program is just a succession of calls to the printf() function , and it demonstrates that output to the screen is controlled by what you pass to the printf() function.
You include the stdio.h file from the standard library through a preprocessing directive:
#include
You can see that this is a preprocessing directive because it begins with #. The stdio.h file provides the definitions you need to be able to use the printf() function.
You then define the start of the function main() and specify that it returns an integer value with this line:
int main(void)
The void keyword between the parentheses indicates that no information is passed to the main() function. The opening brace on the next line indicates that the body of the function follows:
{
The next statement calls the standard library function printf() to output Hi there! to your display screen, followed by two blank lines and the phrase This program is a bit:
printf(Hi there!\n\n\nThis program is a bit
);
The two blank lines are produced by the three \n escape sequences. Each of these starts a new line when the characters are written to the display. The first ends the line containing Hi there!, and the next two produce the two empty lines. The text This program is a bit appears on the fourth line of output. You can see that this one line of code produces a total of four lines of output on the screen.
The line of output produced by the next printf() starts at the character position immediately following the last character in the previous output. This outputs longer than the others with a space as the first output character:
printf( longer than the others.
);
This output will simply continue where the last line left off, following the t in bit. This means that you really do need the space at the beginning of the text; otherwise, the computer will display This program is a bitlonger than the others, which isn’t what you want.
The next statement starts its output on a new line immediately following the previous line because of the \n at the beginning of the text string between the double quotes:
printf(\nBut really it's only more text.\n\n\n\a\a
);
It displays the text and adds two empty lines (because of the three \n escape sequences) and beeps. The next output will start at the beginning of the line that follows the second empty line.
The next output is produced by the following statement:
printf(Hey, wait a minute!! What was that???\n\n
);
This outputs the text and then leaves one empty line. The next output will be on the line following the empty line.
Each of the next three statements inserts a tab, displays a number, inserts another tab followed by some text, and ends with a new line. This is useful for making your output easier to read:
printf(\t1.\tA bird?\n
);
printf(\t2.\tA plane?\n
);
printf(\t3.\tA control character?\n
);
This produces three numbered lines of output.
The next statement initially outputs a newline character, so that there will be an empty line following the previous output. Two tabs are then sent to the command line followed by two backspaces, which moves you back two spaces from the last tab position. Finally, the text is output followed by two newline characters:
printf(\n\t\t\b\bAnd how will this look when it prints out?\n\n
);
The last statement in the body of the function is
return 0;
This ends execution of main() and returns 0 to the operating system.
The closing brace marks the end of the function body:
}
Note
The precise effect of tabs and backspaces in the output can vary between compilers.
Common Mistakes
Mistakes are a fact of life. When you write a computer program in C, the compiler must convert your source code to machine code. To do this, your code must have a precise meaning, so there are very strict rules governing how you use the language. Leave out a comma where one is expected or add a semicolon where you shouldn’t and the compiler won’t be able to translate your program into machine code.
You’ll be surprised just how easy it is to introduce typographical errors into your program, even after years of practice. If you’re lucky, these errors will be picked up when you compile or link your program. If you’re really unlucky, they can result in your program apparently working fine but producing some intermittent erratic behavior. You can end up spending a lot of time tracking these errors down.
Of course, it’s not only typographical errors that cause problems. You’ll often find that your detailed implementation is just not right. Where you’re dealing with complicated decisions in your program, it’s easy to get the logic wrong. Your program may be quite accurate from a language point of view, and it may compile and run without a problem, but it won’t produce the right answers. These kinds of errors can be the most difficult to find.
Points to Remember
It would be a good idea to review what you’ve gleaned from your first program. You can do this by looking at the overview of the important points in Figure 1-4.
../images/311070_6_En_1_Chapter/311070_6_En_1_Fig4_HTML.pngFigure 1-4.
Elements of a simple program
Summary
You’ve reached the end of the first chapter, and you’ve already written a few programs in C. We’ve covered quite a lot of ground, but at a fairly gentle pace. The aim of this chapter was to introduce a few basic ideas rather than teach you a lot about the C programming language. You should now be confident about editing, compiling, and running your programs. You probably have only a vague idea about how to construct a C program at this point. It will become much clearer when you’ve learned a bit more about C and have written some programs with more meat to them.
In the next chapter, you’ll move on to more complicated things than just producing text output using the printf() function. You’ll manipulate information and get some rather more interesting results. And by the way, the printf() function does a whole lot more than just display text strings—as you’ll see soon.
Exercises
The following exercises enable you to try out what you’ve learned in this chapter. If you get stuck, look back over the chapter for help. If you’re still stuck, you can download the solutions from the Source Code/Download section of the Apress website (www.apress.com), but that really should be a last resort.
Exercise 1-1. Write a program that will output your name and address using a separate printf() statement for each line of output.
Exercise 1-2. Modify your solution for the previous exercise so that it produces all the output using only one printf() statement.
Exercise 1-3. Write a program to output the following text exactly as it appears here:
It's freezing in here,
he said coldly.
© German Gonzalez-Morris and Ivor Horton 2020
G. Gonzalez-Morris, I. HortonBeginning Chttps://doi.org/10.1007/978-1-4842-5976-4_2
2. First Steps in Programming
German Gonzalez-Morris¹ and Ivor Horton²
(1)
Santiago, Chile
(2)
STRATFORD UPON AVON, UK
By now you’re probably eager to create programs that allow your computer to really interact with the outside world. You don’t just want programs that work as glorified typewriters, displaying fixed information that you included in the program code, and