navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

C/C++ Essential Training
Richard Downs

C/C++ Essential Training

with Bill Weinman

 


Widely used for both systems and applications development, the C and C++ programming languages are available for virtually every operating system and are often the best choice for performance-critical applications. In this course, Bill Weinman dissects the anatomy of C and C++, from variables to functions and loops, and explores both the C Standard Library and the C++ Standard Template Library. Features introduced in the C++11 standard (ratified in 2011) are also discussed.

This course serves both as an end-to-end tutorial for those new to the language and a solid reference for experienced C/C++ programmers.
Topics include:
  • Setting up a development environment on Mac, Windows, or Linux
  • Understanding the development cycle
  • Writing statements and expressions
  • Declaring variables and functions
  • Working with arrays and strings
  • Comparing with conditionals
  • Including files and executing macros with the C preprocessor
  • Working with different data types
  • Using operators to perform basic arithmetic and more complicated functions
  • Understanding inheritance
  • C++ template programming
  • Handling system errors and exceptions
  • Using C++ STL containers
  • Using C++11 type inference, Lambda functions, and more

show more

author
Bill Weinman
subject
Developer, Desktop Apps, Programming Languages
software
Eclipse , C , C++
level
Beginner
duration
11h 31m
released
Jun 28, 2012

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi, I am Bill Weinman, and welcome to C and C++ Essential Training.
00:08In this course, we'll explore the C and C++ languages along with their standard libraries.
00:14I'll start by showing you the basic syntax of C.
00:17C syntax is the basis for both C and C++ as well as a number of other derived
00:22languages like C#, Java, PHP, and many others.
00:26I'll show you how to write classes and templates in C++ so you can access all
00:30the power of object-oriented programming.
00:33This will enable you to take advantage of modern programming techniques like
00:37encapsulation, generalization, and code reuse.
00:40I'll show you how to use advanced C++ features like inheritance and templates.
00:45I'll show you the standard C library so you can access resources on your system
00:49like reading and writing files and allocating memory.
00:52We'll cover the C++ standard template library providing powerful data types like
00:57vectors, sets, cues, and associative maps.
01:00We'll be covering these topics and much more so that you'll have all the
01:04resources you need to fully take advantage of this powerful language.
01:08C and C++ are among the most powerful and widely used languages today.
01:13Now let's get started with C and C++ Essential Training.
Collapse this transcript
Using the exercise files
00:00If you have access to the exercise files for this course, you can use them to
00:04follow along with the lessons as I present them.
00:07Because this course uses C and C++, you'll need a development environment
00:11capable of compiling and running console applications written in the latest
00:15standard version of C and C++.
00:18If you do not have a development environment available, instructions are
00:21included in this course for installing the Eclipse C Development Tools for that purpose.
00:27You'll need to copy the exercise files folder to a location on your machine
00:31where you can use it, for example, in your Desktop folder.
00:35Here in the exercise files folder, you'll find a folder for each of the
00:38chapters of the course.
00:41For each of the lessons you'll make a working copy of one or more of these files
00:45and work with the copies.
00:46That way if you need to start over, you have the original files available to
00:51make another working copy.
00:53Some of the files are available for non-premium members of lynda.com Online
00:57Training Library like this Operator Precedence chart and these WindowsSupport files.
01:05The chapter folders are available for premium members.
01:08If you do not have access to the chapter folders, you can easily follow along
01:12and create files of your own.
Collapse this transcript
Prerequisites
00:00In order to get the most out of this course, you should have some programming experience.
00:05The more experience you have the more readily you'll be able to learn about C and C++.
00:10But even if you are a relative novice, you should still be able to follow along.
00:15Either way you should be patient with yourself and take your time.
00:18C and C++ are not scripting languages and while they have simple syntax that may
00:23even look familiar, seemingly small errors may seem overwhelming at first.
00:28Remember, computers are very picky about spelling and punctuation.
00:32A parenthesis and a bracket may look similar on your screen but they mean
00:36entirely different things to the computer.
00:39Because this course uses C and C++ you'll need a development environment capable
00:44of compiling and running console applications written in the latest standard
00:48versions of C and C++.
00:50If you do not have a development environment available, instructions are
00:54included in this course for installing the Eclipse C Development Tools for that purpose.
00:59As with all software development, you'll want to do the exercise files for this
01:04course on a system dedicated for this purpose.
01:07C and C++ are systems languages, and it is possible even easy to mistakenly
01:13write a program that takes up all the resources on your system or crashes it entirely.
01:18You'll need to know how to find and correct problems on your system and have the
01:22time and freedom to do so without losing critical resources.
01:26Above all you'll need some patience.
01:28Programming can be a frustrating pursuit at times and with the compiled systems
01:32language like C or C++, it can be even more so.
01:36Take your time, type carefully, and when you inevitably make mistakes,
01:41patiently analyze those mistakes so that you can recognize them when they
01:44inevitably appear again.
01:46This kind of experience is invaluable and will serve you well for the long term.
01:51Now let's go, have some fun learning C and C++.
Collapse this transcript
1. Language Overview
About C
00:00The C programming language is the foundation of C++.
00:04In fact, C is the basis of many modern languages, including Java, JavaScript,
00:09Perl, PHP, Python and many, many others.
00:14Of course, C++ and Objective-C are direct descendents of C and include
00:18the entire C language.
00:20Yes, the entire C language is included in the definition of C++ and learning C
00:25is an essential first step on the road to learning C++.
00:30Let me say this again in a deferent way. You can not skip this step.
00:34In order to learn C++, you must first learn C.
00:38Developed by Dennis Ritchie at Bell Labs in 1969, C was designed as an
00:43alternative to assembly language for creating operating systems utilities and
00:48other systems level code. C is a small language with only 32 keywords.
00:53It's not what we would call today a high-level language.
00:56It is small, efficient, fast, and powerful.
01:00If you consider layers of technology in a computer system as a stack, C is
01:05commonly used to write code at all levels, with its most common usage at the lower levels.
01:11Almost all firmware, almost all modern operating systems and a great deal of
01:15application software is written in C. Why is C so popular?
01:21Systems code written in C tends to be small and fast, well-written C can
01:26generate object code that is almost a small and fast as code written in assembly language.
01:32Code written in C is extremely portable.
01:34C was originally designed for writing operating systems.
01:37For example, the UNIX operating system was written in C, and it runs on many,
01:42many different processors and hardware configurations.
01:46This is possible because so much of the operating system compiles and runs on
01:50many different machines, architectures and processors with little or no
01:54modification to the source code.
01:56This is equally true of applications written in C.
01:59The language itself is relatively small and easy to learn, yet its simplicity is deceptive.
02:06It gives you such access to the machine that is actually very rich and powerful language.
02:11C is a low-level language that means that it's close to the machine.
02:16It doesn't have a lot of features, but it compiles to tight, fast, efficient
02:20code that's what's C is good at, that's why people continue to use C after over 40 years.
02:26C is an imperative language.
02:29This means that the code is described as statements, subroutines are called
02:33functions and arguments are always passed by value.
02:35C is a block-oriented structured language that is code happens in blocks and the
02:42blocks are structured to enhance clarity.
02:44This is to improve quality and maintainability of your code.
02:47C is strongly typed;
02:50this means that each variable must have a declared type.
02:53Type declarations are parsed at compile time and they cannot change during the
02:58life of the variable.
02:59The advantage of a strongly typed language is that performance is significantly
03:04improved over similar dynamically typed languages.
03:07In a dynamically typed system, runtime processing power is used to determine
03:12the type of a variable and create working copies with the appropriate data
03:17structures for every variable and even repeat these actions when a variable is changed.
03:22By determining the type of variable at compile time, all of this overhead is eliminated.
03:28The first written standard for the C programming language was a book called The
03:31C programming language by Brian W. Kernighan and Dennis M. Ritchie.
03:36The book came to be effectually known as K&R and the version of the language
03:40documented was called K&R C.
03:43The first edition of the book is long out of print;
03:46the revised version currently in print documents the next later version ANSI C.
03:51The ANSI C standard was ratified in 1989 and adopted by the ISO in 1990.
03:57So you'll see it referred to as both C89 and C90.
04:01The first truly standardized C, this version is the basis for most of the C we use today.
04:07ANSI C introduced function prototypes, void pointers and locals all of which are
04:12considered fundamental to C today.
04:14C99 is mostly compatible with ANSI C with a few new features and a few tighter restrictions.
04:21Notable enhancements include C++ style one-line comments introduced by two
04:26forward slash characters and variables can be declared anywhere within a
04:30block instead of only at the top of a block.
04:32C11 is the latest standardized version, and it codifies features that have
04:37been implemented by many compilers, including a more detailed memory models for threaded code.
04:43Removal of the get function improved Unicode support, anonymous structures and
04:47unions and some optional features.
04:50This course uses C11 but since most of the changes since ANSI C have been
04:55incremental, most of what you learn will apply to any standard C version.
05:00Because C is the foundation of C++ and the complete C language is included in
05:05the definition of C++, this course contains tutorials sufficient to learn the
05:10basics of the C language.
05:11Here is a list of chapters you may view in order to learn C from this course.
05:16Chapter 2 includes instructions on installing the environment for following
05:20the exercises along with a simple hello world program for testing your development environment.
05:25Chapter 3 includes an overview of the basic syntax of the C language.
05:29Charter 4 covers the C preprocessor and essential part of the language.
05:34Charter 5 describes the types of data used in C.
05:39Chapter 6 covers the rich set of operators providing in the C language.
05:43Chapter 7 discusses the use of functions and Chapter 11 covers the C standard library.
05:50These chapters will give you a thorough introduction to the language and with
05:53little experience enough to begin writing C programs on your own.
05:57The C programming language is the basis of C++ and is included completely in the
06:02definition of the C++ language.
06:04Learning C is an essential first step on the path to learning C++.
Collapse this transcript
About C++
00:00C++ was developed in the late 1970s by the Danish computer scientist, Bjarne Stroustrup,
00:06as a set of enhancements to allow object-oriented programming in C
00:10and today it is one of the most popular programming languages in the world.
00:14C++ is a powerful and flexible general purpose programming language that allows
00:20programming in a number of different paradigms, including object-oriented,
00:23procedural, functional and generic programming.
00:26C++ extends the C language adding many powerful features while retaining as much
00:33of C's efficiency and utility as possible.
00:35C++ is a very popular language and after 30 years, it's still widely considered
00:41a best practices choice for many types of projects, including large scale
00:45systems and applications coding.
00:48If you consider the layers of technology in a computer system as a stack, C++ is
00:52used to write code at all levels except firmware with its most common usage at
00:57the application level.
01:00Today, vast numbers of medium to large scale applications are written in C++.
01:05The list is huge and includes Microsoft Office, Adobe Photoshop, Illustrator,
01:10InDesign, Firefox, Google Chrome, provisioning service and billing systems for
01:15major phone and networks, even major web sites like Amazon, Facebook, and Google
01:20are either written in or have significant backend resources written in C++.
01:24Operating systems, including every version of Windows since 1.0, parts of UNIX
01:31that aren't written in C, major parts of OS X, other parts are in Objective-C
01:35which is also based on C.
01:37In fact, most other programming languages, including Java, PHP, Python, and Perl
01:43are written in C or C++.
01:44C++ is made up of a number of components, parts of which require understanding
01:50distinct sets of grammar.
01:52You can think of it as five distinct but connected languages.
01:56As part of the C language definitions, the C preprocessor is also
01:59incorporated in C++.
02:02The C language itself is the basis of C++, and is entirely incorporated in its definition.
02:08C++ classes and objects are used for object-oriented programming patterns.
02:13C++ templates are part of the C++ language and the C++ Standard Template
02:20Library sometimes called the STL which provides a tremendous amount of common
02:25functionality along with the C and C++ standard libraries is also a part of the C++ standard.
02:33The first standard for C++ was ratified by the ISO in 1998.
02:37This is commonly referred to as C++98.
02:41C++03 was essentially a bug fix release, so it's rarely referred to on its own.
02:47Most compilers that support C++03 simply refer to it as C++98.
02:53Technical Report 1 or TR1 is mostly a set of library extensions, including
02:57regular expressions, smart pointers, hash tables, and random number generators.
03:02Most of this became part of C++11.
03:05Ratified in August, 2011, C++11 is the first real extension of the C++ Standard.
03:12It provides a number of new features, including a range based for loop, type
03:15inference, lambda functions, and unambiguous null pointer constant, and most of TR1.
03:22This course uses C++11 and the latest versions of all the major compilers in use
03:28today support C++11.
03:31To thoroughly learn the C++ language, I suggest that you take this entire course in order.
03:37On the other hand C++ is a big subject you may want to skip around some, here's
03:42an overview of what is covered and where. Chapters 2 through 7 cover the C language.
03:47C provides all the basic syntax for C++. So this is a vital foundation for learning C++.
03:55Chapters 8 and 9 cover the object interface for C++.
03:58This is essential for all object- oriented programming and concepts and is used
04:04in other parts of the language, including templates and the STL.
04:08Chapter 10 covers the templates interface for C++.
04:11Templates are used in the Standard Template Library so you'll need to understand
04:15this in order to fully take advantage of many C++ standard features.
04:20Chapter 11 covers the C Standard Library which provides many common functions for C++.
04:27Chapter 12 covers the Standard Template Library.
04:30The STL provides many higher-level functions to C++ like strings, containers,
04:36algorithms, iterators, and other utilities.
04:39Chapter 13 covers some of the new features in the C++11 Standard.
04:44The C++ programming language is clearly one of the most important languages
04:48in computing today.
04:50It is the go-to language for many large and small projects and forms the basis
04:55of many other popular languages like Java, C#, PHP and many others.
Collapse this transcript
2. Getting Started
Using Xcode with the exercise files
00:00In this movie, I will show you how to create a workspace in Xcode for following along with
00:04the exercises in this course.
00:06I used Eclipse to demonstrate the examples in this course.
00:10I chose Eclipse because it runs on all the popular platforms today, but you don't need
00:14to use Eclipse to follow along with the exercises.
00:18Apple's Xcode is an excellent development environment and if you're a modern Mac it
00:22maybe a good choice for you.
00:24Xcode is an IDE, an Integrated Development Environment.
00:28It includes editors, compilers, and other development tools and they're integrated into
00:33an environment that makes them more easy and pleasant to work with than the tools would be on their own.
00:38The current version of Xcode as of late 2012 requires an Intel-based Mac running OS X Lion 10.7 or later.
00:47If you're running an earlier version of OSX you will not be able to use a current version of Xcode.
00:52In that case you should stop right here and instead install Eclipse with an updated GCC
00:57compiler toolchain.
00:59See the movies installing Eclipse with GCC on a Mac and upgrading GCC on a Mac for further instructions.
01:06The compiler that ships with Apple's Xcode is called LLVM.
01:10LLVM originally stood for Low Level Virtual Machine, but this initialism has been abandoned
01:15as the compiler toolchain is not really limited to development of virtual machines.
01:20LLVM is actually a compiler infrastructure that uses a front-end for each supported language
01:25or language group.
01:26The front end for C/C++ and Objective-C is called Clang short for C language.
01:33As of the time of this recording the current version of Xcode is 4.5 and the version of
01:38Clang that is shipping with Xcode 4.5 is Clang 4.1.
01:42This is the first version of Clang with sufficient support for C++11 for use with this course.
01:49When this course was originally released, the shipping version of Clang was not sufficient
01:52to support this course, at that time I recommend installing Eclipse and upgrading GCC to the latest version.
01:59This is no longer necessary on a modern Mac with the latest Xcode.
02:03Xcode also ships with legacy support for an older version of GCC.
02:08This GCC compiler is far too old to support all the language features used in this course. Do not use it.
02:14Now let's take a look at how to set up a workspace in Xcode for following the examples in this course.
02:19In order to proceed you will need to have installed Xcode 4.5 or later either from the
02:24App Store or from an Apple developer account.
02:28Xcode is free; it requires a modern Intel -based Mac running OS X 10.7 or later.
02:35I've already installed Xcode on this Mac.
02:37So let's go ahead and proceed with the installation.
02:40The first thing you're going to need to do is to install the Command Line tools.
02:44So we'll come up here to the Xcode menu and select preferences or you can press Command+comma,
02:50as you can see there in the shortcut on the right.
02:53And you will want to select Downloads here from the top menu.
02:56It may be on General or wherever you last used it and you'll want to select Download.
03:02From this little selector here, you'll want to select Components which is the one on the
03:07left and you see Command Line tools is the third one down and here it says Installed
03:12next to Command Line tools.
03:14If the Command Line tools were not already installed there would be a button there that says Install.
03:19You would want to press that button and wait while the Command Line tools are installed,
03:23and you'll probably have to type your password at some point during that process.
03:27So now that the Command Line tools are installed we'll go ahead and close this and we will
03:30create a new workspace.
03:33So you don't want to create a file or project.
03:35At this point you want to create a workspace.
03:37So that's from the File menu > New > Workspace.
03:40So I am going go ahead name this CppEssentialTraining and I strongly recommend that you do not use
03:47spaces in your project and workspace file names in Xcode.
03:52Some of the tools are a little bit finicky about that and a space can be interpreted differently.
03:56I don't use spaces. I don't use any special characters. I might use an underscore, I might
04:01use a dash, but in this case just CppEssentialTraining like that will work fine.
04:06I am storing it in my documents folder and you'll notice that that's right off of my home folder.
04:11You can store wherever you like just remember where you stored it.
04:14So I am going to press save and now we have a workspace.
04:19Now the first thing we want to do is to add a folder reference to our exercise files.
04:22So we are going to press this little plus down here at the bottom and I'm going to say
04:27Add Files to our workspace.
04:29I am just going to go my desktop which is where I have my exercise files stored and
04:36select the ExerciseFiles folder.
04:38If your exercise files are someplace else, you'll need to select that.
04:42Do not check copy items, because you don't want to copy this in your project, you want
04:46it to just link to it and you just want to select this one at the bottom that says Create
04:50folder references, and then I'll select Add, and now we have our exercise files here in our workspace.
04:58So I can open this disclosure triangle and that one and I see that I've got the files there.
05:04So what we are going to do is we are going to now create a project for compiling and
05:07running these exercises.
05:08And we will be copying files, not just linking to them, but actually copying them from here
05:14and into our project and then deleting them from our project when we are done with them.
05:18So let's go ahead and add a project.
05:19I am going to press this plus down here and I am going to say New Project.
05:24And in this case, I want to make sure I select OSX and Application and Command Line tool,
05:31and that's what you want, because all of these exercises are simply Command Line tools.
05:36The idea of these exercises being Command Line tools is to get everything else out of
05:40the way so that we can pay attention to the language feature.
05:44So we don't want to have a GUI application where we have to make lots of calls and callbacks
05:48and things like that, because that just gets in the way of understanding the actual language feature.
05:53These are very simple Command Line tools and this is the way that we want this project made.
05:58So we select Command Line tools and then press Next.
06:01I'm going to name my project.
06:03I am just going to call it Working.
06:04In Organization Name you can put whatever is there.
06:07That's just the name of my account on this Mac.
06:10For Company Identifier this is typically in reverse domain formats.
06:14So if you have a domain name, you can use it or you can just use example.com, which is what I do.
06:19So I will just say com.example and you see it puts the .Working already at the end of
06:25it for the bundle identifier.
06:27It's not even going to use that, but it requires that you can't really create this project without it.
06:31For type you want to have it be a C++ project which will allow you to use both C++ and C.
06:38You want to uncheck Use Automatic Reference Counting.
06:41It's not actually even available in C++, but it does add complexity to the executables
06:47and we don't need that.
06:48We are not going to use it.
06:49So you just uncheck that and then press Next.
06:54Now again, I am just going to go ahead and store it under Documents and you can store
06:58it wherever you like as long as you remember where you stored it.
07:01I am going to uncheck the Create a local git repository, because we don't need that.
07:07We are not going to be using it.
07:09For this project you are going to be creating files and deleting files.
07:11You are not really going to be building any project with it.
07:15So the git repository will just get in the way.
07:18And you are going to make sure that Add to has CppEssentialTraining, our workspace, and
07:25Group also has CppEssentialTraining.
07:27So we will go ahead and press Create.
07:33There we now have our Working project.
07:36Now let's check our build settings and make sure that they're correct.
07:38We are going to select our project and under Build Settings you want to select Basic and
07:43Combined up here, otherwise it just gets to be too hard to find things.
07:49Then scroll down to where you see Apple LLVM compiler.
07:57And you want no Optimization for your debug just like that, and that appears to be the
08:01default, and then under C Language Dialect this is under the Language part of LLVM compiler 4.1.
08:10Under C Language Dialect you want GNU99 just like that.
08:15So you see these are the different choices.
08:17If GNU99 is not the one that's selected you want to select GNU99 and you want GNU++11.
08:24Actually C++11 would work or GNU ++11 would work for this one.
08:28That's under C++ Language Dialect.
08:31The defaults here are probably fine, but if they're not what you see here than you want
08:35to change, and likewise for the Standard Library, you don't want libstndc++ like that.
08:42You want just libc++ like this.
08:44That's the GNU library and since we are not using the GNU compiler it won't work.
08:49You want to make sure you have the LLVM version selected.
08:53So if these are all correct we will come over here now and just select this main.cpp in
08:59the working project.
09:00You will notice that it's just a simple Hello, World! Program.
09:03We are not going to use that.
09:04So we are going to go ahead and delete it.
09:06So with this selected I am going to press the Delete key on this keyboard and I am going
09:12to actually Select Move to Trash, not just Remove Reference, but Move to Trash.
09:16That's really important because this has a main in it, you see, and you can't have more
09:21than one main and each of examples has a main.
09:24So we really need to remove this from the project entirely.
09:27So I select Move to Trash and I do the same with this Working.1.
09:33That's a man page.
09:34It assumes that since we are building a command line application that we are going to man
09:37page and this is in this ROFF language.
09:40It's probably NROFF.
09:43But it's not anything we really need to know about or care about.
09:45This is how man pages are made and we are not going to make a man page.
09:48So we are just going to delete this file and I am going to select Move to Trash again and
09:54there we have it.
09:55So now we have our working project and this working group inside, they called it a group.
10:00It's very much like a folder.
10:02This working group is where we're going to be putting our files.
10:05I am also going to hide this information panel.
10:08You might want to leave it there, but for my purposes because I've such limited screen
10:11real estate here I am just going to get rid of that.
10:14Now before we go any farther there is one more thing we need to do.
10:17We need to edit our Scheme.
10:20So you see this is Scheme area up here and we have a working scheme and we also have
10:24it compiling for the 64-bit Mac and you'll have whatever is there for your Mac.
10:29It will probably be a 64-bit Mac if it's an Intel Mac running OSX 10.7.
10:35But you're not going to select that.
10:37You're instead going to select the word Working.
10:39If you have your Working projects selected you'll have this working up there for the scheme.
10:42You're just going to say Edit Scheme under that menu.
10:47So here it says Working, Scheme, it says Destination, My Mac 64-bit, and down here you have all
10:53of these profiles.
10:54Within it you want to select Run Working and then come over here and select arguments in
10:59this little menu there.
11:01Then arguments passed on launch.
11:02You are going to press the plus sign to add an argument, and just type the word one, and then
11:07you will press plus sign again and type the word two, and press the plus sign one more
11:12time and type the word three.
11:14Once you have one, two, and three in there you are going to press OK and that's command
11:20line arguments and we will see how those work later in this movie.
11:23So now we are ready to go.
11:24We are going to open up the ExerciseFiles disclosure triangle and open up Chap02 and
11:29select version-test.cpp.
11:32Now what I am going to do is I am actually going to copy this into my working project.
11:36I'm not going to work on it here.
11:38In fact, it won't compile here, because this is not within a project.
11:41I am going to make a copy of it.
11:43I am going to drag it up to Working and you see how it's highlighted the Working folder
11:49icon there in blue and there's a plus sign.
11:52I am not pressing any modifiers on the keyboard, I am just dragging the file up there.
11:56You don't want to put in Products, you don't want to put it up here, you want to put it
12:00right in there in that Working folder.
12:01So I am going to let that go and I am going to check Copy items, because we want to actually make a copy now.
12:08If we allow it to be a reference, then we will be modifying the original and that defeats
12:13our purpose of making a copy.
12:14I want to be able to make a copy. I want to be able to modify it and change it and be
12:17able to revert back to the original, if we need to.
12:20So we have to leave these files alone in our file system.
12:23So we are making a copy of it there under Working.
12:25Check the Copy box, check create groups for any added folders, and Add to target Working,
12:32that's very important, and Finish.
12:35Now we want make sure we actually select this one.
12:37We don't leave this one in the file system selected, because we are going to edit it.
12:41So we select that one there.
12:43Before you press the Run button actually, you want to come over here to Product and
12:47run Clean just in case you've compiled something before in this project.
12:51Now you're going to come over here press the Run button and it will compile.
12:55It says Build Succeeded, and it runs it, and there it is.
12:59There is my output.
13:01So you see that it says GCC version 4.2.1, and that is actually irrelevant.
13:07That's the equivalent GCC version.
13:09We are not actually running GCC.
13:11We are running LLVM and Clang.
13:13So you notice the version string says 4.2.1 which is the last version of GCC that ever
13:19shipped with Xcode, and they are not shipping anymore, and they won't ship anymore for a lot of reasons.
13:24Instead they're using Clang and so it says 4.2.1 compatible Apple Clang 4.1.
13:31So this is actually the string here that you're concerned with.
13:34It needs to say 4.1 or higher and if it does, then you're in good shape.
13:40So we want to do one more thing here.
13:41We want to check it will actually compile C++11 features.
13:45So you select these lines here and I'm pressing Command+/ on my keyboard and that will uncomment
13:54those lines, and Command+S will save it, and I am going to press this Run button again
14:01and now it's done a whole lot more stuff.
14:03So I am going to scroll up here so we can see the whole thing.
14:06After version string we have one, two, three which is from this vector that be created
14:11using the Initializer List feature from C++11.
14:15This will not compile on an older version of the compiler.
14:19It won't compile on older Clang.
14:21It won't compile on GCC.
14:23This is confirming that you're actually using the current version of Clang and that it's
14:27set up to compile with the C++11 features.
14:32So if that works then we print it out using another C++11 feature the range based for loop.
14:38This is a new construct in C++ and you see that that works as well.
14:43We have this one, two, three.
14:45So we've now confirmed that we have working C++ 11 compiler and that it's actually working.
14:53So we are going to go ahead and delete this version test from our Working project.
14:56I select it and I press the Delete key on my Mac keyboard, and select Move to Trash, and
15:03now we are going to copy over this file that says c99.c.
15:07I am just going to drag that up into my Working project and let it go.
15:12These haven't changed.
15:13So I have copy items, I have create groups, I have checked working.
15:16I press Finish and now I am going to select this file and there it is.
15:23This is a simple C file. This is not C++.
15:25You notice it has .c in the filename.
15:28That makes it C not C++.
15:31I want to come up here to product and run Clean.
15:33This is very important.
15:34You need to do that to make sure that it will compile this and not add it to the other one,
15:39and I'm going to select Run.
15:42So this is testing that our compiler actually runs C99 code as opposed to older versions of C.
15:49Whatever it says here under 0 is just going to be the actual location of the working code
15:54that's been compiled.
15:56That's not really relevant, but if 1, 2, and 3 say one, two, three with the words, that
16:01means that it's grabbing the command line arguments and it's printing them out with
16:04C99 feature right here which allows you to both declare and initialize a variable inside
16:10a for loop control structure.
16:13So we can see that that's working right there, and we have now successfully created our Xcode workspace.
16:21So I am going to go ahead and delete this from my Working project, and I'm going to run
16:28Clean, and now we are ready to proceed with the exercises.
16:35So you now have a working Xcode workspace for following along with the exercises in this course.
16:41Xcode is an excellent IDE and LLVM is becoming a superb compiler.
16:46This combination provides a great environment for the exercises in this course.
Collapse this transcript
Setting up Eclipse with LLVM and Clang on a Mac
00:00In this movie, we're going to install the Eclipse C Development Tools on a Mac using
00:05the LLVM toolchain provided with Xcode.
00:08Note that it's not necessary to install Eclipse in order to take this course.
00:12Even though I used Eclipse for the exercises in videos, you may prefer to use Xcode on
00:17your Mac and that will work fine.
00:20Please see the movie Using Xcode with the Exercise Files for instructions on setting
00:24up Xcode for use with this course.
00:27I used Eclipse for the examples in this course because it's convenient for teaching purposes.
00:31It allows me to demonstrate the examples in a way that is accessible to students on any
00:37of the three major platforms today: Windows, Mac, and Linux.
00:41This is the only reason I used Eclipse for this course.
00:43I normally do my development work with whatever tools are supported on the platform I'm working
00:48on and I encourage you to do the same.
00:51In order to install Eclipse on a Mac, you'll need a few things.
00:54You'll need a relatively modern Mac, running Xcode with the command line tools installed.
00:59The current version of Xcode requires an Intel based Mac running OS X Lion, 10.7 or later.
01:06If you're running an earlier version of OS X, you will not be able to use a current version
01:10of Xcode and in that case, you should stop right here and instead install Eclipse with
01:16an updated new GCC Compiler toolchain.
01:19See the movie, Installing Eclipse with GCC on a Mac and Upgrading GCC on a Mac for instructions.
01:27You will also need the Java Runtime Environment.
01:29If you don't have Java installed, OS X will offer to install it for you the first time you run Eclipse.
01:36So I'm going to launch Xcode and I'm just going to bring up About Xcode here and you
01:43can see that this is Xcode 4.5.2.
01:47Any version of Xcode version 4.5 or higher will work for this purpose.
01:52Xcode is free from the App store.
01:54If we come in here to Preferences and under the Downloads tab and under Components, you'll
02:00see that I have installed the command line tools.
02:03You'll need this in order to run LLVM with Eclipse, and so I have the latest Xcode installed
02:08and I have the command line tools installed, I'm just going to click this Check for updates
02:13right now, here it says no updates available, and I have always checked this little check box.
02:19These updates are the developer tools and you need to keep these as updated as possible.
02:24So Xcode is free from the Apple App Store and you need a free developer account and
02:30then you can install the command line tools and that's what you'll need in order to do this.
02:35So I'm going to close this, I'm going to close Xcode and now we'll install Eclipse.
02:41So I have up here, on my screen, I have the Eclipse Download page at eclipse.org/downloads/
02:48and you'll notice all the way down here, it says Eclipse IDE for C/C++ Developers and
02:54I've already downloaded this Mac OS X 64 bit version and I have that here in my Downloads folder.
03:02So I have downloaded that from the Eclipse website and I'm just going to double-click
03:05on it here, and you see that the Archive Utility expands it, and expands it again and then
03:12we have this folder here which is called eclipse.
03:17And I simply drag this folder into my Applications folder and over here in Applications, we see
03:25there it is eclipse and I come in here and I take Eclipse.app and I just drag that down
03:31onto my doc here and I click on it and that runs Eclipse.
03:35It gives me a little warning that I downloaded it from the Internet and I click Open and
03:41now here it's just running because Java has already been installed on this Mac, but if
03:45Java had not been installed, it would give me an opportunity to install Java.
03:50It's giving me a default choice for my workspace which is under Documents, under my user account.
03:55I'm just going to say, Use this as default and don't ask me again and say OK and there
04:00we have the opening screen for Eclipse.
04:03So I'm going to click the little green button here to maximize this window and I'm going
04:07to click on Workbench.
04:08So you have a number of different choices here and most of them are not things that we need.
04:13We're just going to click on Workbench and it'll default to this in the future.
04:17And you notice over here at the right, it's got my C/C++ tools highlighted.
04:22You might have some other tools up here, you might have some other things up here if you've
04:26used Eclipse for other purposes.
04:28But for our purposes, we're just going to be using this C/C++ tools.
04:32So this is our Eclipse workspace.
04:34You might notice that it looks a little bit different than the one that you have, and
04:37you might notice it looks a little bit different than the one that I used when I recorded the
04:41rest of this course.
04:42Different versions of Eclipse, they change their interface a little bit now and then,
04:46it shouldn't impact how you use it. It will all work just fine.
04:52So the first thing we're going to do is we're going to open up the Preferences and so that's
04:56under the Eclipse menu here and under Preferences, or you can press Command+comma, like you
05:00would with any Mac program.
05:04Under General and Workspace, and you'll see down here, Text file encoding and it defaults
05:10to MacRoman, which is just wrong.
05:13We want it to default instead to UTF-8 and we'll go ahead and press Apply.
05:18The text file line delimiter, Default is Unix, which is just fine.
05:22If it doesn't say Unix there in yours, just click Other and select Unix from these choices and click Apply.
05:30Now we are going to come down here under C/C++ and New CDP Project Wizard, and you'll notice
05:39that you have a selection here on the left and a selection here on the right.
05:42The selection on the left, Executable should be opened up and if it's not, just open up
05:46the little disclosure triangle there and select Empty Project, and under Toolchains you want
05:52to select the MaxOSX GCC Toolchain and click Make toolchain(s) preferred.
06:00Now we're going to come back up here to General and under Editors and Text Editors, and we
06:06just want to check everything here except for Insert spaces for tabs and Show print margin.
06:11So we're just going to check Show line numbers, whitespace, all of these should be checked
06:16except for Insert spaces for tabs and Show print margin, everything else should be checked.
06:21And under General and Appearance, you see Colors and Fonts, and you probably don't need
06:28to change anything in here, but I'm going to come up here and under Basic and under
06:33Text Font, I'm going to make it bigger because my screen is going to show up really small on your screen.
06:40And so, you probably do not need to change this, I am just going to click Edit here,
06:44so I'm going to go in here, and I'm just going to type in 16 points and close that, and that's
06:50just for my purposes of using this screen for the training. You probably don't need to do that.
06:57Now here under C/C++, under Editor, I'm going to click on Folding and you want to check
07:04all three of these boxes at the top and make sure of all of these other ones are unchecked,
07:09that enables all the different kinds of folding, but initially does not use any of them and
07:15that can be really useful.
07:17So for now we're done here. We're going to come back and we're going to change some of the stuff later.
07:21I'm just going to press OK.
07:23And we're going to now create a new project.
07:27So under the File menu > New > Project, do not select C++ Project for this, we'll
07:35get to that later. For now you want just Project.
07:38These may be in a different order on your menu and that's fine, just select the one
07:41that says Project with the ellipsis after it there, and under General you just want
07:45to select Project, and again, these may be in a different order.
07:49You just want the generic project at this point.
07:51And we are going to select Next and we're going to call this CppEssentialTraining, like that.
08:01Do not use any spaces or any punctuation in your file names in Eclipse.
08:05They may be legal in your operating system, they certainly are here on a Mac, but some
08:10of these tools that are part of Eclipse are actually pretty old and they get messed up
08:14with spaces and punctuation in your file names.
08:17So I just avoid--when I'm using Eclipse, I avoid using any spaces or punctuation in my file names.
08:24And I'm just going to click Finish and now we have this empty project here for C++ Essential Training.
08:31I'm going to right-click on the project or you can Ctrl+click if you have a one button
08:35mouse and say New > Folder within the project.
08:40And I'm going to click on this Advanced button here and I'm going to say, Link to alternate
08:45location for a Linked Folder, and we'll browse here and on my Desktop, see my ExerciseFiles,
08:54I'm just going to open that and all this is now filled in for me.
08:58The folder name is ExerciseFiles, it's linked to an alternate location and there is the
09:03exercise files I'm linked to.
09:04So wherever you have your exercise files on your system, I've got them on my desktop,
09:09they may be someplace else in yours, you want to link to that location and make sure you
09:14have Link to alternate location selected here and I am going to select Finish.
09:19And so now when I open up this exercise files, I see I have got each of my folders in here
09:23and I open those up, they have the files inside of them.
09:27That's fine for now, now we are going to go ahead and create a project that we're going
09:30to use as our working space for actually working on the files.
09:34We are not going to work on them in place here we are going to copy them into another
09:37project where we are actually going to compile them and work with them.
09:40There is good reason for this and we'll get to that a little bit later.
09:43So we are going to come back up here to the File menu and New and now we are going to
09:48select C++ Project.
09:51Our project will be called Working and you noticed down here under Executable, it says
09:57Empty Project and our Toolchain is MacOSX GCC.
10:02So if any of these are not selected, these may again be in a different order.
10:06Executable may not be the one that's selected, make sure you select Executable and Empty
10:11Project under there, and your toolchain should say MacOSX GCC and if it doesn't, you want
10:17to go back and do this setup before that we did in the Eclipse Preferences and make sure
10:22that you set that for the default toolchain.
10:25So I am going to select Finish here and it's created a new project here called Working,
10:31and you notice inside of it, it has an Includes folder and that's all that's in it. So I come
10:37up here to ExerciseFiles and open Chapter 02 and select version-test.cpp.
10:44And I'm going to copy that, I am pressing Command+C on my keyboard and then select Working
10:49down here, my Working project and select Command+V on my keyboard to copy--to make a working copy
10:55of that version-test.cpp.
10:58If you just drag it down there, you run the risk of moving the file rather than copying,
11:03Eclipse ought to give you the choice of copying it.
11:05But it's a lot easier to just copy and paste using Command+C and Command+V.
11:10So now I am going to double- click on version-test.cpp.
11:14Now the first time you open this up, it may show you some errors, it may take Eclipse
11:20of couple of minutes even to update enough of itself so that it recognizes this code,
11:25and that's okay and that's not uncommon.
11:29So the very first time that I run something inside of Working I need to build, and so under
11:34Project I am going to click Build Project, and now it's done that and you will notice
11:39down here in our Project we have a few extra folders, we have his Binaries folder and we
11:44have this Debug folder, and that's all to be expected and that works just fine.
11:48I am going to go ahead and collapse this panel over there on the right so we have a little
11:53more room for this.
11:54I am just going to move this over here a little bit, so we have a little more room for our
11:58code, and now I am going to go ahead and run the code.
12:02On my Mac I can press Shift+Command+F11 or I can press this green button up here that says Run.
12:07And I am just going to run that, and now down here at the bottom my Console becomes selected,
12:15and I see the GCC version 4.2.1 and my version string which says 4.2.1.
12:21Now over here it says LLVM build and all that means is this version of GCC was compiled
12:29with the LLVM compiler. It does not mean that this is based on LLVM at all.
12:33And in fact, it's not. This is a very old version of GCC, as of this recording this is a five-year-old version of GCC.
12:41It is not sufficient for our purposes, so we are not going to use it, instead we're
12:47going to use the LLVM Compiler with the C language front-end called Clang.
12:53And so here's how we do this.
12:54We come over here to our Working project and select that.
12:57I am going to press Command+I on my keyboard, alternately you can right-click on it and
13:02if you scroll all the way down here to the bottom you will see something that says Properties,
13:05and I am just going to press Command+I instead and that brings up the Properties for the Working project.
13:12Now if I come down here to the C/C++ Build, and I open the disclosure triangle, and I click
13:18on Settings down here, and you see where it says MacOS X C++ Linker, GCC Assembler, GCC
13:30C++ Compiler and GCC C Compiler.
13:32So what we are going to do is we are actually going to change these settings, so instead
13:37of using the GCC Compiler, it's going to use the LLVM Clang Compiler.
13:42So we are going to start with the C++ one, GCC C++ Compiler and up here where it says
13:48g++ I am going to change it so that it says c++, and then in that same section under Miscellaneous,
13:54I am going to add a couple of command line options down here, so I put in a space and
14:00I type -std=c++11.
14:05That tells it to use the C++11 standard for its internal compiler, and another space and
14:11-stdlib=libc++, that tells it to use the Apple version of the libc++ standard library.
14:24And up here under the MacOS X C++ Linker, I do the same thing, I change that g++ to
14:32say c++ and then under Miscellaneous down here, I add -stdlib=libc++; exactly the same
14:42as I did for the C++ Compiler.
14:45Now we come over here under the C Compiler and I change GCC to just CC like that, and
14:52under Miscellaneous, I am going to come out here and I am going to say space -std=gnu11
15:01and that will have it use the latest standard for C programs as well as C++ programs.
15:08Now there is just one more thing we need to do here, under Run/Debug Settings over here
15:12on the left, select our Working project and press the Edit button, and come over here under Arguments.
15:19We are going to going to give it some default arguments so that every time it runs our Working
15:23project it's going to run it with some command line arguments. So we are just going to type
15:26in the words one two and three, and those will be used for our command line arguments whenever
15:32we run that project.
15:33So we say OK there, over here we say Apply and OK, and now I'm going to come back over
15:41here under Project and I'm going to run Clean, and I am going to make sure it says Clean
15:46all projects and just say OK, and now we are going to run it again.
15:50We are just going to press this Run button and it will compile it and run it.
15:55And now you see it says Version string, it still says 4.2.1, but it says here 4.2.1 Compatible Apple Clang 4.1.
16:05This is a different compiler that one we were running before. This is actually now using
16:09Apple Clang 4.1 with the LLVM Compiler, and we can test this and make sure that it uses
16:17our updated C++11 features by uncommenting this block of code.
16:22I am just going to select it and I am going to press Command+/ on my keyboard which will
16:27uncomment it, and Command+S to save and press the Run button up here, the little green Run button.
16:33And now you will notice that it's actually running all this code and we have the one two three.
16:38So these are C++11 features.
16:40This is the initializer list, this is the range based for loop.
16:44These will not work in that old version of GCC that we were using before.
16:49So we are actually now compiling successfully with the Apple Clang LLVM Compiler.
16:56Now just one more test we want to run here.
16:58I am going to go ahead and I'm going to run Project > Clean and that will clean our project.
17:03I'm going to delete this file from our Working project; I am just pressing the Delete key
17:08here on my Mac keyboard and the Enter key to select OK there.
17:13Now I am going to come up and make a copy of this c99.c out of the Chapter 02 folder
17:19of our exercise files, so I am pressing Command+C, come down here to the Working project, Command+V,
17:24double-click on it and compile and run.
17:27Just press this green button, it compiles it and runs it and we'll notice here that
17:33it's running this code just fine.
17:34Now, this is using code in the C language that will not work with that older compiler.
17:40In particular, this declaring and initializing a variable inside of a for loop, this is a
17:46C99 future and with the default installation of the GCC Compiler, there are command line
17:51switches that you can give it that will make this work, but this is showing that we have
17:55done that installation properly and that everything is working as it should.
17:59So we'll go ahead and run a Clean again from our Project menu, and we'll delete this file
18:04from our Working project, and now we have a working Eclipse with the latest LLVM Clang
18:10Compiler installed and running on a Mac.
18:12Again, there is no reason that you need to run Eclipse, but if you don't have another
18:16environment or you would like to just follow along with the exercises in this course, Eclipse
18:20will work just fine for you.
Collapse this transcript
Setting up Eclipse with GCC on a Mac
00:00In this movie, we're going to install the Eclipse C Development Tools on a Mac.
00:05Keep in mind that it is not necessary to install Eclipse in order to take this
00:09course, you may use whatever development environment you like, in fact I
00:13encourage you to use your own development environment.
00:16I am using Eclipse for the examples in this course, because it's convenient for this purpose.
00:21It allows me to demonstrate the examples in a way that's accessible to students
00:25on any of the three major platforms today; Windows, Mac and Linux.
00:29That is the only reason I'm using Eclipse for this course.
00:32I normally do my development work with whatever tools are supported on the
00:36platform I am working on, and I encourage you to do the same.
00:40In order to install Eclipse on a Mac, you'll need a few things.
00:43You'll need a relatively modern Mac running Xcode with the Command Line Tools installed.
00:48You'll need the Java Runtime Environment, and you'll need a version of the GNU
00:52compiler, GCC version 4.70 or later. Let's take a look at these, one at a time.
01:00I have Xcode running here on this Mac, and I have the Preferences dialog box
01:04open, and I've selected Downloads in the Preferences.
01:08And you'll notice the bottom item here, it says Command Line Tools, and it says Installed.
01:13If yours does not say Installed, it will have one of these Install buttons
01:17like this other stuff has, and you'll press that button, and you'll install
01:21the Command Line Tools.
01:22Keep in mind that in order to install the Command Line Tools on a Mac, you'll
01:26need an Apple Developer account.
01:28The free version of the Apple Developer account is just fine.
01:32So I am just going to quit out of Xcode here, I am going to press Command+Q, and
01:37now we are going to install Eclipse.
01:38Now Eclipse is written in Java, and it was originally developed to be a Java
01:43IDE, IDE stands for Integrated Developer Environment.
01:47And over the years it's been expanded to support a number of different
01:50languages, and it now also supports C and C++.
01:54The beauty of Eclipse is that the same code runs on a number of different platforms.
01:59So I can demonstrate for you the examples for this course, and you can have
02:03exactly the same screen on your screen and follow along no matter what
02:06platform you're running; Windows, Mac or Linux.
02:10But you do need a Java Runtime Environment in order to run Eclipse.
02:14The nice thing on a Mac is the first time you run Eclipse, if you don't have
02:17Java installed, it will give you the opportunity to install it at that time.
02:21So looking down here, you see it says Eclipse IDE for C/C++ Developers (includes Incubating components).
02:29And if yours doesn't say that includes Incubating components, that's just fine.
02:32That just means some of the components that are included are yet
02:35considered fully released in the Eclipse world, but they're working just
02:39fine for our purposes.
02:41So because it knows that I am on a Mac, you've got this little drop box here if
02:44you want to install something else, but it should default to Mac Cocoa.
02:48And you see I have a choice of the 64 Bit or the 32 Bit.
02:52This is a 64 Bit Mac and so I've downloaded the 64 Bit version.
02:56And you can see it right here in my Finder under Downloads.
02:59So I am just going to double-click on that eclipse-cpp blah, blah, blah...
03:03And you'll go ahead and expand the archive, and I have this folder called
03:07eclipse, and I am just going to drag that into Applications and eclipse, believe
03:11it or not is now installed.
03:13So I'll select Applications, and I'll scroll down here until I find eclipse, and
03:18there is the folder, and inside the folder, I have Eclipse.app.
03:22I am just going to drag that down here to my dock and run it.
03:26It says I've downloaded it from the Internet, and I am sure that I want to run
03:30that, so I select Open, and there it is.
03:33Now at this point, if you didn't have Java installed, it would give you the
03:37opportunity to download and install Java.
03:39So the first time I run Eclipse, there's a number of things I have to do.
03:42The first one is is I have to select a workspace.
03:45So there is what it's defaulted for me, and I am just going to accept the
03:48default, and I'm just going to click this box so that it doesn't ask me every
03:51time I start up Eclipse.
03:54Now it's finished loading the rest of its stuff, and I'm just going to click
03:58on Workbench which is the rightmost button here, and that will take me to my Workbench.
04:03And I am going to click Maximize, and there we have Eclipse.
04:06So the first thing I am going to do before I create a Workspace is I am going to
04:10set some preferences here.
04:12So come up here into the Eclipse menu and select Preferences and under General,
04:17go down here to Workspace, and you see where it says Text file encoding.
04:22The Default is MacRoman, MacRoman is a very, very old text file encoding, and we
04:27are not going to be using that, we are going to be using UTF-8.
04:30So I select Other in the dropdown box, and I select UTF-8, and that allows us to
04:37work with files from different platforms.
04:39Of course all the files in the exercise files are in UTF-8 so that they'll work
04:43on different platforms.
04:45So I am going to press Apply, and then I'm going to go up here to General and
04:49Editors and under Text Editors, I am going to select a bunch of these boxes.
04:55I am actually going to select all of the check boxes except Insert spaces for
04:59tabs and Show print margin.
05:01So I am going to select line numbers, range indicator, whitespace characters,
05:06of course Highlight current line, all of these are going to be selected except for those two.
05:12I am also going to click on this little link down here that says Colors and
05:15Fonts, you can also find that under Appearance > Colors and Fonts, and this is
05:20just for the purposes of my computer while I am demonstrating.
05:24I need to make the text a little bit larger than the default, you probably
05:28don't need to do that.
05:29If you select this, and you look down here, and you can read The quick brown
05:33fox, and it looks just fine to you, then you don't need to change this.
05:37For my purposes I need to use a little bit larger font.
05:40So I am going to select that and press Edit and under my Recently Used I
05:44have this Calynda and 18 point, and that makes this nice and big and
05:50readable for this purpose.
05:52I am also going to do the same thing under Text editor Block Selection Font.
05:55That probably won't even get used, but just in case there it is.
06:00Now we are going to go here under C/C ++, I am going to fold up this General
06:04here and go under C/C++.
06:06And under New CDT Project Wizard you have Preferred Toolchains selected here and
06:12Empty Project under Executable, and I am going to select the MacOSX GCC.
06:18For the Toolchain, I am going to say Make toolchain preferred.
06:21And you see you get that little arrow there next to the MacOSX GCC.
06:25And that's really important, that makes the MacOSX GCC toolchain the default
06:30toolchain for all of your new projects.
06:33If that's not selected, your new projects won't compile and they won't run.
06:37Still under C/C++ here, I am going to go to editor, and I am going to expand
06:42that, and I am going to click on Folding.
06:45What Folding is is that's when you have blocks of things in your source code, it
06:49can fold them up so that you don't see all of the contents of that block.
06:53We want that enabled, but we want it off by default.
06:58So we are going to select all of these enabled things, and we are going to
06:59uncheck all of these initially fold things.
07:02So your screen should look like this, you got the top three checked and all of
07:06these other ones, unchecked.
07:08So I am going to press Apply, and I am going to press OK, and we're now ready
07:12to create a project.
07:13So I am going to go in here to Project Explorer, and I'm just going to select
07:16this little disclosure triangle there next to the New project icon, and I am
07:21going to say Project, the generic project.
07:23We're not making a C++ Project at this point, we're making a generic project
07:28because this is just going to be a holding tank for our source files, we're not
07:32actually going to compile inside this project;
07:34we are going to create a second project for doing our compiling.
07:37So I'll select that and under General, I am going to select Project, and I am
07:42going to press Next.
07:43I am going to name the Project C++ (Cpp ), and I'm just using the P characters,
07:48and I am going to say EssentialTraining, and you'll notice I don't even have any spaces.
07:53I don't typically like to use spaces in file names especially for source code,
07:58because there are some tools occasionally that seem to not work with spaces and
08:02special characters in filenames, so for the most part, I really try to stick to
08:06just plain ASCII compatible text characters in filenames, and that avoids
08:11problems that can sometimes be hard to find.
08:14So I am just naming it CppEssentialTraining like that.
08:17And I am going to select Finish, default location is fine for me, you might want
08:21to put it someplace else. But that's fine.
08:23And I am going to right-click on that and say New > Folder and select Advanced,
08:30and we are going to link to an alternate location.
08:33This allows us to bring in our exercise files without actually having to move
08:37them from their default location, because we are not going to really edit them
08:41in place, we're going to be making copies of them and putting them into our
08:45Working project in order to compile them.
08:47So press Browse and--on the Desktop-- select ExerciseFiles, that's where I've put
08:54my ExerciseFiles, yours may be someplace else, and Open, and it will fill in the
09:00folder name, you can leave that alone and the rest of this should be just fine,
09:04and I can say Finish. And there we have it.
09:06Now we have our project with our ExerciseFiles, and you see there are all of the
09:11ExerciseFile folders inside with all of those files.
09:15For now, I am going to come back up here and make one more project, and this is
09:20actually going to be a C++ Project.
09:22We are going to call this one working, Use default location is fine, you
09:26notice the Toolchain is selected, it says MacOSX GCC, and it's got the little arrow next to it.
09:32If yours doesn't have that little arrow then you need to go back and do
09:35the Preferences setting again, because you missed something in setting the Preferences.
09:40So you leave this as Empty Project and make sure that that's selected and just
09:46press finish, and we now have our Working project down here, and you'll notice
09:50that it just has one folder inside of it for the Includes, we're going to a
09:54fix that in a moment.
09:55First thing I am going to do here is I am going to go under ExerciseFiles in
09:58the CppEssentialTraining and select Chap02, and there's a file in here called version-test.cpp.
10:06If you want to make copy of that, you can press Command+C or you can Ctrl-click
10:10or right-click and select Copy and then come down here to Working and either
10:14press Command+V or Ctrl or right-click and press Paste.
10:18So what we've done is we've copied and pasted this file here down into Working,
10:22and that's how we're going to run all of our examples in this course.
10:26So that's the pattern you are going to get used to.
10:28You select the file in the exercise files, press Command+C to copy it and come
10:32down here to Working and Command+V to paste it.
10:35Now before we can run it, we need to actually select the project.
10:39So I am selecting the word Working there, and it's highlighted and then come up
10:44here to Project and select Build All or just press Command+B. And you'll notice
10:49that what this does is it builds up the project, and it builds all of the
10:53support files inside of the project that it needs and creates a couple of extra
10:57directories and everything, and it actually compiles stuff and makes stuff all
11:01ready so that it will work.
11:03You only need to do that the first time you create the project.
11:06We won't actually need to do that anymore throughout the rest of the course.
11:10So I am going to double-click on version- test.cpp, and there is our source code
11:14in nice big letters, yours hopefully will be the right size for you, and I am
11:19just going to double-click on this here so that you can see the entire file.
11:23There's a lot of stuff in here that you don't need to understand at this point.
11:26Really all we're doing right now is trying to find out what version of
11:30compiler we have installed.
11:31But I want to show you a few things here at this point, because as we go through
11:35the course you're going to notice these things.
11:36First of all, you'll notice that all of the spaces are visible as little middle
11:40dots and they are light color gray, the tabs look like this with the two right
11:47angle bracket character, it's like a European quote mark and the paragraph
11:51markers look like that.
11:53And the purpose of this is whenever I'm working with source code, these little
11:57details like is that a space character or is that a tab character, these things
12:01can sometimes matter.
12:02So whenever I am working with source code, my Text editor always has all of the
12:06meta-characters visible, whatever they call it, whitespace characters or show
12:10tabs and spaces or whatever that setting is in the editor that I am working
12:14with, that stuff is always visible.
12:16So here is our source file, and I'm going to go ahead and compile and run it,
12:20and select from the Run menu, this Run Last Launched.
12:23Actually, I am not even going to do that, I am just going to press
12:26Shift+Command+F11, because you are going to want to know a shortcut for this,
12:30you are not going to want to have to go to the menus all the time for it.
12:33Alternately, you can come up here and press this little green arrow, and that
12:36will do the same thing.
12:37So I am just going to press Shift+F11 and F, and it compiles it, and it runs it,
12:43and there we have the console right up here, and it says GCC version 4.2.1, and
12:48it's got this version string that this is the Apple default compiler.
12:52And if I close that and come back up here and double-click on that tab, and then
12:57we have our full screen, this is probably the way you'll run things.
13:00And if I do this again, Command+ Shift+F11, and it runs it down here.
13:05So you can see the source code and the output at the same time.
13:09It might also be worthwhile for you to know that if you press this icon over
13:13here, it says Display Selected Console;
13:17you can see the output of the compiler as well.
13:20Then press it again, and you get the output of the program after its run.
13:24So what we know at this point is that we are running GCC 4.2.1, and that is less
13:30than 4.7.0, which is the minimum we need to be able to use C++11 features, and
13:36so at this point, we actually need to download and install the latest GCC.
13:42And I'll show you how to do that in the next movie.
Collapse this transcript
Upgrading GCC on a Mac
00:00In this movie we are going to upgrade the GCC toolchain for use with Eclipse on a Mac.
00:06Here I have Eclipse installed on this Mac, and I've found that the GCC version
00:10is not sufficient to support the latest C++ Standard C++11.
00:15You notice here that the GCC version is 4.2.1, and this class uses C++11
00:21features, so we'll need a GCC of at least 4.7.0 for its C++11 support.
00:28As of the time that I am recording C++11 is new and GCC 4.7 is new, so we are
00:35going to install 4.7.0 so that it has support for the new C++ features.
00:40Here I have the web page of High Performance Computing, which is a port of GCC
00:46that works on a Mac.
00:48And it's hosted at sourceforge.net and the URL is hpc.sourceforge.net.
00:55And we'll see here that the latest version is GCC 4.7, and you're free to
01:00use the latest version whatever that is, and you'll notice under binaries we
01:04see gcc-lion.tar.gz.
01:07There's another one gfortran-lion.tar.gz, and that's only FORTRAN that does not include C++.
01:15There's also versions down here for Snow Leopard, so if you're running
01:19Snow Leopard, and you're not running Lion, then you'll want to install
01:23that Snow Leopard version.
01:24I am running Lion on this Mac and so I've already downloaded gcc-lion, and I
01:30have that here in my Downloads folder.
01:33I am just going to double-click on it and let OS X open the Archive and here we
01:39have a folder that includes the compiler tools.
01:42And so under this usr and under local you see there are our compiler tools.
01:47We have bin, include, lib, libexec, and share. So that's all the GCC toolchain.
01:54So I am going to take this local folder, and I'm actually going to rename it,
01:58and I'm going to call it hpc-gcc.
02:03And you want to do that with the local folder, you don't want to rename the user folder.
02:07And I am just going to drag it into my home directory.
02:10And there it is it's going to be whatever your home directory is on your Mac.
02:14So you drag it into your home folder, and there I've selected my home folder,
02:18and you see I have a folder there called hpc-gcc, and when I click on it it's
02:22got that bin, include, lib, libexec, all of those folders inside of it.
02:27So it's real important that it'd be named that, and it'd be there, because we're
02:31going to use that location as we set the preferences in Eclipse.
02:34Now I am going to go back over here to my Downloads folder, and I am just going
02:38to delete this usr folder.
02:40And now I am going to come back into Eclipse, and then I am going to select my
02:44Working project and right- click and select Properties.
02:48So this is setting the properties of the Working project.
02:52You see it says Properties for Working.
02:53This is not the properties for the entire Eclipse application.
02:57So under C++ Build here, C/C++ Build, you'll notice something called
03:03Environment, and here in the Environment we're going to add a few
03:07Environment variables, and this will tell Eclipse where to find the
03:10toolchain so that it will use the correct version of GCC and leave the
03:15version alone that Xcode wants.
03:17Because Xcode still depends on that, it still needs to be there for your Xcode to work.
03:22You can't delete it, you're still going to be depending on the other tools that Xcode has;
03:26you need to leave Xcode alone.
03:28And yet we've installed this other version of GCC in our home directory, and we
03:32want to use that for compiling in Eclipse.
03:35Under Configuration I am going to select All configurations, and then I am
03:40going to select Add.
03:41I am going to type CPATH and then under Value I am going to put a dollar sign $ and a left curly bracket and the
03:49word HOME, all in caps, and a right curly bracket.
03:53Instead you can select Variables, and you can come down here, and you can find
03:57HOME and click on it and press OK, and you get the same thing.
04:02That tells it that it's under my home directory whatever that's called and in my
04:05case it's that billweinman directory that we saw.
04:08And I am going to press slash and hpc- gcc because that's what we named the
04:14folder and then another slash and include.
04:17Now if you're not familiar with file name paths in UNIX or in OS X, these are
04:24forward slashes, these are not backslashes.
04:26These are just the slash key which is right next to the Shift key on your
04:30keyboard without Shift pressed or anything like that.
04:32Now I'll press OK, and I am going to do a couple more of these.
04:37The next one is called LIBRARY_PATH, and you'll notice that there is
04:41an underscore there.
04:42LIBRARY_PATH, and I am going to select Variables again grab that HOME variable,
04:47and there it is and press /hpc-gcc/lib and press OK.
04:58So we have LIBRARY_PATH set, and we have CPATH set.
05:03Now we're going to set one more, this is the Path variable, and this one has got
05:06a little bit of rigmarole to it.
05:08So here's how it goes, it's called PATH, and there's already a path variable
05:13set, although it doesn't show up there.
05:16After we set it we are going to notice that what we put here gets added to the
05:20end, we're going to need to come back in and edit it and move it to the
05:22beginning, because it needs to be at the beginning.
05:25So I am going to go here under Value, and I am going to select Variables
05:28again, and I am going to find our little HOME and double-click on that and say /hpc-gcc/bin.
05:40Now when I say OK you'll notice that we look at what path has, and it's all this
05:44other stuff, and if I press Edit over here you'll see that what I added actually
05:48went all the way to the end of the variable.
05:51So I need to select that, I am holding down the Shift key and pressing the left arrow.
05:55I press the right arrow to get to the end, and I am holding down the Shift key
05:58and pressing the left arrow, and I am coming all the way back here, and I'm
06:02taking the colon as well.
06:04You'll notice there's a colon at the end of sbin and then there's the $ curly brace HOME curly brace.
06:08So I am taking that colon as well, and I am pressing Command+X to cut, because
06:13then I am going to paste.
06:15And I press the up arrow, and that will take me to the beginning, and I am going
06:19to press a colon and then my left arrow to go before the colon, and then I am
06:23going to press Command+V to paste.
06:25And then I need to go all the way back to the beginning and take that
06:27first colon out again.
06:28So I'll select that and hit the Delete key, and now what we have is we have
06:33$ curly brace HOME curly brace/hpc-gcc/bin and then there is a colon and then the other stuff that
06:43was already in the variable starting with the /usr/sbin.
06:47It's really important that it look like this, that it has this
06:51HOME hpc-gcc/bin at the beginning and not at the end of the variable.
06:56So I am going to press OK, and we see that we have that correct right there.
07:00Now I am going to press the Apply button over here, and that applies it.
07:04Now I am going to go back over here to C/ C++ Build an then down here to Settings.
07:09So under Settings you see we have tool Settings selected at the left here and
07:12these are settings for all of our tools.
07:14And we have the C++ Linker, the GCC Assembler, and we have the C++ Compiler, and
07:20the C Complier and those are the ones that we are interested in.
07:24If I select the GCC C++ Compiler, you'll notice that it has all of these
07:29options down there.
07:30And if I come down here to Miscellaneous I am going to add an option here.
07:35I am going to put in a space at the end of this list of options, and I am going to say -std--
07:41it's an abbreviation for the word standard-- = c++11, so two 1s.
07:48So it is letters c, two + symbols and two number 1s. -std=c++11.
07:56Now you'll notice if I come back up here and click on GCC C++ Compiler you'll
08:01see that there is that option at the end so that's what I wanted to accomplish.
08:05You can't edit that here, you need to edit that under Miscellaneous.
08:08I am going to do the same thing under the C Complier.
08:11So this is GCC C Compiler, and you'll notice that all of the options are there.
08:16If I come down here under Miscellaneous, I am going to add the options for
08:20latest version of the C standard which is also C11.
08:24So this is -std=gnu11.
08:30So that's the C11 standard with the gnu extensions.
08:34So there is one more thing we need to do here. We need to go in here to the Run/Debug Settings.
08:40And that's right over here under C++ General down here Run/Debug Settings
08:45and our Launch configuration for our Working project we are going to go
08:50ahead and edit that.
08:51So I select Working, and I press Edit, and I come in here, and there is a couple
08:55of things we want to do.
08:56One, I want to come over here to Arguments, and I just want to put in some
09:01arguments because we'll use these occasionally.
09:02So under our Program arguments I am going to type the words for one two three,
09:07like that, and it's just as if you run something at the command-line, and it's
09:10got three arguments after it.
09:12So it's like you type your command, and then you type a one, and a two, and a
09:15three on the command-line, that provides it that environment.
09:19Then I am going to select the Environment tab, and we are going to add Environment variable.
09:24Because we are running a C Compiler that's not the default C Compiler
09:27that's installed in the operating system, we need to tell it where to find
09:31its libraries, because it's not going to find the right libraries in the normal place.
09:35In fact, it will find libraries in the normal place, but they'll be the wrong libraries.
09:40So we want to make sure that it finds the right libraries.
09:42So we just have to add a variable to the environment here.
09:45This is for the runtime environment.
09:47The other variables that we added before, those were for the compile time environment.
09:50These are for the runtime environment.
09:52I have Environment selected, and I am going to press New, and I am going to name
09:57this variable DYLD_LIBRARY_PATH.
10:04And if I select variables here I'll find one called env_var, because there isn't
10:09one that's called HOME.
10:11And under Argument I am going to type the word HOME all in caps.
10:15Press OK, and I get this env_var:HOME thing like that, and that's exactly what you want.
10:21So if you have that, great.
10:23If not, you can just type it here, and it will work just fine. And /hpc-gcc/lib.
10:31I am going to say OK, and there we have DYLD_LIBRARY_PATH and the value.
10:37So I am going to press the OK button and press the OK button again and at this
10:43point we should have the correct version of our Compiler installed.
10:47So I can just come up here, and I can press the Run Working button, and it will
10:51rebuild it, and there is GCC version 4.7.0, Version string 4.7.0. We now have a
11:00sufficient version of GCC.
11:01If you're doing this at some point in the future you may have a later version of GCC.
11:06As long as it's 4.7.0 or later you should be fine.
11:10We are going to do one more thing to test this.
11:12I am going to go ahead and put this in fullscreen mode so you can see this entire file.
11:16And I am going to select all of this stuff here.
11:18This only works in C++11, and I am going to uncomment it by pressing Command+/ key.
11:25And that's just a little shortcut inside of Eclipse that takes those comment
11:28markers out from the beginning. So now it should look like this.
11:31And I am going to press Command+S to save, and I am going to minimize it again
11:36by double tapping on the title there, and I am going to press Run.
11:41Now you will see it also says one two three.
11:43So what it did, I am going to maximize this again so you can see it is it came
11:48out here, and it creates a C++ vector which is like an array.
11:53And it uses this feature here, the for each version of the for loop, which is
11:57not a C construct that existed before C++11.
12:01It's also using this initializer list which is another C++11 feature.
12:05So it's using some C++11 feature, and it is working.
12:09Now one final thing I am going to do here is I am going to go ahead and I'm
12:14going to delete this file so that we are in a nice working state as we start our next exercise.
12:18And I am just going to select it and press the Delete key here on my Mac
12:21keyboard or you can just right-click and select Delete, and I am going to say OK.
12:26And because we were using a copy we still have it up here in the Chap02 folder, but
12:30it's now deleted from our Working project.
12:33So in using Eclipse in this course we have the C++ Essential Training project,
12:38and that's just holding all the exercise files.
12:41When we want to actually use an Exercise File, we select that, we copy it, we
12:45paste it into Working, and we use it down there.
12:47So now you have working Eclipse with the latest GCC installed and running on your Mac.
Collapse this transcript
Setting up Eclipse for Windows
00:00In this movie, we are going to install the Eclipse C Development Tools on a
00:04PC running Windows 7.
00:06Now, it's not necessary to install Eclipse in order to take this course.
00:11You may use whatever development environment you like.
00:13In fact, I encourage you to use your own development environment.
00:16I am using Eclipse for the examples in this course because it's convenient for this purpose.
00:21It allows me to demonstrate the examples in a way that's accessible to students
00:25on any of the three major platforms today;
00:27Windows, Mac, and Linux.
00:29That is the only reason I'm using Eclipse for this course.
00:32I normally do my development work with whatever tools are supported on the
00:36platform I'm working on, and I encourage you to do the same.
00:39Now, in order to install Eclipse, you will need three things;
00:43you need the Java Runtime Environment, you'll need the GNU GCC Compiler
00:48version 4.7 or later, and you will need Eclipse with the CDT, that's the C
00:54Development Tools, and you will need the version that's appropriate for your
00:58PC and your Java installation.
01:00So the first thing we're going to do here is we are going to go to the Java website,
01:04and we are going to check and make sure we have Java on this machine.
01:07I am going to click on Do I have Java?
01:09And verify Java version, and it says that I have the recommended latest Java
01:14version installed on this machine.
01:16If I did not have that, it would give me the opportunity to download and install that.
01:20So we have Java on this machine.
01:22The next thing we need to do is make sure we have the proper compiler.
01:26Now, there is a number of ways to download and install the GCC Complier, and
01:31I've found one that works, that has this latest version of GCC, that
01:36supports C++11 and C11.
01:39So, both the C language and the C++ language have recently had major releases
01:44and the only compiler that I am aware of at this time that supports these latest
01:49versions is the latest version of GCC.
01:51The latest version of the normal tools for installing GCC on a PC which is the
01:57MinGW environment does not have that latest version of GCC.
02:02So, there's this company here called Equation Solution which has created a
02:07version of MinGW that has the latest version of GCC.
02:12So, long story short, you come in here to this web site, you go to Programming
02:16Tools, and you go to Fortran, C, C++, and you'll see it down here, and whatever
02:22version is there, may or may not work.
02:24So, what I've done for you is I have downloaded this and put it in the exercise files.
02:30So, if you look in the exercise files, and I am going to switch to the
02:32desktop here and open the exercise files, you'll see this folder, it says WindowsSupport.
02:38Under WindowsSupport, you will see gcc-4.7.0;
02:40you have a 32-bit version and a 64-bit version.
02:44If you don't already have installed a later version of GCC that works in
02:49whatever environment it is that you're using just use this one.
02:52This one works, it's tested, and I know that it works with Eclipse and everything.
02:57So I have already copied this to my Downloads folder along with Eclipse, and
03:02let's go ahead and see where you get Eclipse.
03:04You should use the latest version of Eclipse if it's available, and so here we
03:08have the eclipse.org web site under Downloads.
03:10And if you look down here Eclipse IDE for C/C++ Developers, that's us, and
03:16because I am coming to this web site on a Windows machine, it's detected that I'm
03:20running Windows, and this will say Windows. I could select another one if I want to.
03:24But right here it's got Windows 32 Bit and Windows 64 Bit, and I just
03:29download the Windows 64 Bit version, and you will see I already have that
03:33here in my Downloads.
03:34And so that's the version right there, it's the same version that's on that web site today.
03:38When you come to the web site, they are likely be a different version, and you
03:41can download that version.
03:42So now we have all the pieces that we need, I am going to go I am
03:47going to close Firefox, and so we will start by installing this latest version
03:51of GCC from equation.com.
03:52I am going to run the installer as administrator.
03:56So I right-clicked on that, and I selected Run as administrator.
04:00You see this lovely screen here which has a license on it.
04:03This is the GNU General Public License. I just say Accept.
04:08I have to put this in a particular path where Eclipse will look for it.
04:12This path will not work.
04:13Any path that has a space in it will not work, and in fact, Eclipse just expects
04:18it to be in a very particular path, and it's not the default path.
04:21So, I am going to type here MinGW, and the M is capitalized, and the G is
04:27capitalized, and the W is capitalized.
04:29So, I am going to go ahead and press Install, and this will take a few minutes. All right!
04:34We're going to say Finish, and we usually get a little pop up window, there it
04:39is that says it might not have installed correctly.
04:42This is the Windows Program Compatibility Assistant, and you may safely ignore this.
04:45I just press the red x.
04:47So I am going to close this.
04:49This is the Start Menu stuff, and this is now properly installed.
04:54So now we've installed our GCC Complier, we are going to go we are
04:57going to install Eclipse.
04:59And to install Eclipse, it's actually a little bit simpler.
05:03Eclipse comes in the Zip file, and it's just a bunch of files that you are going
05:06to end up copying to Program Files.
05:08So I am going to right-click on this, and I am going to say Extract All, and I
05:13am just going to take the default location here.
05:15We'll end up being right there in that same directory.
05:17So I am going to click Extract, and this takes a few minutes.
05:22So now this is the directory that it's been copied into, and what I do is I just
05:28come down here in the sidebar.
05:29The idea is you want to copy this into the Program Files directory, and this
05:33is the 64-bit version, so I want it in the 64-bit Program Files which does not say x86.
05:39And I just drag this and move it right there.
05:43There it is eclipse, and there is all that stuff.
05:46So I want to right-click and pin it to the Start Menu.
05:51So then it shows up right there in the Start menu.
05:54Looks like I may have previously pinned it down there, but you can pin it there
05:58as well if you like.
05:59So now we close this, and at this point, because this is Windows, it's probably
06:03a really good idea to log out, and log back in or even reboot your machine just
06:07to make sure that all of your paths are set up properly.
06:10So now we've installed our compiler, we've installed Eclipse, we have Java,
06:15and so we can go we can run Eclipse, and so I am going click on
06:20Eclipse in my Start menu.
06:21You notice I get this little security warning the first time.
06:24I am going to uncheck this Always ask, and I am going to say Run.
06:28So, it's asking me to select a workspace, and I am just going to leave the
06:32default, and I am going to say OK, and there is Eclipse.
06:35So, I am just going to press the Maximize button here, and I'm going to go to
06:40the Workbench which is this button over here on the right, and there is Eclipse,
06:44and it's already set up for our C++ perspective.
06:48If yours is not set up for your C++ perspective, you can write this one here,
06:52Open Perspective, and select Other, and then find your C++ perspective, and
06:58open that, and that will give you the C++ perspective which is the layout of the screen here.
07:04So, before we do anything else, we want to go into Preferences.
07:07So, we are going to click on the Window menu and select Preferences, and under
07:11General, I am going to open the little disclosure triangle here next to General.
07:15I am going to click on Workspace, and you notice down here at the bottom the
07:18Text file encoding, this is very important.
07:20Our files are cross-platform, and they are in UTF-8, and that is not the
07:26default for Windows.
07:27They will probably work just fine, at least most of the time, but UTF-8 is now
07:33the standard, and so if you are working with source files, especially if you are
07:37working with source files that you are going to share with anybody else that
07:41might be working on a different operating system, you are going to want to make
07:45sure that you are using UTF-8.
07:46So I am going to select Other here, and the dropdown box, and I am going to select UTF-8.
07:51And under New text file line delimiter, I want to select Other, and I want to
07:55select Unix because Windows line delimiters are different and these files are
07:59cross-platform, and Unix is the standard.
08:02Now, next thing I want to do is I want to come here under C and C++, and I am
08:06going to open that disclosure triangle. I am going to go to New CDT Project Wizard.
08:13You see under Executable, I am going to make sure that, that's opened up, and I
08:17am going to select Empty Project.
08:19And yours will probably say Cross GCC, that's not correct.
08:21You want to make sure this says MinGW GCC, and then you want to click on this
08:26Make toolchain preferred and so you will get a little arrow there next to your MinGW GCC.
08:32So, we will close the C/C++, and we are going to come back up under General, and
08:36we are going to go to Editors, and Text Editors, and we're going to check every
08:43box in this except for Insert spaces for tabs and Show print margin, and so I am
08:49going to select Show line numbers, Show whitespace characters and make sure all
08:52of these are checked, and leave the Displayed tab width to 4 and leave
08:56everything else like it is.
08:58So now we are going to close the General Tab, and we are going to open up the
09:01C and C++ Tab again, and we are going to go to editor, and we are going to select Folding.
09:07Here, you want to select everything at the top, and all these, in these little
09:11box that says Initially fold these regions, these all get unselected.
09:14So, I am going to uncheck all of those, and I am going to check all of these,
09:19and that enables code folding, but it doesn't initially fold anything.
09:23So, that's all the preferences for now.
09:25We will be setting some more preferences in a few minutes.
09:28So I am just going to select OK down here, and I am going to come up here and
09:32create a new project.
09:34So here is the little new project, and you see little arrow there, the dropdown
09:38arrow, and I am just going to select the one that says Project, and I am going
09:41to select a General project.
09:44So I will open up General, and I select Project, and I say Next.
09:48Our project name is going to be CppEssentialTraining with no spaces in it, and
09:55we'll go ahead and use the default location, and select Finish.
09:57Now, we are going to create a new folder within this project.
10:01So I am going to right-click on the project, and I am going to say New > Folder,
10:07and under Folder name, there is an Advanced button.
10:10I am going to select that button, and then I am going to select Link to
10:14alternate location, and press the Browse button.
10:16So what this will do is it will allow us to import our exercise files without
10:20actually needing to make a copy of the entire directory.
10:23So, I am going to browse there, and on the Desktop, you see exercise files.
10:29I am just going to select the exercise files, and I say OK, and make sure this
10:34link is selected, and then I press Finish. So now we have our exercise files.
10:39You notice the little Link icon there, and there they all are. All right!
10:43So I am just going to close all that up and create one more project here,
10:47and this is actually going to be a C++ project, and so I am going to call it Working.
10:53You will notice down here under Toolchains, the MinGW should be selected.
10:57If MinGW is not selected, then you missed something in your configuration, in
11:02your preferences, and you want to go back and do that again.
11:05So, this creates our Working project, and I select Finish there.
11:09This selects our Working project, and this is where we are actually going to be
11:12doing all of the compiling.
11:14We are going to be copying files from our exercise files, and putting them in
11:18our Working project and using them there. So let's go ahead and do that.
11:22We are going to come into our exercise files, we are going to go into Chapter
11:252, and I am going to select version-test. cpp, and I am going to press Ctrl+C on
11:30my keyboard to copy that, and then I am going to select the Working project
11:33down here and press Ctrl+V to paste it, and that will make a working copy of
11:38the version-test.cpp.
11:39See we have one down here, and it still exists up there.
11:43When I double-click on this, it opens it up in the editor, and it should
11:47look just like that.
11:48So this is just a little C++ file for testing the version of GCC that we
11:53have installed here.
11:54So, the first time through when we just created this Working project, we are not
11:58going to be able to just press the green Build and Run because this Working
12:02project hasn't been used yet.
12:03So, the first thing we actually have to do is we need to come in to the Project
12:08Menu and select Build All.
12:09Once that's done, then we can select this Build and Run button, and you see it
12:15compiled our source file, and it gave us a result down here.
12:19So, the result down here, it's under the Console Tab, and it already
12:22selected that tab for you.
12:24At this point, you should be seeing a version number that says 4.7.0 or later if
12:29you have installed a later version of GCC.
12:31Now, we're not quite done but we are getting there.
12:34At this point, we need to finish setting up our Working project environment.
12:38So you can right-click on Working and my screen is so small here for the
12:42purposes of teaching.
12:44I have to scroll down, and you will find Properties all the way down at the bottom.
12:48So I am going to select Properties there, and I am going to come down here into
12:52C/C++ Build, and I am going to open that up, and I am going to select Settings,
12:57and you should see a screen that looks like this.
12:59Again, the screen here is a little bit small, so this scrolls.
13:02So this is not going to look exactly like it looks on yours.
13:06And when I select these things, it goes and scrolls for me, so it look a little
13:10bit weird, but the first thing we do is come in here under C++ Compiler, and select Miscellaneous.
13:16So if I just select C++ Complier, you will see, it scrolled there for me.
13:21It's got my Command: g++ and all of my options.
13:24And so we are going to be changing those options but you can't change them here,
13:28and so you need to select Miscellaneous, and under Miscellaneous, under Other
13:32flags, put the cursor in there, and you're going to type exactly this, -std as
13:38in standard, std=c++11.
13:43Then you are going to come down here under GCC C Complier, that was for the C++
13:47Complier, under the C Complier all the way down at Miscellaneous, and you are
13:52going to do it again, same thing,
13:54come into the Other flags, and go in there, and you're going to type -std=, and
13:58it's a little bit different, gnu11.
14:02So that sets up the C++ Complier so that it will compile with the latest
14:06standard of C++ which is C++11, and it sets up the C Complier so that it will
14:12compile with the latest C standard which is C11 with a few small GNU Extensions.
14:17Now, we're almost done.
14:19We are going to go into the Run/Debug Settings which is right here, and select
14:23our Working project, that says Working. exe, and I am going to click on Edit.
14:29And then, under the second tab here that says Arguments, I am going to type in some Arguments.
14:33I am going to type in one two three, and I am typing those words out;
14:38one two three, and they have spaces between them.
14:41These are like Command Line Arguments, and we use these occasionally in the
14:45course to test and work with the Command Line Arguments that you might use on a
14:49console-based application. So that's all there is to it.
14:53I am going to press OK there.
14:55I am going to press OK down here, and now we should be all set up.
14:58I am going to select the Build and Run button, and you see it complies
15:03everything now with the correct standard.
15:05Now, I can uncomment this code here because this is C++ feature test.
15:12These are some features that are only available in C++11, they are not available
15:15in older versions of C++.
15:18So, the GNU Compiler wouldn't have worked with these if I hadn't set those
15:22flags to set up C++11.
15:25So I am going to uncomment them, and I can do that by just pressing the Ctrl and
15:30the Slash key on my keyboard, and that's a Eclipse shortcut for uncommenting
15:35that, and then Ctrl+S to save, and you see my little star went away up there. So now it's saved.
15:40And I can press the Compile and Run button again, and it compiles, and it runs
15:45without error, and you can see we have our output, and it says one two three,
15:48and I have initialized this vector with an initializer list which is a C++11
15:53feature, and I am using the Range- based for loop which is a C++11 feature.
15:58So we can see that that's working with C++11. Now, I am going to delete our Working file.
16:05I select it, and I press the Delete key on my keyboard, and I select OK here.
16:10And I am going to come up here to my Project, and I am going to say Clean, and I
16:15am going to make sure that Clean all projects is selected, and press OK, and
16:19there it's cleaned the project.
16:20Now, I am just going to copy and paste the c99.c and select our Working project,
16:26and press Ctrl+V to paste it.
16:29I am going to open that up in the editor, and this will check to make sure that
16:33we have the latest version of the C Complier selected in our command line
16:37switches, and I am going to select the Compile and Run button, and you see
16:42that, that works fine.
16:44It's also testing that we have our Command Line Arguments.
16:46Here is zero, one, two, three, those are our Command Line Arguments so
16:49that's installed right.
16:51This syntax here, both declaring and initializing the integer inside the for
16:55loop, that's a c99 feature, so the compiler does not work with that unless we
16:59have that compiler switch set. So, all of this is working exactly as it should.
17:04So, I am just going to select this file, and I am going to delete it, and I am
17:09going to run Project and Clean, and Clean all projects is set, and that's okay.
17:14And that gets us all set up for the first lesson in the course.
17:17So, each time you use the Working project, when you're all done, you need to
17:22delete whatever working files you put in there, and you need to run Project > Clean.
17:27The short version and the reason for this is that if you leave those files
17:30there, it will create conflicts when you try to use the project for the
17:34next example files.
17:36The way Eclipse is set up, it will compile all the files in a project.
17:39And as you will learn later in the course, you can only have one instance of
17:43the entry point for a project which is called main, and since each of our
17:47example files has its own main, you can only have one of them in the folder at
17:51a time, and you need to run Setup Clean each time to reset the Working project
17:55for the next source file.
17:56So, now we have a working Eclipse with the latest GCC installed and running on a PC, running Windows 7.
Collapse this transcript
Working with Eclipse on Windows
00:00If you are running Eclipse on Windows you need to be aware of one important and
00:04quirky behavior, every time you change the main file in a project, and we will
00:08be doing that for just about every movie in this course.
00:10Eclipse could get confused and not realized that its file system is out of sync.
00:15Let's take a quick look at this behavior.
00:17I am going to go ahead and make a working copy of version-test.cpp, so I select
00:21it here, and I press Ctrl+C, and then I select Working, and I press Ctrl+V. And
00:27that copies and pastes it into the Working project.
00:30Now I am going to double-click on it, and that opens it up, I am just going to
00:34press this Run button up here, and that compiles it, and it runs it, and it runs just fine.
00:40Now I am going to close this, and I am going to delete it from the Working file system.
00:45I am going to come up here and grab a different one, let's grab hello.cpp.
00:52I will press Ctrl+C to Copy it and select Working and Ctrl+V to Paste it and open it up.
00:59Now I am just going to press this Run button again which ought to compile it and run it, right?
01:04You notice we have an error, say No, and I will hover over this, it says first
01:09defined here, that's not very helpful. Look down here and ah!
01:13Multiple definition of main.
01:16So what that means is that there's another object file in our project that
01:21already has main defined.
01:23If I look over here in Debug, I am going to open this Disclosure triangle here,
01:27you see we have two object files;
01:29hello.0 and version-test.o. Well, that's not right, and that won't work.
01:33So the solution here is to run something called Clean.
01:37We'll come up here to the Project menu, and I am going to select Clean, I am
01:41going to select Clean all projects and say OK.
01:44And you notice that that deletes the whole Debug directory, it also deletes
01:48the Binaries directory.
01:49And now when I press the Run button, it compiles, and it runs and everything is
01:56fine, and we look in the Debug folder, we see we have Working.exe, and we have
02:00hello.o, and that's exactly what we are supposed to have.
02:03So the problem here is that every time we delete a C file or a CPP file and
02:08copy and paste a different one into the Working folder we have this potential conflict.
02:13The easiest solution is to do a Clean whenever you delete a file in the Working Project.
02:19This seems to ensure that you won't see this problem.
02:21So I am going to go ahead and do that right now. I am going to take this hello.cpp.
02:26I am going to delete it, I am pressing the Delete key on my keyboard and OK.
02:30And now it's deleted, and now I am just going to come right up here to Project
02:33and select Clean, unfortunately there's no button for this on the Toolbar.
02:37Clean all projects is selected, I am going to press OK, and now it's clean, and
02:41now we are ready to begin the next movie.
02:43This problem doesn't seem to happen in Eclipse on other OSs, it's no use
02:47speculating how or why this is a problem on Windows, it's just something that
02:51you need to be aware of, so you know what's going on and what to do about it when you see this behavior.
Collapse this transcript
Setting up Eclipse in Ubuntu Linux
00:00In this movie, we're going to install the Eclipse C Development Tools on a PC
00:05running Ubuntu 12.04 Precise Pangolin.
00:09Note that it's not necessary to install Eclipse in order to take this course.
00:14You may use whatever development environment you like.
00:16In fact, I encourage you to use your own development environment.
00:20I'm using Eclipse for the examples in this course because it's convenient for this purpose.
00:25It allows me to demonstrate the examples in a way that is accessible to students
00:29on any of the three major platforms today;
00:31Windows, Mac, and Linux.
00:34That is the only reason I'm using Eclipse for this course.
00:37I normally do my development work with whatever tools are supported on the
00:40platform I'm working on, and I encourage you to do the same.
00:44So the first thing we're going to do is we're going to start up the Ubuntu
00:47Software Center which is this little icon here.
00:49We're going to use this to check our version of GCC.
00:53GCC is the new Compiler Collection.
00:56That's the C Compiler that we're using for this course.
01:00So I simply type in gcc, and I see that it's installed, and I click on
01:04More Info, and I'm going to scroll down to the bottom here where I can see the version.
01:09I see that the version is 4.6.3. For this course, you need at least GCC 4.7.0,
01:16and the reason for that is that we're teaching the C++11 standard and the C11
01:21standard which were both just ratified last year and are not fully supported in
01:26GCC 4.6.3. Some of the later GCC 4.6s had some of the features, but GCC 4.7 is
01:34the minimum that we're using for this course.
01:37So, for that reason, I'm going to need to update the GCC on this computer.
01:42So I'm going to type in up here gcc-4.7. Searching in the Ubuntu Software Center
01:48is a little bit weird, at least as of this version.
01:51So, there's no simple way for it to tell me what's the latest version available,
01:55I've actually installed some more archives here, you probably have too;
02:00you may need to have another archive besides a default Ubuntu archive in order
02:04to find the latest GCC.
02:06So, this is the GCC 4.7. I'm going to go ahead and install this.
02:10It will install it on this computer in addition to the GCC 4.6 that's already there.
02:14We're going to have to update some symbolic links in order to get it to work.
02:17We'll get there in a minute.
02:20And now that GCC 4.7 is installed, we're going to do the same thing for G++.
02:24G++ is the C++ Compiler that's part of the GNU C Compiler Collection, but it
02:30doesn't come installed by default.
02:32So, here we can see that it's not installed on this computer.
02:35If I look inside the one that it found here, well notice, at least in this case
02:40because I noticed this before, it's 4.7, but it's not the same 4.7 as the GCC
02:46that I installed before.
02:49If I come back here, and I type g++-4.7, you'll see that I get a different version.
02:55I will click on More Info down here.
02:58See that this one says -3. So, this is the one that I want to install.
03:03So again, when you're installing stuff like this on a Linux distribution, and
03:07this is true with any Linux distribution because of the open source nature of
03:10it, you need to be careful about the versions and make sure that they match.
03:14So I'm going to click on Install here, and this will install the GNU C++ Compiler. Okay.
03:20Now that, that's done, I need to go and update my symbolic links.
03:23So I'm going to bring up the Terminal, and I'm just assuming that if you're
03:27using a distribution of Linux that you're somewhat familiar with the Terminal,
03:32so I may not explain all of the steps as I go along. I'll do my best.
03:36So first thing I'm going to do is I'm going to type sudo which gives me
03:39superuser root privileges, and I'm going to type su - which will actually give
03:45me a shell as root, and it should ask for my password here.
03:49And now, I am the most powerful person on this computer.
03:52It's possible to do a lot of damage.
03:55You need to be very careful how you type and what you type because there
03:58are some commands that you could type by mistake that could potentially
04:02wipe out your system.
04:03I don't mean to scare you, but you need to be careful when you're typing as root.
04:08So I'm going to change directories to user bin;
04:10type cd /usr/bin, and I'm going to look and see what we have here in terms of
04:19these pieces of the GCC system.
04:21So, I'm going to type ls -l, and I'm going to type gcc* and g++* and these all
04:30have spaces between them, and cpp*.
04:34These are the three commands that we need to see how they're linked up.
04:38ls -l will give me a listing of the directory with a lot of access information
04:44that I actually need in this case.
04:46We can see we have symbolic links for cpp and gcc and those are the ones that
04:52are highlighted in the light blue there.
04:54You see that we also have g++-4.7, and there's no symbolic link for G++.
04:59So, I'm going to start by creating the symbolic link for G++, and I'm going to
05:06type ln -s for symbolic, g ++-4.7, and a space, and g++.
05:13And what this command does is it will create a symbolic link using g++-4.7 as
05:19the source and g++ as the target.
05:22And then when I say ln -s g++, I meant to say ls -l g++, there we see that
05:33it has the link now.
05:35There is a g++ that is linked to the file that we want.
05:38Now, I need to do the same thing for the ones that are already linked, which
05:41means that I need to delete them first.
05:43I'm going to type rm which is the UNIX command for delete--
05:47it's short for remove--and both cpp and gcc, and that will remove those two
05:53files that you see highlighted there, they're the symbolic links to the old 4.6
05:57versions, and now I'm going to create new links,
06:00ln -s gcc-4.7, to gcc, and ln -s cpp, which is the C preprocessor -4.7 to cpp.
06:15Now, when I type that original command again, ls -l gcc* g++* cpp*, you see that
06:25we have exactly what we need.
06:27Those symbolic links are now updated, plus we have one for g++ and they're all
06:31pointing to the 4.7 versions.
06:34So now that, that's done, and it's correct, I'm going to press Ctrl+D for David,
06:38and that will get me out of my root shell, and I'll press Ctrl+D again, and that
06:43will close the Terminal. Now, we're going to install the JRE.
06:47JRE stands for Java Runtime Environment, and this is necessary for Eclipse.
06:52So I'm going to type in here default-jre.
06:56Again, searching for things in Ubuntu Software Center is a little bit of an
07:00adventure, and so I'm just typing the exact names because I know what they are,
07:04and that may or may not actually work for you if you're using a different
07:08version of Ubuntu than I am. So, there it is.
07:10The standard Java or Java-compatible runtime, and I'm going to click on the
07:14Install button, and that will install Java, type in my password, and now the
07:21Java Runtime is being installed.
07:22So now that the JRE is installed, we can finally install Eclipse, and we do that
07:28by searching for Eclipse, eclipse-cdt.
07:36CDT stands for the C Development Tools, and that will install both the Eclipse
07:42environment and the Development Tools.
07:45So we'll click on that, and we'll click on Install.
07:50So now we have Eclipse installed which requires the Java Runtime Environment, so
07:54we have that installed, and we have the correct version of the GNU Compiler
07:59Collection, GCC installed, and so now we're ready to start up Eclipse.
08:04So, I'm going to close out the Ubuntu Software Center, and I'm going to click on
08:09this Dashboard and type in Eclipse just the first couple of letters, you'll find
08:14it there, and I'm going to click on that to start up Eclipse.
08:18And just as Eclipse starts running, you'll see an icon come up here in the
08:22Toolbar on the left.
08:23So I'm going to right-click on Eclipse here in the Toolbar, and I'm going to say
08:27Lock to Launcher, and that way, it will always be there in the Launch Bar.
08:32Select a workspace, accept the default, and press OK and also check this box
08:37that says Use this as the default and do not ask again, and it loads up all of its stuff.
08:43I've had this experience before the first time starting up Eclipse on Ubuntu,
08:48and it doesn't actually show me that it's got C++.
08:51If I come in here to the Preferences, I see that I have the C++ there.
08:56So, if it didn't show up in here, my experience is by closing Eclipse and
09:00starting it up again, it finds it. But there it is.
09:04So the first thing I'm going to do is I'm going to select the Workbench over here.
09:08And if you know anything about Eclipse, you'll see we have a perspective started
09:12up that says Resource. What we want is the C and C++ perspective.
09:16So I'm going to go into Window, I'm going to say Open Perspective, and there I
09:20see the C/C++ in the menu.
09:23Again, sometimes it doesn't show up, in which case you can select Other and
09:27select C/C++ that way.
09:29And now, it's changed the perspective when we have the C/C++ perspective.
09:33Now, I'm going to come in here to the Preferences under Window, and under
09:38General, I'm going to open that up and come down to Workspace.
09:43And down here under Text file encoding, you see it says Default (UTF-8), and
09:47that's exactly what we want.
09:48If it does not say UTF-8 on yours, you can select Other, and select UTF-8
09:53from this dropdown.
09:54But we're going to leave the default there because that's correct on this one.
09:58Also, under General, I'm going to open up Editors, and I'm going to select Text Editors.
10:03We're going to check a few boxes in here.
10:05I'm going to leave Insert spaces for tabs unchecked, I'm going to leave Show
10:09print margin unchecked, I'm going to check the Highlight current line, actually
10:13everything else in here except those two;
10:16Spaces for tabs and Print margin, everything else in here gets checked.
10:20Now, we're going to close General, and open up C and C++, and I'm going to
10:26select on the New CDT Project Wizard.
10:28And under Preferred Toolchains, Empty Project, I'm going to select Linux GCC and
10:35press this button that says Make toolchain preferred.
10:38You'll notice that it puts a little arrow next to that one, and that's what you want.
10:44And then here under editor, I'm going to open the disclosure triangle and press Folding.
10:49You want all of these check boxes checked that enable the various types of
10:53folding, and you want all of these unchecked in the initially fold region.
10:59So that's the preferences for now.
11:01We're going to set some other preferences in our project after we create a project.
11:05So now we're going to create a couple of projects.
11:07We're going to actually create two projects.
11:09One of them is going to hold all of the exercise files, and the other one is
11:13actually going to be for compiling.
11:15And the reason for that is you can really only compile one of these files at a
11:19time, and Eclipse likes to compile all the files in a project.
11:22So I'm going to select this little arrow next to the New button, and I'm
11:26going to say Project...
11:28just the normal project, not any of these other ones;
11:31just Project with the dots, and under General just the one that says Project,
11:37press the Next button, and give the project a name.
11:39This is going to be CppEssentialTraining, and you notice I don't put any spaces in that.
11:45My programming projects, I really like to have folder names that don't
11:49have spaces in them.
11:50That's getting harder and harder to do as desktops get more sophisticated.
11:53But there's still a lot of tools out there that will complain about spaces in
11:57file names and folder names.
11:58So I'll press Finish, and that gives us this empty project, and it's got nothing
12:03in it, and so we're going to put something in it.
12:05I'm going to right-click on this and under New > Folder, come down here and
12:09select the Advanced button, and this allows to link to an alternate location.
12:13This way, we can load up the exercise files, and not have it make a copy of
12:18them into our workspace. We don't really need that.
12:20We're not going to actually be editing these files in place anyway.
12:23So I'm linking to this alternate location, and select Browse, and under Desktop,
12:29you see ExerciseFiles, and select OK.
12:33So I've got my exercise files on the Desktop, you might have yours some place else.
12:38When you're browsing, you can find yours.
12:40Now I'll select Finish, and there is our exercise files inside that project.
12:44So, when I click on the disclosure triangle, you see we've got all of our
12:48folders, and there's all of our exercise files. So I'm going to leave that alone for now.
12:53I'm going to create a new project and so I just right-click on this area
12:57where you can select the arrow next to the New Project up here, and select C++ Project.
13:02And this one is going to be called Working, and this is where we're actually
13:05going to do our work.
13:07You'll notice that the default empty project, it's got the Linux GCC Toolchain. That's important.
13:12If you don't see that arrow there, then you need to go back and do your
13:16preferences configuration again because you missed something.
13:19Select Finish, and there's our Working project, and so I'm going to open that one up.
13:25You see it's just got the Includes in it.
13:26Now, it will have more things in it once we do a build inside there.
13:30So I'm going to open the disclosure triangle on our C++ Essential Training
13:34and on our ExerciseFiles and on Chap02, and I'm going to come down here and
13:38select version-test.cpp.
13:40Now, I'm pressing Ctrl+C on my keyboard to copy that file, and I'll just close
13:46all of that and select Working and press Ctrl+V to paste it, and now I have a
13:51copy of that file inside the Working folder. Double-click on it, and that will bring it up.
13:58Now, there's another little quirk you may run into with Eclipse here.
14:01The first time it runs and the first time it runs a project, sometimes it will
14:05show some errors in the file.
14:06You can ignore those and just let it sit there for a few minutes.
14:10They'll actually go away as it finds all of its header files, and it builds all
14:13of its indexes inside.
14:15So now, I'm going to go I'm going to press Build, and it's this
14:19little Hammer icon up here, and that will build the project.
14:23And then I'm going to select Run up here, the larger of the two green buttons,
14:27and that will run, compiles it if it needs to, and it runs this, and you see
14:31that we have our results down there.
14:33It says GCC version: 4.7.0 and Version string:
14:374.7.0. So this tells us that we have the right version of GCC that it's
14:42installed that it's working.
14:44Our Toolchain is doing everything that it needs to do.
14:47There's one more bit of configuration that we need to do because the way that
14:51this is installed by default, it's not supporting C++11.
14:56So if I select this part that's commented out and press Ctrl and the Slash
15:00key on my keyboard, it will uncomment that, and that's a little Eclipse shortcut there.
15:04Well, I press Ctrl+S to save, and then I press this Run Working button again.
15:10And you notice that it has errors, and I'll say No, we're not going to run it anyway.
15:16These lines here are complaining about features that aren't in C++98 which is
15:20the default mode of the GCC 4.7 Compiler series.
15:25So if you're not seeing those errors, that means that you've got a later version
15:28of GCC that's defaulting to C ++11, and that's wonderful.
15:32We're going to go ahead and do a little more configuring inside the project.
15:35I want you to follow along, and you won't need to set the standard strings, but
15:39you'll need to follow along to do a little bit of other configuring anyway.
15:43So I'm going to right-click on the Working project, and I'm going to scroll all
15:47the way down to the bottom here under Properties, and I'm going to open up the
15:51C++ Build disclosure triangle, and I'm going to click on Settings.
15:55Here's where we set the versions of the Compiler.
15:57For the C++ Compiler, click on Miscellaneous there, and then, here under Other
16:02flags, I'm going to put in here -std, which means standard, =c++11.
16:11And again, if your Compiler is already doing that, then you might not need this
16:15string or it might already be there.
16:17Then under the C Compiler, I'm going to do the same thing.
16:21I'm going to come down here under Miscellaneous, I'm going to say -std=gnu11,
16:26and that's the C11 standard with a couple of GNU extensions. All right!
16:31So once those are done, I'm going to scroll down here, and I'm going to click
16:35on this Apply button.
16:36And then there's one more bit of configuring we want to do here under
16:39Run/Debug Settings. I'm going to select Working;
16:42that's our Working project, and I'm going to press Edit, and then I'm going to
16:46select Arguments here.
16:47Occasionally, we're going to want to run a program as if it has some
16:51Command Line argument. So I'm just going to type those in here;
16:54one two three and press OK and press OK, and now we're all ready.
17:01Now, when I run this again, you'll notice, it will recompile it, and
17:06everything will work.
17:07So, click Run, and now it's working. It's showing the one two three.
17:12That's actually this vector string 1.3 because I'm testing the C++11 feature.
17:18Here's the whole file, by the way.
17:21This C++11 feature that has initializer lists, and also the range-based for loop.
17:26These don't work in earlier versions of C++, they're incredibly useful, and we
17:31are going to be using them in this course.
17:33So now I'm going to go I'm going to delete version-test.cpp from
17:38the Working project.
17:41The short version of the reason for this is if you leave it here, it will create
17:44conflicts when you try to use this project with the example files.
17:47A little more explanation, the way Eclipse is set up, it will compile all
17:51the files in a project.
17:52And as you'll learn later in the course, you can really only have one instance
17:56of a main function, the entry point to any C++ project in a given compile set.
18:03So since each of our example files has its own main, you can only have one of
18:06them in this folder at a time.
18:08So at the end of every one of these lessons, we're going to be deleting whatever
18:12is in Working so that we have a fresh working to start with.
18:16So, I'm going to press the Delete key on my keyboard, and I'm going to say OK,
18:20and that deletes it from there, but of course, it still exists in the
18:24ExerciseFiles because we were working on a copy.
18:27So now you have a working Eclipse with the latest GCC installed, and running on a PC running Ubuntu.
Collapse this transcript
Understanding the development cycle with "Hello, World"
00:00Before we can really dive into the examples we need to learn how to work our tools.
00:04For most of you, the Eclipse environment will be new, and it will not ultimately
00:08be the tool you'll use to develop in C and C++.
00:11Even for those of you who are familiar with Eclipse, and even those of you who
00:15are going to be using it to develop in C and C++, our development cycle for
00:19these exercises will probably be different anyway.
00:22So let's take a few minutes now, learn how this works for the purpose of
00:26following along with the exercises in this course, and the time spent now will
00:30serve you well later on.
00:31So let's start by making a working copy of a file.
00:34We're going to select hello.c. That's the traditional way to do this.
00:38We use a Hello World example.
00:39It's very simple, we know there's not much that can go wrong with it, and we can
00:43really focus on the development environment, and I'm going to copy and paste.
00:48You can right-click or Ctrl-click on a Mac, and you can select the copy and
00:52paste here from the Context menu or what I am going to do is I am going to get
00:56used to using my keyboard.
00:58I am on a Mac here, so I am going to press Command+C, you'd press Ctrl+C if
01:03you're on a PC, and that will copy this, and it puts in the copy buffer, and
01:07then you select the Working folder down here;
01:09it's a seperate project actually, the Working project, and you press Ctrl+V on a
01:14PC, or I am going to press Command+V on this Mac to paste it.
01:18It's good to get into the habit of doing it that way.
01:21If you want to drag it and hold a special key, you can do that.
01:24You just need to be careful that you're not making a link back to the original
01:28file or moving the original file. It's just a whole easier to copy and paste.
01:32So I am going to double-click on hello.c, and there it is very simple comment at the top, #include <stdio.h>.
01:38We'll learn all about these different parts of the C program later on.
01:42What we have here is just a really simple example of a very minimal C program
01:46that we can use for this purpose. So at this point, there is different options,
01:50we can do build, we can do run.
01:52For most purposes, pressing the Run key here would work fine, and yet on some
01:57platforms, and if you're running on a PC, make sure you take a look at the movie
02:01Working With Eclipse on Windows to understand the problems that sometimes
02:05happens on Windows computers. That may not actually work.
02:08You might need to do a clean first. So we're going to start with doing a clean.
02:12We're going to come up here to the Project menu.
02:15Unfortunately, there's no shortcut key, there's no icon on the Toolbar for this,
02:18you just have to go up to the Project menu, and select Clean.
02:21What this does is it cleans all the files that may have been lingering from
02:25anything that we ran before.
02:27So I am going to select Clean all projects, and press OK, and that makes sure
02:31that our project down here is in a clean state and ready to compile.
02:35Once that's happened if I press this Run button, it's the big green one, it will
02:40actually compile and run this project without a problem.
02:44The other option is to press Build first, and Build will always build the entire
02:49project and then Run will run it. And there we have it running again.
02:56It's just good to play around with this, try some different combinations of it,
02:59erase the hello.c, copy it back, maybe try some of the other files from that
03:03chapter 2 folder and run them, and get a good idea for the environment here and
03:07what can go wrong and what works.
03:09Taking the time to do that at this point is always a good idea.
03:13Let's take a moment here and also try the CPP version, the hello.cpp.
03:18So I am going to delete hello.c, because remember you cannot have two different
03:22source files with main in them in the same project.
03:25So I am just going to press Delete here, select hello.c, and Delete, and press
03:29OK, and that deletes it.
03:31I am also going to come back up here and press Clean.
03:34Try and get into the habit of doing this every time you delete a file, Clean
03:40all projects, and then we're going to come back and select hello.cpp, this is
03:44the C++ version of it, and Command+C copy or Ctrl+C on a PC, and Command+V
03:51paste or a Ctrl+V on a PC. I am going to I double-click on it.
03:55That brings it up here. You can see it's slightly different.
03:58It's pretty much the same program, but with some C++ idioms in it, and it's in the C++ file.
04:03I am just going to press that Run, because we already did a clean when we
04:07deleted the other file.
04:08So Run should work fine, and that compiles it, and it runs it.
04:12So you will notice in the Debug folder here, we've got a couple of files in there.
04:17There is the hello.o. That's the object file.
04:20And in Binaries, we have Working, that's the executable file.
04:26And look around in those directories and see what you find, get familiar
04:29with this environment.
04:32It's also useful to understand what happens when we introduce some errors into our code.
04:36If I misspell cout just put an X there, and save it.
04:40I am pressing Command+S on my keyboard, Ctrl+S if you're on a PC, and try and
04:45compile, and run it.
04:46You see that we get errors, and we have an error up here.
04:49If I hover over it, it says xcout was not declared in this scope, symbol xcout
04:54could not be resolved.
04:55Get an idea of what some of these error messages look like.
04:59Go ahead and delete that and save it and run again, and now it works fine.
05:04Let's get rid of the semicolon and see what happens when we get rid of the semicolon.
05:09And I'll Save and sometimes when you press that Run, it goes and does
05:14whole build instead.
05:17This is just something that Eclipse does. Press OK.
05:20I can always say Run in the Background if I want to.
05:23So it's good to understand that, that's something you'll see now and then.
05:26If I hover over this area, you see it says expected ; before return, and
05:32if I hover over this question mark, it says missing ; .
05:35You will notice that the Compiler message, if we look down here at the compiler
05:39message, it doesn't have the missing ; message. That's actually from Eclipse's syntax checker.
05:45So that's done by Eclipse and not by the compiler.
05:48That's why it's this yellow question mark icon instead of one of the red icons
05:52that you get from the Compiler errors.
05:54So I will go ahead and I'll put that semicolon back, and I will save, and I will build.
05:59I am going to say Run in Background, and there, it builds the file and runs it.
06:05So play around a little bit, make some mistakes. This is the time to get to know the tools.
06:10Let's just go ahead and delete hello.cpp, and I am going to run Clean.
06:20You'll want to do this at the end of every one of these movies so that you're
06:24always in this clean state at the beginning as you start the next lesson.
06:29This should give you a good idea of how you'll be using the Eclipse environment
06:32to run the examples in this course, because every environment is different and
06:36really every project is different.
06:38You'll want to go carefully through this process at the beginning of every
06:41project that you do so that you can focus on the problem at hand later on rather
06:46than worrying about your development environment.
Collapse this transcript
Using stdout and stderr
00:00For the purposes of this course, we will be working with console-based applications.
00:05These are small programs that communicate with the user by sending plain text to a console.
00:11C and C++ uses standard library that include support for three standard streams of text.
00:17In this movie, we will be discussing the standard out and standard error streams.
00:21Standard in will be discussed in next movie.
00:24Let's start by making a working copy of working.c. So I am going to copy that and
00:31paste it down into our Working project and double-click on it to open it up.
00:38So you can see this is very simple, it's just like the Hello, World!
00:42And when I compile it and run it, and you notice I ran Clean at the end of the
00:47last time I used this.
00:49So I am just going to click on the Run Working button there, and when I compile
00:53and run it, it displays Hello, World! on the console.
00:56This window down here is the console.
00:58You see I have the tab selected, this is console, and that's where the
01:02messages are displayed that are sent to the console from the standard output
01:06stream in the C library.
01:09So the function, printf is a very common way to sent things to the console.
01:13Printf is actually very powerful, it has a lot of different capabilities.
01:17But this is the simplest form, and this is what it's very commonly used for.
01:21There is another function called fprintf with a f like Frank at the beginning of
01:26it that is also commonly used.
01:30And instead of just sending things to the output stream, it will send things to
01:33whatever streams you tell it.
01:35So I can specify the standard output stream by typing an stdout and a comma,
01:41and that gives the standard output stream as the first argument to the function fprintf.
01:47So if I save this, I will press Command+S on this Mac, Ctrl+S on a PC
01:52and compile and run. You see the effect is exactly the same.
01:57Now I want to make a copy of this line and paste it on the next line, and I am
02:02going to change standard out to standard error, err and save that and run it.
02:09Now you will notice we have two lines.
02:12The first line is in red, and that's because it's the standard error stream and
02:18the second line is in black which is standard output stream.
02:21And so this is an eclipse thing.
02:23Things are sent to the standard error stream come out in red on the console and eclipse.
02:29In other environments, they work in different ways and things would go to the
02:33standard out stream or displayed in black on the eclipse console.
02:37You will notice that they are not in order. They maybe in order on yours,
02:41they may be out of order, this is a little bit whimsical which one it ends up.
02:46The reason for this is is that the standard output is typically buffered in a UNIX
02:52environment or an environment that emulates UNIX which is most C compiler or
02:56standard libraries and the standard error stream is typically not buffered.
03:02So the buffer isn't getting flushed until the end of the program, here in this
03:07case the end of main.
03:08So the standard error is getting displayed before the standard output even
03:12though they're not in that order in the program. This is typical behavior.
03:17It's not surprising if they're in any order whatsoever.
03:20Now let's take a look at how this works in C++.
03:22I am going to go ahead and delete working.c, and I am going to run clean, and
03:31I am going to take a copy of working.cpp and select working and paste,
03:37double-click to bring it up, and we will go ahead and press the green Run button.
03:43So this is pretty much the same effect, but it's using some C++ paradigms.
03:47You will notice that I have iostream in the include there, and I am using
03:52cout to display text.
03:55So cout sends things to the standard output stream.
03:59If I copy and paste this and change cout to cerr, we will save and run, you will
04:09see I get that same result again.
04:10I have got the red which means the standard error and the black which is the
04:15standard output and again, they are out of order on mine and they may or may not
04:19be out of order on yours.
04:20Another interesting paradigm in C++ is instead of these new line characters, \n
04:26is a meta-sequence for a new line.
04:29Instead of that, I can stream endl, and I can actually do that on both the
04:36 cout and the cerr.
04:40When I save and run, you will see that those new lines are still getting
04:44inserted, they are still on separate lines.
04:46This is another common paradigm that you'll see in C++.
04:51You will see this endl instead of the new line in the stream.
04:55Another advantage of endl is it actually flushes the output stream buffer.
04:59It does both things;
05:00it sends a new line, and it flushes the buffer and so you will see that often.
05:05Also you will notice that if I comment out this line using name space standard,
05:10and I am just going to comment that out, all of a sudden, these tokens for cout
05:15and cerr and endl aren't recognized anymore. And if I try and compile this, you
05:19will see I get lots and lots of errors.
05:21If I hover over this, you will see it says endl was not declared in the scope.
05:26It's just not understanding these symbols, and that's because the namespace is
05:30not getting imported. You'll see it this way a lot.
05:34Instead of using namespace standard like that, having namespace specified in
05:39front of each of these tokens is very common.
05:41So I am just going to show you we will get into namespaces later on in the
05:45course, and you will understand them a lot better later, but you'll want to know
05:49what this looks like because you're going to see it sometimes.
05:52So we are going to type STD for the namespace and two colons, and that
05:55specifies the namespace.
05:56Then I am just going to copy and paste that in front of endl as well, you will
06:01notice that bug symbol went away.
06:02I am going to do that on the next line and the bug symbol went away, and when I
06:09press Command+S here on this Mac or Ctrl+S on a PC and save, and then I go up
06:14and compile and run, see those Xs go away and try running that again and
06:19they come up on the separate lines.
06:21So what was happening there, you see now the red is on the bottom is that the
06:25Hello, World to the standard out was going out before the new line went out for
06:30the standard errors.
06:31So things like this happen sometimes when you are mixing your streams, and it's
06:35not unusual, and it's not unexpected.
06:38So you'll see some strange behavior when you are using both of these strings.
06:42So now let's go ahead and delete and Clean and then delete working.cpp, and I am
06:49going to come up here to Project and Clean and clean up our eclipse environment.
06:54So that should give you a good introduction to the standard output streams in C and C++.
06:58We will take a quick look at the standard input stream in the next movie.
Collapse this transcript
Using stdin
00:01In C and C++ console applications, it's very common to get user input from the standard input string.
00:07Let's see how that works.
00:09We will start by making a working copy of working.c so I will copy that and paste it
00:15into the Working project.
00:17I am going to double-click on it to open it in the Editor here.
00:20The first thing we are going to do is we are going to define a couple of constants and
00:24these will be used later in the program.
00:26I am going to use techniques here that we haven't learned yet in this course and these
00:30will be explained later in more detail.
00:32I am going to start by declaring an enum. This is a common technique for creating constant
00:38integer values in C.
00:40C++ has a better way to do this, but in C, this is common.
00:44So I am going to just call this one max_length and I am going to give it a value of 127, and
00:49then I am going to declare a static character string, let's call it static char and we will
00:58call it response and give it a size of max_length.
01:03Come down here to the printf and I am going to just change this to give us a prompt, it
01:06will say Type a sting.
01:08And you notice it has a space there and no new line, and that allows the prompt to sit
01:14there and just have the cursor waiting at the end of the prompt rather than on the next line.
01:19But because this is using the standard output string that string needs to be flushed before
01:25we go waiting for input, otherwise there is a chance that the prompt won't get printed
01:30until after the input is gathered, that's not we want.
01:33So we use the fflush function like that and we specify the standard output string.
01:40And that flushes the standard output string so that, that prompt displays.
01:44Now we can go ahead and use fgets to get a response from the console and that looks like
01:49this. Fgets takes these three arguments, the first one is the variable where the result
01:56will be stored, the second one is the size of that variable, the maximum length. In fact,
02:03the fgets function will reserve a byte for the null terminator.
02:08So it will actually use max_length minus 1.
02:11And then the third argument is the input string to use which could be a file, it could be
02:16a socket. In this case, we are using standard input from the console.
02:20So now that we have our response, we'll print it. We will say printf, The string is, and we
02:26use this %s token and that allows us to put the value in there of our variable and we
02:32will give that variable.
02:33And I will save it with the Command+S key on this Mac, you can use Ctrl+S on a PC.
02:40And then we will come up here and press the Compile and Run button and it's asking for the string.
02:46Now the Console doesn't have focus, so I am going to click on that with my mouse and now
02:50the Console has focus and you see that my cursor is right there where I want it. I just
02:54type a string and I press the Return key and you notice the string is this is a string,
03:01so there is our response.
03:02So there is a couple of important things that you need to know about this.
03:07You will notice that we are using the fgets function. There is another function called
03:11gets that is a common way to do this and I am going to warn you right now never use gets,
03:15always use fgets instead.
03:18Gets was deprecated in C99 and it's actually been removed from C11.
03:23And the reason for this is that it's a very insecure function.
03:26It allows somebody to just type too much and crash your computer.
03:30By not limiting the size of the input, it just blindly takes however many character
03:35it's given and puts them into a variable, but maybe too small for that.
03:39It's a very, very common security hole.
03:42And you are cautioned to never use the gets function to always use fgets instead.
03:47C11 actually defines a new function called gets_s that may also be used, but as of the
03:54time of this recording, this is not yet supported by the Standard GCC Library and it's probably
03:59not supported by very many libraries at all.
04:02I strongly recommend that you just use fgets for this. It's the right way to do it.
04:07You may see other examples using the gets functions, just don't ever do it yourself.
04:11So this is how this is done is C.
04:14Let's take a look at how this is done in C++.
04:16I am going to go ahead and delete this working.c from our Working project.
04:22And we will copy working.cpp, copy that and paste it and open it up in our Editor.
04:33Now because of the object-oriented nature of C++ and the fact that it has a very robust
04:38string library, we don't need those constants at the top, we can simply declare a string like this.
04:45And then I can take this cout and I can put in my prompt.
04:50You notice that I have a colon and a space just like I did in the C version, and here
04:54for the flushing, I don't use the fflush function, instead I am going to use this feature of
04:59the C++ iostring library and I just put a flush there like that with this Shift Left operator.
05:06The string library overloads this shift left operator. We will talk about this a lot more
05:11in detail later on.
05:13But just to understand this is how you do something like this with a flush.
05:17And now we can go ahead and get our input and we do this with cin and we use the Right
05:23Shift operator and we give it the name of our variable.
05:28Now we output our result.
05:30And I am going to use another feature of the iostring library and this is endl; endl does
05:37a flush and then a new line.
05:40And so it does both of those in one.
05:43It's effectively the same as if I have done this.
05:46And so instead you can just do all of that in four little characters like that, very
05:51common. You are going to see this a lot.
05:53And so I will save this and press the Compile and Run button and you see down here we have
05:59a little prompt. I am going to put my cursor in the Console and click, so it gets focused
06:04and I am going to type, this is a string and press Return.
06:08And you see our response this time says the string is this and it doesn't have the last
06:15three words. It just has the first word.
06:17The reason for that is the cin function.
06:21The cin function is designed to get just the first word of a response, not the full response.
06:28If you want to get the full response, the best way to do that is with a function called
06:33getline and it looks like this.
06:37The getline function doesn't work like some of these other string functions with the overloaded shift operators.
06:42Personally, I like it better like this. I think it's more clear.
06:46And so now when we compile and run, I have saved already with my Command+S key and I
06:50will type a string and press Return.
06:54And now we get our full response. The string is this is a string.
06:58So this is actually a lot simpler in C++. We don't have to create a buffer, we don't
07:03have to worry about the size of the buffer, all that's done for us with the string library
07:07and the iostring library.
07:10That's how you get input from the standard input for your Console applications in both C and C++.
07:15Now we'll go ahead and delete our working file and run Clean to get ready for the next lesson.
07:22
Collapse this transcript
3. The C Programming Language
Exploring the anatomy of a C program
00:00As we begin learning about C, let's take a look at a minimally valid C program.
00:05In the Chap03 folder of your Excise Files, you will find hello.c. Just copy
00:10that and paste it into Working Project and double-click on it, and this is a minimal C program.
00:18It's actually not the smallest most minimal possible legal correct C program,
00:24but it is the smallest practical example of a correct C program.
00:30Let's take a look at all of the different components.
00:32In the first line here, we have a comment, and you will notice that this comment
00:35is introduced by the double slash .
00:38This is actually a syntax that was borrowed from C++ and was added to the C
00:42Standard with C99, but it's commonly used, and it has the advantage that if you
00:48come out to the end of a line, and you want to put just a comment to the end of
00:51the line, you can do it that way, instead of using the old syntax which would
00:55have been to have a slash and an asterisk and then another asterisk and a slash
01:00at the end of the comment.
01:02Now the advantage of the old style C comments is that you can actually have your
01:07comment span multiple lines, so you can have it go on and on and on like that
01:12and just introduce it with the beginning comment marker and add the ending
01:16comment marker at the end of it. Each style has its advantages.
01:20I tend to like the // version, // to the end of the line, it's simple, and it's
01:25quick and most of my comments are just one line anyway.
01:29The next line is actually a preprocessor directive, and we'll get into the
01:33preprocessor in our next chapter.
01:34But this one includes a file, and it includes this file in place.
01:38So this file, called stdio.h which sometimes simply pronounced standard I/O, the
01:45entire file will be included in the compilation process in this place, and that
01:50allows us to have all our function declarations for the standard I/O functions
01:54from the standard library.
01:56Next, we have the declaration of the main function.
01:59The main function is reserved in C.
02:02All C programs must have a main function, it's where execution begins.
02:07So it is required, it is not optional.
02:10Correctly, the main function should return an int and so you see that first word
02:14int that declares the return type for the function.
02:19And you notice we have a return statement that says return 0, and that 0 is the
02:24int that's been returned by this function.
02:26After the word main you have parentheses and inside of those parentheses, are
02:31declarations of variables.
02:33These are the variables that will be used for parameters.
02:36When parameters pass this function, they will be copied into these variables and
02:39those variables become accessible inside the body of the function.
02:43Then there is an opening curly brace, and there is a closing curly brace on line 7.
02:48Those mark off the beginning and the ending of the block of code that is
02:52the body of the function and inside the body of this function, we have two statements.
02:57The first statement is a function call, calling a function called printf, and
03:01you know it's a function call because it's got a name and parentheses and
03:04something inside of the parentheses.
03:07And the next statement is the return statement with the 0.
03:10Both of these statements are terminated by a semicolon, and that semicolon is not optional.
03:16In C, all statements must be terminated by a semicolon even if it's the last
03:20statement in a block.
03:21In a lot of languages, a semicolon can be omitted as the last statement of a
03:25block, it makes the semicolon more of a separator than a terminator.
03:29In C, it's a terminator and all statements must be terminated by a semicolon.
03:33If I remove this semicolon from the return statement, then you will notice we
03:37get a syntax error, says right there Syntax error and so that semicolon is
03:41required, and it is not optional.
03:44So let's go ahead and compile this and run it, and I'll press this Run button up
03:48there, and you see the printf function displaying the string Hello, World!
03:53That's the argument to the printf function.
03:55Now another thing you need to know about C is that all this white space is
03:59really just there for decoration. It makes the program readable.
04:03In other words I can get rid of these indents, and it will still run just fine.
04:08I can put these curly braces on a separate line, and it runs just fine.
04:13In fact, I can get rid of all of the white space except in a few places
04:18where it's required.
04:19Obviously, it's required between the return and the 0, because otherwise it
04:23would be no way to know that these are two different tokens, likewise between
04:26int and main, but everyplace else, well, we need it between int and argc but we
04:31don't need this one.
04:33And we don't even need these, and we don't need that one, and we don't even need
04:37that white space there. So this is a perfectly valid C program.
04:42I am going to save that, and we'll compile it and run it, and you see it runs just fine.
04:47Of course, this is not very readable.
04:49So the reason we have all of these spaces and the indents is to make the code readable.
04:56Now there are different styles of doing this.
04:58Some people like to put the curly braces on lines by themselves, some people
05:01like to indent one or both of the curly braces.
05:05Whatever style you choose just be consistent that style, there is no one right way.
05:10Of course, if you work with other people, it's often times useful for everybody
05:15to agree on a particular style and to stick to that style.
05:18I tend to use the old K&R style because it's the first one that I learned
05:22from the original C programming book that came out in the 70s by Kernighan
05:26and Ritchie, often called K&R. So I tend to use a style like that which is what you see here.
05:31But it's not the best. There is no best.
05:34The only thing that matters is that you are consistent, and that you use the
05:38same style consistently so that you can read your code and so that other
05:41people can read your code.
05:43Now because C++ is based on C, its syntax is basically the same.
05:47Let's take a look at a C++ version of this program.
05:50So I am going to go ahead and delete this from the Working Project, and I will run Clean.
05:57We'll take the hello.cpp, copy that and paste it into Working and double-click.
06:05And here we have the hello.cpp version of this that's in C++, and I'll just
06:10run it, and you see it does exactly the same thing, and there are a few distinct differences.
06:15You'll notice that the include directive includes something called iostream, and
06:18it does not have a .h at the end.
06:21It's traditional for C++ include files to not have the .h. You will also see a
06:26line called using namespace std.
06:28Namespaces are a concept that is in C++ but not in C, and we'll learn about
06:33namespaces later on in the course.
06:36But suffice it to know at this point that the objects in the standard library,
06:42the C++ standard library are all in the standard namespace.
06:47So this cout is actually in the standard namespace.
06:50If I take out that line that says using namespace std, then I need to declare,
06:55you see I get a syntax error there, Symbol could not be resolved.
06:58Then I need to declare that cout is in that namespace, and I do that like this,
07:02std::, and that declares that cout is in that standard namespace.
07:08Now if I save it and run it, it continues to run fine.
07:11I am just going to click this Run in Background.
07:14So I tend to have the using namespace line towards the beginning of all of
07:19my examples in C++ because it makes it easier, I can just type cout instead
07:24of std::cout, especially if there is a lot of objects in the code that use
07:29the standard namespace.
07:31You will also notice that the text is output with the cout object rather than
07:36using printf and cout is an object.
07:39So it's using an operator here, it's actually overloading the left shift
07:43operator in order to send text to this output stream.
07:48That's become a common thing for input and output streams and actually
07:51the iostream library does that a lot with the various input and output stream classes.
07:56In fact, you can use printf if you like, and I'm just going to put that in here
08:01instead say printf and call the printf function.
08:06Even though in the GCC library, printf is declared in iostream, and it's
08:11actually even declared in the standard namespace.
08:13It's more common when you are using printf to go ahead and include the stdio.h
08:18file or its C++ equivalent.
08:23So C++ equivalents of .h files have a c at the beginning and no h at the end
08:29to designate that they are part of the C standard library and not the C++ standard library.
08:34And then I no longer need this using namespace, so I can comment that out.
08:37I can save this and run it, and you will notice that we're basically
08:42running exactly the same program that we had in the .c file but we are running
08:46it in .cpp file when compiling it with the C++ compiler.
08:51So it is possible because the entire C language is included in C++ to simply
08:57write C programs in a C++ file.
09:01Obviously, if you have C++, it's a good idea to make use of its various
09:06features, but it's also good to know that your regular C code will run just fine in C++.
09:12So let's go ahead and delete this file and clean it up, and Project > Clean, and
09:18now we are all clean for the next lesson.
09:20So that's the basic syntax of a minimal C and C++ program.
09:25We'll get into more of the details later in this chapter.
Collapse this transcript
Writing statements and expressions
00:00The C programming language consists mostly of expressions and statements.
00:04In fact, many statements are also expressions and vice-versa.
00:08Let's make a working copy of working.c from the Chap03 folder in the exercise
00:14files, paste it into the Working Project and double-click to open it.
00:18And this is our simple Hello, World! program.
00:21So, if I press the green Run, it will compile it and run it, and it displays the
00:26constant string Hello, World!
00:28But what you may not realize is that printf is also an expression.
00:31It is a function that returns a value, and that value can be assigned, it can be
00:37calculated with, you can do all kinds of things with it.
00:39So let's assign it to a simple integer variable here x =, printf returns an
00:45integer value, so I can print that with another printf statement.
00:50So that's printf and the constant string printf returned %d and \n which
00:56represents a new line and then Comma and the x variable so that x variable will
01:03be used for the value of this %d. So it will say, printf returned and a number,
01:09and that number will be the number returned by printf.
01:11The value that printf returns is the number of characters that it printed.
01:15So in this case, there are five characters in Hello, there are five characters
01:19in World, you have a comma, a space and a new line and an Exclamation Point so
01:24that comes out to 14 characters.
01:26So when I run this, Compile and Run, see it says printf returned 14 because it
01:32printed 14 characters.
01:34Now in fact, because printf returns a value that value can be used on the right
01:39side of an expression as it is here in assigning it to x, it can also be used on
01:44the left side of an expression.
01:46So I can say printf * 5.
01:48So it will take that value 14, and it will multiply it by five and display that.
01:53So I am going to Save and Compile and Run, you see, it returned 70.
01:58Well, printf actually returned 14, and then it got multiplied by 5.
02:02But x here is now the value 70 because we've multiplied it by 5.
02:08So in fact, the printf statement is also an expression.
02:12It calls a function, and that function returns a value, and that value can
02:16be used in calculations. It can be used on the right or on the left side of an expression.
02:21So, really most statements are expressions, what makes an expression a statement
02:26is the fact that it's terminated by a semicolon.
02:28So this entire statement here is a statement because it's terminated by a
02:32semicolon, but it also includes a few expressions, and this expression here,
02:38even though we are not using the value of it, it's still an expression, and it's
02:43also a statement because it's terminated by a semicolon.
02:46So, very specifically, an expression is a unit of computation.
02:50An expression has a value.
02:52That value can be void in some cases which means that it can't be used, but
02:56it's still a value.
02:57A statement on the other hand is a unit of execution and a statement is
03:01terminated by a semicolon.
03:02Multiple statements can be grouped together with curly braces.
03:06These are called Compound Statements. They are also sometimes called blocks.
03:09Unfortunately, the term block also has other meanings, so you will need to be
03:13careful of its context where you see it and where you use it.
03:16You can use a compound statement anywhere where a statement is allowed, but they
03:20are commonly used with control statements.
03:21For example, I can put all of this inside of a loop.
03:24I can say for(int i = 1; i <= 5; ++i).
03:33All of that inside of this block, and I'll go ahead and indent those so
03:37that we can see that they are inside the block, but really it's the curly braces
03:41that make that a block.
03:43Now both of these statements will be executed each time we iterate this loop.
03:47So I'll save this, and we'll Run it, and we see now this is getting run
03:53five times Hello, World! printf returned 70, Hello, World!
03:57Five times, and that's because all of that is inside of that block with the curly braces.
04:03Keep in mind that the compound statement here is really a convenience.
04:07It allows you to have several statements in place where normally you would have just one.
04:11If I were to delete all of this and just put one statement here--terminate that
04:16with a semicolon. Now we have this control structure, this for loop, and it has
04:21just one statement so that one statement will get run five times.
04:24So I am going to Save that and Run it, and we see i is 1, i is 2, i is 3, i is 4 and i is 5.
04:33So that loop got run five times, but it only has the one statement.
04:36When there's just the one statement, it's a single statement, so you don't need
04:40the curly braces because it doesn't have to be compound.
04:43Although it is common practice, and it's actually good practice when you have a
04:47control structure to go ahead and use a compound block anyway, even when
04:53there's just one statement.
04:54You notice that Eclipse put in both of the brackets there for me and
04:59indented and everything.
05:00The reason you want to use the braces in the compound structure even when
05:03there's only one statement is if later on you decide to add another statement,
05:11you already have the braces, and you already have the block.
05:15Otherwise it's possible to forget that and even though you indent it, not having
05:19the braces, it won't be part of that block, so it just prevents errors.
05:23So I'll go ahead and Save this and Run it, and you see that those all get run
05:28together each time through the loop.
05:29Statements and expressions are the building blocks of the C language.
05:32While statements are often also expressions, understanding distinction is
05:38important to becoming a proficient C programmer.
05:41Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with identifiers
00:00Identifiers in C are tokens used to give recognizable names to variables,
00:05functions, labels and defined types.
00:09In C and C++ Identifiers consist of the ASCII representation of the 26 letters
00:15of the ISO basic Latin Alphabet, both in lowercase and uppercase. The 10 Western
00:23Arabic Numerals and the ASCII Underscore character.
00:27Identifiers may not begin with a number.
00:30Identifiers may not conflict with reserved words.
00:33The current C language Standard C11 reserves 43 words, and the current C++
00:40Standard C++11 reserves 73 words.
00:44You cannot use any of these words as an identifier.
00:48Identifiers are case sensitive, so this Az on the left is different from the aZ on the right.
00:55So even though these both say Az they are different identifiers.
00:59Current standards allow letters that are not part of the ISO basic
01:03Latin Alphabet but support for this is implementation dependent, and it is not portable.
01:09I highly recommend you stick to the 26 letters of the basic Latin Alphabet
01:13Numbers and the Underscore using international character sets is not portable.
01:19Current standards allow identifiers to be of any length, although only the first
01:2363 characters are guaranteed to be check for uniqueness and only the first 31
01:29characters are guaranteed for external identifiers.
01:32So in practice you should keep your identifiers under 31 characters long.
01:36An initial Underscore character, that is an Underscore in the first position of
01:41an identifier is commonly used for private identifiers.
01:45More than one initial Underscore is normally reserved for system-level private use.
01:50So don't name your variables with two initial underscores.
01:54Like so many aspects of programming it's a really good idea to decide on a
01:58consistent style for choosing your identifiers and stick to that style,
02:02understanding the rules, choosing conventions and sticking with them, will help
02:06to make your code more readable and maintainable for the long term.
Collapse this transcript
Defining variables
00:00Variables are strongly typed in C, that means that the token representing a
00:04variable represents both its value and its type.
00:07Let's make a working copy of working.c. Copy and Paste and open it up in our
00:14editor here, and I'm going to go ahead and declare a variable.
00:18I'm just going to say, int i; like that. So this statement is a variable definition.
00:23It defines the type of the variable, and it allocates space of a size sufficient
00:28to hold a value of that type.
00:30This variable is an integer, currently it has no assigned value, so it's said to
00:35be undefined, and undefined variables are dangerous thing, so be sure to always
00:40assign a value to a variable.
00:42So let's go ahead and give it a value, give it 7.
00:45A variable definition is also a variable declaration, the distinction exists
00:49only really for external variables, and we'll talk about external variables
00:53later on in this course.
00:55Under many circumstances you'll both declare and initialize a variable at
01:01once like I have here, or we can do something like that and declare and
01:07define a character string.
01:08Now once that character string is declared and defined we can actually use it here.
01:14And when I compile this it will probably complain about i being unused.
01:19Save it and Run it, and so we get a little bit warning there, you see because i is unused.
01:24That's a nice feature of Eclipse.
01:26But here we have declared and defined this variable, and we've initialized it
01:30with the value of this constant string, and we printed it.
01:34So in C all variables must be declared before they can be used.
01:39In other words, if I didn't declare and define it like that, and I try to use
01:44it we get an error.
01:45We can see Eclipse will give us that error right away, Symbol 's' could not be resolved.
01:50The fundamental types available for variables are covered in more detail in
01:53the Data Types chapter.
01:55So now let's go ahead and delete and clean so that we're prepared for the next lesson.
Collapse this transcript
Understanding identifier scope and using storage classes
00:00Identifier Scope and Storage Class determine when and where you may use an
00:06identifier or a variable.
00:07Let's make a working copy of working.c, copy and paste it into the Working
00:14project and double-click to open it in the editor.
00:17Scope refers to the places where an identifier may be safely used.
00:21For example, if an identifier is declared outside of any functions or blocks,
00:26it's visible from the place it was declared until the end of the file.
00:30So if I go ahead and declare an identifier out here, and I have a variable
00:34named number, and if I want to print that inside of this function, I can say
00:42save that and run it, sometimes we get this launcher thing, and it says the number is 7.
00:48Now on the other hand if I take this, and I move that and put it after the
00:54function where it's used, and if I save that and try to compile it, we are
00:58going to get an error.
00:59And our Error here says number is undeclared, because it's actually
01:04declared after the fact.
01:06So when an identifier is declared outside of any functions or blocks, it's
01:10visible from the place it was declared until the end of the file, and here it
01:14is not visible to this function, because the function happens before the declaration.
01:18So we'll go ahead and move that again, and we're going to declare it inside the block.
01:25Now it will be visible again because it's declared inside of this same block
01:30and before it's used.
01:31So if I save that and run it, but if I were to declare it inside the block,
01:38but after where we are using it, now we're going to get an error, see we've
01:43already got this error showing up here, if I try to compile it,
01:46we have that problem again.
01:48And if I were to declare it inside of another block, let's say if(1), which is
01:53always going to be true, and I'll just declare that variable inside of there,
01:58but it's inside of that block, it will not be visible out here either.
02:03Try and run that, and we get the same error.
02:06And we also get an error that it's an unused variable.
02:09So that's called identifier scope.
02:11It talks about the scope in which a variable or an identifier is available.
02:17Scope is not to be confused with storage class.
02:20Storage class refers to when, where and how the storage space for a variable is
02:26allocated and deallocated.
02:28Storage class is sometimes referred to as storage duration, and there are four
02:32distinct storage classes available. Auto, static, extern and register.
02:38Auto is the default storage class for a variable defined inside of a block.
02:43So here, for example, we've defined this integer inside of this block, so its
02:48default storage class is auto, which means that it's allocated in temporary
02:52space, and so here we'll save this, and we'll run this, and we see that it works
02:58fine, and this is an auto variable.
03:00So the space that variable is actually allocated at that time inside that block,
03:05and it's deallocated at the end of the block.
03:08Now let's put all of this inside of a loop, so we can take a look at the
03:12difference between auto and static storage duration, for(int i = 1; i <= 5; ++i)
03:25and we'll go ahead and close the block here and indent it for clarity.
03:29So now the interesting thing here is that when I save this and run it, you see
03:33we just have the number is 7 five times.
03:36If I increment that, I'll just put a plus, plus after it, so now it gets
03:43incremented each time, but it's still going to be the number is 7 five times,
03:47because it's auto storage, it goes away each time.
03:51On the other hand, if I make this static, say static int number = 7, now it's no
03:58longer auto storage, every time through the loop it's using exactly the same
04:01storage space and so when I run it, it actually gets incremented, it starts at
04:05seven and goes up 8, 9, 10, 11.
04:07That's now static storage, it's permanent, it stays there, and it can be reused.
04:12We are going to skip extern storage for a moment, and we are going to talk
04:17about register storage.
04:18If I say register here, you'll see that it works just like auto, so I'll
04:21save that and run it.
04:23You see it says the number is 7, the number is 7 seven.
04:26The distinction here is that you're giving the compiler a hint to try to store
04:29this variable in a register of the processor rather than storing it in temporary
04:35storage space, and this should make it faster.
04:38The reality is is if you are using any optimization in your compiler anyway, the
04:43register keyword is probably going to be ignored.
04:45And the optimizer is going to choose variables that are used in certain ways and
04:51put those in registers if it can to make them really, really fast.
04:54So, even though this keyword exists, it may or may not be implemented in certain ways.
04:59Modern optimizers are usually better at this than the programmers, so it's best
05:03to use this only where it's absolutely necessary.
05:06Now let's talk briefly about extern.
05:09What I am going to do here is I am going to grab this func.c, and I am going to
05:12copy and paste that into our Working space.
05:16I am going to open that up, and now we have two files open, we have func.c and
05:20working.c. We have a problem here, we have this func.h, I am going to delete
05:25that, I am also going to delete this main because we're not going to use that.
05:29And so what we have here is we have a function called func, and I'm going
05:33to just also declare variable int, I am going to call it var, and I am
05:37going to give it a value 47.
05:40Because these are in the same folder, and we're using Eclipse, this will go
05:44ahead and get compiled and linked together with our working.c. And so I can
05:48declare up here, I can say extern func and what's my function, it's just a void.
05:54So I am going to say extern void func like that, and then I can call it from right here.
05:59I can say func, and it will get called.
06:02And if we look over what it does, it just printfs, this is in the function.
06:06And when I save that and run it, you'll notice that this is the function,
06:11because that's what in our function over there so that got actually run.
06:15If I take out this extern void func declaration and try to run it, you'll notice
06:22that we get an error right here, implicit declaration, and that's not allowed.
06:28So put that extern void func back in.
06:31So the external storage class means this is something that's in a different
06:34translation unit, it's in a different source file, and it gets linked
06:38together at link time.
06:39So this tells the compiler don't worry about it, we'll link that together
06:43when we do the linking.
06:44So, I am going to save that and run it, and that should get rid of our
06:49little error thing there.
06:50We can do the same with the variable, I can say extern int var, and now I can
06:54actually print that, I can come down here, and I can say printf extern var is %d
07:03and a new line and var.
07:05And that will actually you see this variable over here is number 47 so that will
07:09actually go ahead and print that. So it's the extern var is 47.
07:14So this external storage class extern, it tells the compiler this is something
07:20that's defined elsewhere, but we're declaring it here because we're going to
07:24use it here, but it's actually defined in a different file, in a different translation unit.
07:29So scope refers to where an identifier is visible and storage class refers to
07:34how and where the storage is allocated for the identifier.
07:37Understanding these concepts is important for writing code that is efficient and reliable.
07:43Now let's delete our working files and run Clean to get set up for the next lesson.
Collapse this transcript
Declaring variables and functions
00:00Before identifiers can be used they must be declared.
00:03In early versions of C all the declarations needed to be at the top of the block
00:07of code, but in version since ANSI C or C89 this restriction has been removed.
00:13It's now considered good practice to declare variables closest to where they are first used.
00:18Let's make a working copy of func.c, paste it here into the Working project,
00:24and I'll open that up.
00:26I'm going to go ahead and comment out this #include directive for now, we'll
00:29be using that later.
00:30I'll go ahead and Compile and Run it, and you can see it displays Hello, World!
00:34And then it calls this function which prints, this is in the function.
00:39So in this case we have declared and defined the function before it's used.
00:43We're using the function in main, and that's on line 11 and up here in line 5,
00:49the function is being declared and defined.
00:52If we move that definition down after the main function, and we go ahead and
00:57Save this and Compile and Run it, you see our compilation. I'm going to go ahead
01:02and press this button over here which changes the Console to show the compilation process.
01:07You see that there are warnings in here, and we can see those warnings also in
01:12these little Exclamation markers.
01:13And so that's not really working as we expected it, it's kind of working by accident.
01:19If we go ahead and declare this above here, let's say void func() with a
01:24semicolon, like that. That's just a declaration it's not a definition, and we save
01:29this and Compile it and Run it.
01:32Now our warnings go away and everything is working as we expected it.
01:36So the declaration, even though the definition can be later or the definition
01:39can be even in an external translation and linked later, that declaration needs
01:44to be before it's used.
01:46The same is true of course, of variables, I can say int i = 47 up here, and then
01:52I can come inside my printf, and I can just say, i is %d, and i there, and that
02:01will work exactly as I expected it to. See now here it says i is 47.
02:07And if I were to move that to after main and try to Compile and Run it, we
02:13actually get an error.
02:15This is not just a warning because it doesn't even know what to do with the i.
02:19It's also common to declare it inside of the function, this main function here,
02:24I can save this and Compile and Run it, and that works just fine.
02:28And I can move both of these later in the function even after the function call
02:34and Compile and Run that, and that works as expected to.
02:37This is the thing that didn't used to be legal in C before C89 that would have
02:43had to have been at the top of the function.
02:45So oftentimes you'll see just as a matter of tradition a lot of declarations
02:49at the top of a function and then those things are all used later on in the function.
02:53And that's really a throwback to the early days of C, and it's not really
02:57considered best practice anymore, best practice is considered today to declare
03:01something just before you use it and perhaps set off that bit of code with some
03:05new lines like that.
03:07I'll go ahead and Compile and Run that, and we see that it works as expected.
03:12Another common paradigm is to have a for loop and inside the for loop control
03:18you have a variable that's just use for loop control, so you can say (int i = 0; i < 5; ++i)
03:26increment i and then put this all in a block, and we can take this printf,
03:32and we can put that inside the block, and now that will happen five times.
03:37And so I'll compile and Run that, and we see that i is 1, 2, 3, 4, 5.
03:42Now here I reused i because I had named my variable i up above there as well,
03:47and so this one is getting unused because I have one defined inside this other scope.
03:53So I'll get rid of that for now.
03:55This construct here of both defining and declaring the variable inside of those
04:02parentheses that used to be illegal, you used to have to declare the variable
04:08outside like this and then initialized inside the loop construct like that.
04:14We'll see that runs exactly as we expected to, and so you'll often see that.
04:18But since C99 the second to latest standard we've been able to do it this way
04:26which is a lot cleaner.
04:28And as we've seen our functions need to be declared as well, so here we have
04:31this void func() at the top.
04:34It's often very common instead to put that inside a header file and include that
04:39using a Preprocessor directive like this.
04:41So let's go ahead and copy and paste func.h from the Chap03 folder and paste
04:46that into our Working project.
04:48We'll go ahead and open that up, and you see in here we have that function declaration.
04:53And so, by including it here then it's actually included in the scope, because
04:58remember that included file gets included in place.
05:02This entire #include directive gets replaced with the contents of that file.
05:07We'll discuss later the distinction between these quote marks and these brackets
05:10when we'll talk about the preprocessor.
05:13But for now know that everything that's inside of this file is actually get
05:17included in this context.
05:18So when I save this and run it, our function call happens fine, we don't get the
05:22warnings even though the function is defined down here.
05:26So inside the header file we have the declaration and inside the source file we
05:32have the definition. That's an important distinction.
05:36So variables and functions must be declared before they can be used, they may be
05:40declared in header files, even defined in external source files that are
05:45compiled separately and linked later, but they must always be declared in scope
05:49before they are used.
05:52Now let's delete our working files run Clean to get set up for the next lesson.
Collapse this transcript
Using pointers
00:00Pointers are very powerful, useful, dangerous and common construct in C.
00:06To truly understand pointers you must first understand how variable works.
00:10A variable is a typed and named location in memory.
00:14In this declaration memory is allocated in the size of an integer and
00:18associated with the name x.
00:20Here the integer value 1 is placed in the memory location associated with the
00:25integer variable x, and this is both a declaration and an assignment, memory is
00:30allocated in the size of int and the value from the variable x is copied into
00:35the variable named y.
00:36The variable y now contains a separate integer in a separate memory location
00:41with the same value as the variable x.
00:44So we can see that the name of a variable is used as an index to map to a memory
00:49address and a particular associated data type.
00:52C syntax gives you the ability to create a variable that is a pointer to a value
00:57as opposed to carrying the value itself. This is a pointer declaration.
01:02The variable named ip is of the type pointer to int.
01:06Here memory is allocated in a sizable pointer and the Compiler associates this
01:11pointer with the type int.
01:13This is typically referred to as an integer pointer.
01:17Here the address of x is placed in the pointer variable named ip.
01:22The Ampersand is formally called the Reference Operator, but is more commonly
01:26called the address of operator.
01:28It returns the address of an object, suitable for assigning to a pointer.
01:34So this statement assigns the address of x to the integer pointer ip.
01:39The integer pointer ip now points to the integer variable x.
01:44It's worth noting that the Ampersand is also used in C++ for special reference
01:49type that is not available in C.
01:50The reference type is covered later in the Data Types chapter.
01:54This statement copies the value pointed to by ip which currently points to the
02:00integer variable x to the integer variable y.
02:03You can of course change ip to point to a different variable.
02:07Understanding pointers is critical to using C or C++ effectively.
02:11Take some time to go through these examples and experiment with pointers on your
02:14own, understanding this will serve you well for the long-term.
Collapse this transcript
Working with arrays and strings
00:00Arrays are simple to define and simple to use in C.
00:04This declares an array of integers with room for five values.
00:09Arrays are indexed with integer values. The first element is always number 0.
00:15This assigns the value 1 to the first element of the array.
00:20This declares an integer pointer and assigns the address of the array.
00:24Notice that you don't need to use the ampersand address of operator to assign
00:28an array's address.
00:30This is a special case in C syntax, and it's worth remembering because it's used frequently.
00:35The name of an array may be used as an address without the ampersand address of operator.
00:42This assigns the value 2 to the first element of the array, because the pointer
00:47was assigned to the array, it is pointing to the first element.
00:51You can increment the pointer, and it will point to the second element.
00:56In C pointers are strongly typed. So they know the size of what they point at.
01:00So when you increment a pointer it always increments by the size of the object it points to.
01:04So this assigns the value 3 to the second element of the array.
01:09This is another common technique in C.
01:11Here we're incrementing pointer and using it at the same time.
01:15It's just a shortcut for the separate increment and assignment of the
01:18previous two statements.
01:21In C a string is a special case of an array. To illustrate let's look at an example.
01:28Let's make a copy of working.c, and I'll copy that and paste it into the working
01:33project and double-click to open it up.
01:36I am going to start out by declaring an array of characters.
01:40So I'll say char s and just the two brackets.
01:44We're not going to put a number in for the size of the array, because that can
01:49be inferred by its initialization.
01:50Here we're going to initialize it with a number of characters 's', 't', 'r',
01:58'I', you see where I'm going with this? The 'n' and a 'g'.
02:01Then I am going to give it a number 0 and a semicolon, and this is a c-string.
02:07In C a string is simply a special case of an array.
02:11It's array of characters, and it's terminated by a 0 value.
02:15Some people call that a null terminator.
02:17So this null-terminated array of characters is exactly the same as string.
02:23In fact, I can do this. I can say string is:
02:28%s and give it the s variable which is an array of character that we've
02:33initialized right there.
02:34And give this all to printf, and it will print the word string.
02:38I'm just going to save that and run it.
02:41It's compiles it and runs it, and it says string is string.
02:44So this is exactly the same as if we had done this, which is of course the more
02:49common way to do that.
02:51So this simply initializes this character array with the letters s, t, r, i, n,
02:57g, and the null byte the 0 value.
03:00So this array is seven characters long, and it holds the string string.
03:05So if I run this we get exactly the same result.
03:08In fact, we can treat this as a string.
03:11We can say for (int i = 0; s left bracket i right bracket != 0; ++i).
03:21We can just print out each character.
03:26%c will print a character, and we are going to say s sub i, which is actually of
03:32type character, and now when I save this and run it, see we get all of the individual characters.
03:39Here they are, s, t, r, i, n, and g.
03:42So we can see that a string is really just a special case of an array of characters.
03:47And that character pointer should index into that array just as we would expect.
03:52So we can actually do something like this instead of using the integer to index
03:57in the array I can declare a character pointer like this, initialize it to
04:01point at the array.
04:02Remember, you don't need to use the address of operator with an array, and I can
04:07say, while, what is pointed at by cp.
04:09I don't even really need to compare it, and I don't need to do not equal to
04:14zero, because I can actually use it as a logical value.
04:17This is very common in C, and increment the character pointer, and now instead
04:22of this s sub i, I can just do that.
04:25So here I'm using this character pointer to index through this array.
04:29I'm using it like an iterator, and that's really a very, very common paradigm in C.
04:34So I save this and run it, and you see we get exactly the same result.
04:38There is our character string s, t, r, i, n, and g.
04:42So the combination of arrays and pointers is really powerful and really common in C.
04:47Array is a structure variable of the same type stored contiguously indexed by an integer value.
04:53Because the array is guaranteed to be stored contiguously it's also easy to
04:57iterate it with pointers and C syntax lends itself well to this usage.
05:02So let's delete the Working file and run Clean to get set up for the next class.
Collapse this transcript
Comparing with conditionals
00:00The C language has two basic forms of conditionals.
00:03The if else control structure, and the conditional operator.
00:08Let's take a look at this.
00:09Make a working copy of working.c, paste it here into our Working project,
00:15double-click on it to open it up, and we'll just replace that printf with
00:20a control structure.
00:21We'll start with if and a couple variables for true and false int a = 1 and int b = 0.
00:31In C++, you have a bool type for booleans, and you have true and false.
00:36In plain old C, you've got integers, and 1s and 0s.
00:40Of course you can use any of these scalar integer types, you can use character,
00:45you can use int, you can use long, int is really common, it's usually a
00:49convenient word size usually don't actually save any space or any speed by using a char.
00:54You can use a char here, and it'll work just as well.
00:57I'm going to use ints for now. And so 1 is true and 0 is false.
01:02So we're going to say, if(a), we'll use a puts here, because we're not going to be
01:08doing these substitution, "this is true".
01:10So if I save this and run it, we'll get this is true.
01:15And if I change that a to a b, save that and run it then we'll get nothing
01:20because it's not true. So let's put in an else clause.
01:23We can say else puts ("this is not true") and save that and run it.
01:31And now for b, it's not true, and if we put the a back in there and save that
01:36and run it, we get this is true.
01:38So that's pretty straightforward, and of course the common way to see this, and
01:42I personally will rarely just put a statement on the same line as a conditional
01:47like that, that's an invitation to bugs.
01:49I mean, it works, and it's correct, and if you never change it, it's fine, but
01:54the minute you start messing with it, you tend to make mistakes.
01:57So always just put it in the curly braces like that, and do the same thing here.
02:02And I will usually also put the else on the same line as the closing curly brace
02:07of the if, that's called a cuddled else. And a lot of people hate that, I like it.
02:12I find it really easy to read, and I find that it's economical on space, and so
02:16this has exactly the same result here.
02:18We'll run that, and it says this is true, and if we change it to a b and save it
02:23and run it, we get this is not true.
02:26You notice we get the little warning here for the variable we're not using as an
02:30unused variable, and that's fine, we were expecting that.
02:32Now what if you want to test for if that's not true, let's see if the other one is true?
02:37A lot of languages have an elseif, where you can do something like that.
02:41I'll change this one to a and then test for b and the elseif, unfortunately C
02:47does not have an elseif.
02:48So you have to actually do this here, and say else if as two words, and it
02:53works exactly the same.
02:55So if I run this, I say this is true, and if I make this one a 0, and this one
03:02a 1, then I get the else if b, and I can actually put there, the other is true and run that.
03:11And then if you want, you can have final else, and say, nothing is true.
03:16And then if I make both of these 0s, then I get the nothing is true.
03:21This is a really, really common you know, sometimes you'll get chains of
03:25else ifs and else ifs and then an else at the end, it's a pretty common way to do things.
03:30C also has another way of doing conditionals, and this is called the
03:35ternary conditional operator just because it's so much fun to say, and it works like this.
03:44So if a is true, we'll get a seven in c, and if a is not true then we'll get a 9, okay?
03:50So I'll go ahead and I'll say printf("c is %d\n ", c) and save it and run it, it says c is 9.
03:59So what it does here is it tests the condition, and if the condition is true,
04:03it gives you the first value, and if the condition is not true, it gives you the second value.
04:08So in this case, it's not true because both of these are 0s at this point, so we
04:12get a 9, and if I change the a to a 1 and save that and run it, then we get a 7
04:18because that condition is true.
04:19And so, you can do things like you can say if a == 5, save that and run it, then
04:27I get 9, because it's not equal to 5.
04:29If I make it a 5, then I save it and run it, then we get the 7 because it's now true.
04:35So it's called the ternary conditional operator because there is a condition,
04:39which is this part here, and it's really always a good idea to put this in
04:43parentheses, because otherwise you need to memorize the operator precedence
04:47chart, and nobody enjoys doing that.
04:49And if you have anything more than a single value in these value places then you
04:55want to put those in parentheses as well.
04:57And we can just stick parentheses around that, for that purpose for now.
05:00So we'll save this, and we'll run it, and we see we get the 7 because it is
05:05equal to five, and if we make it 42, then it's no longer equal to 5, and now
05:11we'll get the 9 value.
05:12So it's called the ternary conditional operator because it's ternary because it
05:16has three operands as the condition and the true and the false operands.
05:21And it's called conditional because it operates on a condition.
05:26So ternary conditional operator, you will hear referred to a lot because people
05:30are proud themselves to being able to remember it and say it, I guess.
05:34Conditionals in C are simple and effective.
05:36There's one more type of conditional multiway switch that's covered in the next lesson.
05:41So let's go ahead and delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using switch statements
00:00C provides a special multi-way switch control for branching conditional
00:04operations using the switch and case statements. Let's take a look at how this works.
00:10We'll make a working copy of working.c, and I'm just going to paste it here into
00:15the Working project and double- click on it and open it up there.
00:19We're going to put in a switch statement here. We're going to have to a little other typing.
00:23So bear with me for a moment. Switch statement works like this.
00:27If I've a variable like in this, like in this case I'll make an integer, and
00:31I'll call it foo, and we give it value of 3, then I can have a switch statement
00:35like this switch(foo) and give it an empty block.
00:41Now depending on the value of foo I can have it do a number of different things.
00:45So I can say case 1 and have it do puts("one");, and I need a break.
00:52I'll explain that in a minute.
00:54And if I type case 2, you'll notice that Eclipse is really nice about formatting
00:59this, puts("two");, and a break.
01:03Let's just go ahead and copy and paste it a couple of more times.
01:08So if the value is 2, it'll come down here, it'll put two.
01:11If the value is 3, which it is it will branch to this case 3 and run everything
01:17from there to the break. So if I run this, you see there it prints three.
01:22If I were to take out this break, it would print both three and four.
01:26This happens sometimes in Eclipse.
01:28You can just click run in the background, and there you go.
01:31So it prints three and four, and you notice we get a little warning here.
01:34It says No break at end of case, because that's usually a bug.
01:38Because usually you want to have a break in there so that it just does that one conditional.
01:42This is what's called a multi-way conditional or a multi-way switch.
01:47One thing you need to be aware of is these case clauses cannot have a variable.
01:52It has to be a constant.
01:53So if I had a variable up here, int twovalue = 2;, and if I'm trying to say case twovalue;
02:02then when I try to compile it and run it.
02:04I can just press Save, and I'll Run in here, you'll see I get an error, and the
02:09error says case label does not reduce to an integer constant.
02:13So that has to be an integer constant.
02:16So I'll put a 2 back there and save and run it, and it works just fine.
02:20So normally what's you end up doing, especially in C is you end up creating a
02:25list of constants and in C a constant looks like this #define ONE (1) like that, and
02:32because this is a preprocessor directive, and it's not actually compiled, it's
02:37run through the preprocessor, and it's actually a macro, we will learn more
02:41about this in the chapter on the preprocessor, because of that you do not put a
02:45semicolon at the end. The semicolon here would be a syntax error.
02:49So let's just create a few of these, and now in place of these 1, 2, 3, 4, I
02:54can say, ONE and TWO.
02:58So you want to use constants here if you can. Just makes it easier to maintain your code.
03:04Now you can change all this in one place rather than having to look for all the
03:07places where you need to change it.
03:09So I'll save that and run it, and you see that it works just fine.
03:13Now there's also a disadvantage to using these defines for constants.
03:17Unfortunately, in C that's all you've got.
03:19In C++ you can actually use real integer constants, because these aren't
03:25processed by the compiler at all.
03:26These are processed by the preprocessor, and they are actually macros.
03:30They're subject to side effects and they don't get into the symbol table.
03:33So for a lot of purposes that's all you got.
03:36So you use it, but it's not the best way to do it.
03:39For best programming practice, you want to use integer constants, which only works in C++.
03:43So we're going to go ahead and rename this file, and I'm just going to put pp on
03:47the end of it, and that makes it working.cpp instead of working.c, and now it
03:52will compile with the C++ Compiler instead of the C Compiler.
03:55I'm going to go ahead and clean the project to make sure this works on all of
04:00the platforms, and I'm going to bring that up in my editor.
04:03Now instead of this #define ONE like that, I'm going to say const int iOne = 1;
04:11like that, and I'm just going to make four of those, and I'm just going to
04:16paste these in down here.
04:18Now again, this does not work in C, it only works in C++, but it does
04:24work beautifully in C++.
04:27Now these are integer constants. They're immutable.
04:29You can not change them. They're actually constants.
04:32So I can't come down here and say iOne = 42.
04:37I'll get a syntax error if I try to compile and run that, and there it is.
04:43See that little error there, it says assignment of read-only variable 'iOne'. Cannot do that.
04:50But for the purposes of the switch statement for all of these case clauses it does work fine.
04:55I am going to go ahead and compile and run this, and we see that it does exactly
04:58what we expect them.
05:00I am going to change this value to a 4 and again we're getting this here.
05:04You can just switch this Always run in the background and never see this, but I
05:08leave it running, and there we have 4.
05:10Now if I change this to another value like 5, we don't have a case for 5.
05:16So if I run that, you'll notice we get nothing.
05:19And for that purpose the switch statement has a default clause.
05:25So save that and run it, and now we get default.
05:28So any number we put up here, 42 run that, and it says default, zoom this in a
05:35little bit so you can see the whole thing. So that's how switch works.
05:40The multi-way switch control can be very handy in cases where you need to select
05:44a condition from a list of possibilities. The case statement needs a constant.
05:49So you'll need to take special care to use the proper type of constant for this purpose.
05:53Now let's go ahead and bring this back, and we will delete our Working file and
05:58run Clean to get set up for the next lesson.
Collapse this transcript
Using while and do loops
00:00The basic looping control in C is the while loop.
00:03The while loop tests a condition at the top of the loop, and there's also a
00:07version that tests the condition at the bottom of the loop, and we'll look
00:10at both of them here.
00:11So let's start by making a working copy of working.c out of the Chap03 folder
00:15I'll copy that and paste it down here in our Working project and open it up in the editor.
00:22So we'll start by defining a variable for our while loop, I'll just define
00:27integer x and give it a value of 5, and then we'll say while(x > 0) and then our
00:36loop here, and we'll printf("x is %d\n", x);, and then we'll decrement x.
00:47So, we'll go ahead and save this and run it, and we'll see that we have x is 5, 4, 3, 2 and 1.
00:54So let's step through it.
00:56First we initialize x to be equal to 5, and we test if x is greater than 0.
01:03And it is that first time of course, and so we print it out, and we get a 5
01:08there in our output. And then we decrement x, and now x is 4.
01:11And we get to the end of the block and so that takes us back up to the testing
01:16condition of the loop at the top of the loop, and it tests again.
01:20Now x is 4, so it's still greater than zero and so we print out the 4 and then
01:24the 3, the 2, and when it gets down to 1, it prints out the 1, and it decrements
01:29the x and then the next time it tests it's no longer greater than the 0.
01:33It's also common to just test for x like this while, because when x hits 0 it becomes false.
01:40And so this while like this is testing x as if it were a Boolean variable and of
01:45course in C, there's no Boolean type.
01:48There're just integer types that are tested against 0.
01:52So when it's 0 it's false, when it's not 0 it's true, and so you'll often see
01:56it tested like this.
01:58In C++ there is a Boolean type, but this still works, and this is still a common
02:02pattern even in C++.
02:04So we'll save this, and we'll run it, and we see that we get exactly the same result.
02:08Now there's another version of this loop called do while, and it looks like this.
02:15I'm going to put that in my cut buffer, and I'm going to say do and open the
02:20bracket and close it down here and say while and put in a semicolon there
02:26and get rid of the tab.
02:27So do while looks like this, do print blah, blah, blah while x, and you'll see,
02:34because the way we're doing our testing here, we'll get exactly the same result; 5, 4, 3, 2, 1.
02:40The difference is that that we're doing the test at the end of the loop rather
02:44than at beginning of loop.
02:45And since I'm doing this decrement at the end of the loop anyway, we're really
02:49getting exactly the same result.
02:50Where we get a difference is like this, I'm going to put it back for a moment
02:55the way that it was.
02:56I'm just pressing the Undo key on my keyboard which is Command+Z on a Mac;
03:02it would be Ctrl+Z on a PC and get back to this point.
03:05And instead of decrementing the x down here, I'm going to decrement the x in the loop control.
03:10This is also a very common construct, and it's actually even more common
03:14probably to see it done this way than the other way.
03:16We're going to get a different result though because we're actually decrementing
03:20it before we do the printf.
03:22And so our results will start at 4 and go through 1, rather than starting at 5
03:27the way that it does.
03:28Now because first time through it starts out at 5, and we decrement it
03:32before we even test it. And so when I run this we get 4, 3, 2, 1.
03:39So the decrement operator here being before the x means that the decrement
03:43happens before you test the value, before you get the result of the expression.
03:47If I put the decrement operator after the x then it'll evaluate x first and then decrement it.
03:53And now what we'll get is 4, 3, 2, 1, 0.
03:56So I'll save this us, and I'll run it, and now we get 4, 3, 2, 1, 0.
04:00Now if I were to take this and put this at the end with a do while like that, so
04:08now we have do printf, and we have the condition with the decrement.
04:13Let's try it first with the prefix decrement, and let's see if we can figure out
04:18what we're going to get.
04:19We'll start out with a 5, and we'll get all the way down to 1, but we won't get to 0.
04:24There we go 5, 4, 3, 2, 1.
04:26Now if I take that and make it a post decrement, now we'll get the 0.
04:31And it'll go 5, 4, 3, 2, 1, 0. So you see you get different results.
04:35So the while loop is a fundamental control in C.
04:39The while loop tests the condition at the top of the loop and do while tests the
04:44condition at the bottom of the loop.
04:46Do while is used less frequently, but it's still very important to
04:49understand both of them.
04:51Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Iterating with the for loop
00:00C provides a very useful iteration loop control called the for loop.
00:04Let's see how this works.
00:06I'm going to take a working copy of working.c and paste it into the Working
00:11project and open it up in the editor.
00:14First let's just create a simple while loop, and this is actually an example
00:18from a previous movie. We'll say int x = 5.
00:21While we'll printf the value of x, and then we'll decrement x using
00:28the decrement operator.
00:29So this initializes x to 5 and then the first time through the loop, obviously 5
00:34is still true as long as it's nonzero, it's true.
00:37Once it hits 0 it becomes false, and that while loop will end.
00:40So it'll print a 5, and it'll decrement, and then it'll print a 4, and it'll
00:45decrement, all the way down to when this gets to be 0 then it'll stop the loop,
00:49and it won't print 0, so it'll print 5, 4, 3, 2, 1.
00:52So save that and run it, and there we have x is 5, 4, 3, 2, 1.
00:58The purpose of the for loop is to be able to do all of this on one line.
01:02So let's go ahead and create this as a for loop. We'll say for( x = 5; x; --x ),
01:06and we'll printf() the value of x, and let me declare x here with an int.
01:16So this for loop is exactly the same as all of this, and it's really just two
01:21lines of code unless you count this closing brace.
01:25So we've reduced the amount of lines of code, and we've made it actually simpler.
01:29Now this might look cryptic at first if you haven't seen this before, but once
01:32you get what this is it's a lot simpler.
01:35So I am going to go ahead and delete the while version, and we'll just take a look at this.
01:40The for loop takes three clauses in the control section.
01:43The first clause is the initializer, and here we say int x = 5.
01:47The second clause is really the while control, while x.
01:51And the third clause is do this at the end of the loop before we start the
01:56control again and so here we decrement x.
01:59So it's exactly the same code that we had in the while loop.
02:02And so when I save this and run it, you'll see we get exactly the same result 5, 4, 3, 2, 1.
02:07Now it's much more common to do this like this.
02:11Say int i = 0 and people tend to use i because this is an iteration
02:16control, while i < 5;
02:20and ++i. So if you want to do something five times, you make a for loop like
02:25this, and you say i = 0 while i is less than 5.
02:29In C it's tradition to start things at 0, so testing for while i is less than 5
02:35actually ensures it happens exactly 5 times, because when it gets to 5 you've done
02:39it five times, and it'll stop.
02:41So if we run this it'll say i is 0 through i is 4, and there will still be five
02:46lines, i equals 0, 1, 2, 3, 4, and that makes five lines.
02:50So that's a really common way to do this.
02:53Also you'll notice that I'm able to declare and initialize the variable inside
03:00the for loop control.
03:01This is one of the few places where this is allowed in C and actually this
03:05wasn't allowed in C until C99.
03:08So it's only been the last version of C, of course we are it C11 now.
03:11But until recently, C99 was the latest version and before that this wasn't
03:16allowed, and what you had to do is you had to do something like this, int I
03:20and then say for(i=0;).
03:23And since it's such a bad form to declare a variable and not initialize it, it's
03:29really prone to errors, if you end up using that variable for something else.
03:33So you would see this int i = 0 and then nothing in the initializing clause of the for loop.
03:41So here we'll see we get exactly the same result, save it and run it, and we
03:45have this sort of odd looking for loop like this.
03:47And so when C99 was ratified, this became legal, and it made it a whole lot
03:53simpler and a whole lot more common.
03:54And it has the added benefit that this particular version of i is really only
04:00valid inside of this loop.
04:02Outside of this loop if you had an int i declared outside of it, it would be a
04:07separate variable than the one that's inside the loop.
04:10So you don't have your namespace pollution that you have the other way.
04:13Now let's take a look at an example of how to iterate through an array, because
04:17this is another common use of for loops. Let's create an integer array.
04:21We have five elements, and we'll go ahead and terminate this with a null.
04:25We'll put a 0 at the end, so we have six elements and the last one is the
04:29terminator, and it's a 0 and again that's a common pattern in C.
04:33And so we'll declare an integer pointer here, and we'll initialize it to ia.
04:39And remember, with an array the name of array can be used as a pointer.
04:44It's an immutable pointer, but it's still a pointer.
04:46So I can assign it to a pointer and use that as an iterator.
04:51And while what's pointed at it by *ip is not null so that just looks like that.
04:56And then we'll increment ++ip and down here instead of i we'll say value is, and
05:04it's what's pointed out by *ip. So let's take a look at this real quick.
05:07We have an integer pointer, and we're initializing it to the beginning of the
05:10array, the first element in the array.
05:13And then we're testing for what's pointed out by that pointer to see whether it's null.
05:18When it gets to null, this test will become false and the loop will stop.
05:22And then we're incrementing the pointer at the end of the loop.
05:26And in the loop we're simply printing the value of the pointer, so this should
05:29come out saying value his 1, 2, 3, 4, 5.
05:32So I'm going to save that and run it and here we have value is 1, 2, 3, 4, 5.
05:39So that's actually a pretty common way to step through an array using an integer
05:45pointer or whatever type that array is that pointer as an iterator.
05:51So the for loop is a fundamental control in C, it's incredibly powerful and
05:55useful, and while it may look cryptic at first, once you to get to know it,
05:59you'll find a lot of uses for it.
06:01Let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Creating functions
00:00Functions are the basic code structure in C.
00:03A function consists of a return type, a function name, zero or more parameters
00:07and a block of code. All code must be in functions in C.
00:13Let's make a working copy of func.c, and we'll paste this into our Working project.
00:19I'm just going to comment this part out, and we'll use that in a bit.
00:24Here we have a function and main which calls the functional, so we'll go ahead
00:29and save this and run it, and we can see how this works.
00:32Now this is a very simple function, it doesn't take any parameters,
00:35it doesn't return a value, and it's simply called like this.
00:38And when you call it, the code inside the functions block is executed which has
00:42this one printf statement. So the block is where things happen.
00:47We could have more things happen in the block, we could declare a variable, we
00:54could initialize a variable, we could do some math on the variable, and we could
01:00print the value of the variable.
01:03And many things we can do in there save it and run it, and you can see i is 25.
01:08In fact, if we wanted to, we could simply return the value of i and in order to
01:14do that we need to change the return type to int and then down here we can print
01:19the value, like this.
01:23So there we're actually using the return value directly, we are not even
01:26assigning it to anything first.
01:28We'll save this and run it, we see we get value is 25 is so that's from over other.
01:34If the return type is void of course, then it's no longer legal to return anything.
01:40And it's no longer legal to take that value.
01:44So if I were to try and assign this, say int x = func() and put the x over here,
01:54this is no longer legal.
01:55If I save this and run it, it says void value not ignored as it ought to be,
02:02because I've declared it as void.
02:04So this type declaration, this actually dictates the type that the function is used as.
02:11So when I try to use this function like this, the compiler knows that that is a
02:17void value, and I can't assign it something.
02:19So if I give it an int type, and I give it a return value, now the type of this
02:25function expression is now int, and I can assign it to an int, and I can use it
02:29in the context of an int, and if I run this, I get the value that I expect.
02:34I could also pass parameters to func.
02:36In this case let's just pass one parameter, we'll pass an int, and we'll call it
02:40x and instead of adding 25 here I'll add x, so I'll use it like that.
02:47And now when I call it I'll call it with 50, so we get a different value.
02:51So what this does is it passes this 50 into the function.
02:55Now the way that it does that is by declaring a new temporary variable, and
03:00copying this value into that variable.
03:03So it's not actually using the 50 directly, it's actually copying it into the function.
03:09This called call by value and all functions in C are called by value.
03:14So if I save that and run it, now the value is 50, because it's getting added to
03:18the i which was zero.
03:20In fact, if I were to have int y = 50 and then pass the y instead, same thing
03:28happens, it's making a copy, it's not directly using y.
03:32So if I run that, that's what happens.
03:35Now instead if I wanted to actually change the value of x here, x = 100, and if
03:44we come out here and also print the value of y, you'll see that y doesn't get
03:50changed, and that's because this is passing the value, it's not actually passing
03:55a reference to the variable. So the function has no way of affecting this y.
03:59So if run this you'll see y is still 50.
04:02If I want to be able to affect y, then what I have to do is I have to pass a pointer.
04:08So I can pass y like this, that's the address of operator if you'll remember,
04:14and then this one has become a pointer.
04:16Then I have to use it as a pointer in all of these places.
04:21So now my parameter is a pointer and what I'm passing it is the address of a variable.
04:28So now I'm actually able to affect this variable, and when I assign a 100 to it
04:32I'm assigning it through the pointer, so I'm dereferencing the pointer and so
04:35that has the address of his variable and so it's actually going to affect this
04:39variable and then y will be a 100.
04:41So we'll save this and run it, and you see that the variable actually affect our
04:46variable and so that's called pass by reference as opposed to pass by value.
04:50C is always pass by value, and I'm still passing a value, it's just the value is now a pointer.
04:56And so that's how I'm able to affect variables outside the function, and that's
05:00how I'm able to implement call by reference instead of call by value.
05:04So let's put this back to how we had it before, which was call by value, save
05:08that and run it and see that it's working the way that we expected.
05:12Now if were to move this function to after main, if i try to compile it and run
05:18it, I get a warning here, implicit declaration of func.
05:22And so the compiler was able to discern it, but it's really wrong, and you don't
05:26want to do it this way.
05:28In this case the compiler was able to tolerate it, but many compilers will
05:33simply give you an error.
05:34In order to properly use this function when it's used before its definition is
05:39to have a declaration.
05:41So I take the function signature and the function signature is the return value,
05:46the name and any parameters just their types.
05:50The actual variable name is not part of the function signature.
05:54Now it's common to include the name, because it often gives a hint of how it's
05:59used and so we'll leave that in there.
06:01Now you'll see this warning will go away when we save it and run it, so now that
06:05warning goes away, because we've told the compiler exactly what that function
06:08looks like, and that it will be defined later.
06:11What's really common is that the function itself is actually in a separate
06:16translation unit, it's in a separate source file, and it's linked in later.
06:21And what's even more common is instead of having this function signature here to
06:25have it in a header file.
06:28So I am going to uncomment this, and I am going to take this func.h, and I'm
06:33going to copy it and paste it into our Working project, and we'll open it up, we
06:37see there we have a declaration of the function, that's actually not how we have
06:41it defined it right now.
06:42So I'm going to copy this and paste it in there, and there is our declaration of
06:47the function signature.
06:48And now that's included in this header file, and this will compile and run
06:53without error or warning.
06:54So that's the common way to do this, whatever functions you are using in a
06:58particular source file to have their function signatures in a header file.
07:02And what that allows me to do is if I have a set of functions, I can have all of
07:07those in one source file, and I can have all of their function signatures in the
07:11header file, and I can compile that as a separate unit.
07:14And then when I want to use that and link to it, all of those function
07:19signatures are in the header file, and I can simply include that header file
07:24in my main program, and link to the code and everything will work the way that I want it to.
07:30So this is really the common way to do this, this is how libraries are created.
07:34In fact, this is why we include <stdio.h> at the beginning of all our programs.
07:40Because functions like printf() and puts() that we use a lot are defined in <stdio.h>.
07:46And then the actual code is linked in with our program as we build it.
07:50So that's how our standard libraries work, and that's really how all
07:53libraries work in C. So the function is the basic unit of code in C.
07:58Everything starts from the main function and all code must be in function blocks.
08:03Understanding functions is a fundamental skill for C and C++ programming.
08:06Now let's delete our working files and run Clean to get set up for the next lesson.
Collapse this transcript
Branching with goto, break, and continue
00:00C provides three basic branching controls, goto, break, and continue.
00:06These controls should be used with care.
00:08Under many circumstances they can be very difficult to debug, and they are use
00:13often indicates flawed logic.
00:15On the other hand, especially with break and continue, there are circumstances
00:19when they are entirely appropriate and expected. Let's start with goto.
00:24Let's make a working copy of goto.c, and we'll paste it in the Working project
00:29and double-click on it to open it up.
00:32Here you see we have a label which looks like that, it's a token with a colon
00:37after it, and it's the only thing on a line it's not a statement, it's simply a label.
00:42And we have a goto statement which targets that label.
00:46It says goto and then the name of the label, which in this case is target.
00:50So what will happen here is the goto statement is basically an unconditional branch.
00:56When the execution encounters the goto statement, it'll simply skip to the target.
01:02So this printf will never be executed, we'll get Before the goto, and we'll get
01:07After the target but we will not get After the goto.
01:09So let's go ahead and compile and run this, and you see Before the goto
01:13and After the target. So that's simple.
01:16Like I said, you're not going to need it very often, you rarely actually going
01:20to need it, when you do need it, you're going to think twice, three times, and
01:24if you find that your logic is actually sound, and this goto is the best way
01:29to do it, then you'll comment it really good, and you'll use it, and that's how it works.
01:34The break statement is used in loops.
01:36It will branch to the end of the current loop or switch control, and execution
01:41will continue after the loop, it will not continue the loop.
01:45So let's take a look at this.
01:47We'll go ahead and delete these lines, and we'll create a simple for loop.
01:51So there is our simple for loop, and it will print ten lines, and we'll count 0 to 9.
01:56So we'll go ahead and save that and run it, and you see there are our ten lines,
02:01I'm using my little scroll wheel here, and that's what they look like.
02:05Now if we want to we could break out of this, and we could say if(i == 5) break;
02:12and so now it will only print 1 through 4, and when it sees 5 it'll actually end
02:16the loop prematurely.
02:17So we'll save this and run it, and there we are. 0, 1, 2, 3, 4, and when it gets to 5, it breaks.
02:25Break is most commonly used in switch controls, and you'll see a good example of
02:30that in the lesson on switch in this chapter.
02:32On the other hand if we use continue, instead of break, what continue does is it
02:38goes back to the top of the control.
02:41It will skip everything after the continue in the block and go back to the
02:45top of the control.
02:47So in this case what it'll do is it'll print 0, 1, 2, 3, 4, 6, 7, 8, 9.
02:52Because when it sees 5, it'll skip everything after the continue which is this
02:57printf, the body of the loop, and it'll go ahead and continue with the loop.
03:01So we'll save that and run it, and there you see we have it 1, 2, 3, 4, 6, 7, 8, 9.
03:07So it's just skipping that one iteration, but it continues with the loop.
03:12So these branching controls are an important part of the C language, but they
03:16should really, rarely be used.
03:18Most of the time they're unnecessary and even problematic, but when you need
03:22them it's important to know how to use them.
03:25So let's delete the Working file and run Clean and get set up for the next lesson.
Collapse this transcript
4. The C Preprocessor
About the C preprocessor
00:00The C Preprocessor provides a number of essential capabilities for both the
00:04C and C++ languages. Let's take a quick look at what it does.
00:10In order for your source code to become an executable program it first needs to be compiled.
00:15But what we need to realize is that this Compiler is really several things in
00:21one package, preprocessor, compiler, optimizer and linker and often more.
00:27Each of these steps is separate and distinct even though they're often
00:30invoked with one command.
00:31For now the step we're interested in is the preprocessor.
00:35One of the more common uses for the preprocessor is file inclusion.
00:41When you use the #include directive your source file be treated as if the
00:45entire contents of the file you name here were included in place of the include directive.
00:50Then this combine file called a translation unit is passed to the compiler.
00:57A preprocessor macro works like a really smart alias.
01:00For example, after this declaration and use of the word CONSTANT in all caps
01:06will be replaced by the digit 1.
01:08No math is performed, this is really just a string substitution in the source file.
01:13In this second example we have a macro with parameters.
01:17Those parameters maybe used in the replacement.
01:19This construct is common in C, less so in C++ where templates are often used instead.
01:27Conditional processing allows you to compile parts of your code only if certain
01:30conditions are true.
01:32In this common example, the contents of a header file are only processed once.
01:37This technique is called an include guard.
01:39Keep in mind that this step happens before compilation, so you may only use
01:44constants and preprocessor macros for your conditions.
01:49Pragmas maybe used to define implementation specific behaviors for the compiler.
01:54Most common uses of pragmas relate to supporting certain compilers and computing architectures.
02:00Be careful using pragmas, they are typically not portable.
02:04The C preprocessor is an essential part of the compiler toolchain and
02:08understanding how it works and what it can be used for is an essential part of learning C and C++.
Collapse this transcript
Defining constants
00:00One common use for the preprocessor is to define constants.
00:03In fact, the preprocessor cannot define constants or any other C language
00:08object, but it does have a feature that's commonly used for this purpose.
00:11Let's start by make a working copy of working.c out of our Chap04 folder in
00:16the exercise files.
00:17I'll just Paste this into our Working Project and open it up in the editor.
00:22Now if I come down here and use the define directive #define, and I'll give it a
00:29symbol ONE and a value of 1.
00:32Now what this does is during the preprocessor stage before anything gets passed
00:36the Compiler, every time it sees the text string with the capital letters ONE it
00:43replaces that was the digit 1.
00:46And that's literally what it does.
00:47So this is not actually a constant, there is no symbol in the symbol table, it
00:51doesn't have a type, it is really just a string substitution.
00:56You'll also notice that there is no semicolon at the end of the line.
01:00This is the Preprocessor, this is not C, it's actually not the C language.
01:04It's a separate language that's used by the C Preprocessor and the same C
01:08preprocessor could be used with any language and actually often is.
01:12In fact, what this is is a very, very simple version of a preprocessor macro,
01:16and we'll talk about macros in more detail later in this chapter.
01:19But really what this is is a very, very simple form of a macro.
01:24So if I come down here in printf, and I say, The constant is, and I'll put in a
01:32%d, and we'll put ONE over here.
01:35What will happen when the preprocessor runs through the file, it'll actually
01:39take this string, letters O-N-E, and it'll replace them with a literal number 1,
01:46which is a literal token it's not actually a constant.
01:50So if I do this and go ahead and Compile and Run it you'll see that we'll
01:55get, The constant is 1.
01:56And now if I come up here, and I change this and make it a string, and it says
02:02One like that and Save that and Run it, we'll get a syntax error because you
02:08notice the warning here, format expects an argument of type int but got a type
02:12character pointer, and down here we get the address of that character pointer
02:16because it's really trying to do what it can.
02:19So this is not typed, this is really just a string substitution.
02:23On the other hand, if we change this to s in the printf and save it and Run it,
02:29it works exactly as we expect.
02:32Because this is a simple text substitution sometimes there can be unintended
02:37consequences and side effects, and so one thing that's done to mitigate that is
02:42it's very common to take all of your macro constant things like this and enclose
02:47them in parentheses.
02:48Again, in this case it'll work just fine, and there are some cases where the
02:54macro substitution can create ambiguous syntax, and this tends to mitigate that problem.
03:01So the problems with this approach, it has no type, you can't use it with a
03:06pointer, it has no symbol in the Symbol table, it's really not a constant it's
03:10simply a text substitution.
03:12Alternatives are instead of using a define, in many cases you can actually use
03:18a constant variable.
03:19You can say something like const int iOne = and give it a 1, and now that's an
03:26actual variable, and this symbol ONE no longer exist.
03:29So if I say, iOne and make this an int, now what we've is an actual constant,
03:36and it's actually part of the language, and it's in the Symbol Table.
03:39If I go ahead and I Run it I can run it. I can create a pointer and take its address.
03:48And then I can do this, and that works, Save and Run.
03:52We're getting the result that we expect.
03:54We have a little warning here that the initialization discards the constant qualifier.
03:59So this should probably be a constant integer pointer, of course, that
04:04constant go before or after.
04:06I Save and Run, and we see that warning goes away.
04:10So this is actually strongly typed.
04:12As you saw that we got a warning where the type was just a little bit off.
04:16Just like any variable in C it's in allocated memory.
04:19We can take a pointer to it;
04:20it's in the Symbol table so debugging becomes easier.
04:24It cannot be used in C where a literal constant is required as with the
04:29switch and case statement. But in C++ you actually can do that.
04:33So Preprocessor macros are often used to define constants in C.
04:37It's important to realize that in fact they are not constants, rather they are
04:42simple text replacements.
04:43So often better to use variables declared with the const keyword where
04:47that's actually possible.
04:48So now let's delete the Working file and run Clean to get ready for the next lesson.
Collapse this transcript
Including files
00:00You'll typically have a list of #include directives at the top of each source file.
00:04This is probably the most common or at least the most visible use of the preprocessor.
00:08Let's start with a working copy of our working.c, copy and paste that into the
00:14Working folder, and double- click on it to open it up here.
00:18You'll notice at the top there, I have this #include<stdio.h>, the #include
00:25directive, that's the pound sign, and word include is used to include a header
00:30file in a source file.
00:31The preprocessor replaces the # include directive with the contents of the
00:35included header file, then takes that combined file and passes that onto the compiler.
00:40Multiple include directives are allowed and are in fact common.
00:44All the #include directives are processed, including those nested within other
00:48included files and they are all combined into one piece, and that one piece is
00:52often called a translation unit.
00:55There are in fact two basic forms of the #include directive.
00:59One form using the angle brackets, as we see here is used at the top of each
01:04of our working files. It says #include<stdio.h>.
01:08This form with the angle brackets instructs the preprocessor to search for
01:12the included file using a set of predefined locations that are defined as
01:16part of the implementation.
01:18This form is typically used for system-level headers that are common to
01:22different projects in source files. The other form, using double-quote marks.
01:26I'm going to go ahead and type one here.
01:28This form is commonly used for header files that are specific to a given
01:32project or a source file.
01:33This does not search for files in the system header locations.
01:37So, in order to use this, I have to take this preproc.h, and I'm going to copy
01:42and paste that into our Working project.
01:44Now, you notice that the little question mark goes away, and we can actually
01:48save this and run it.
01:50If we look in that header file, we'll see it defines our little constants here.
01:55So I can take this one, and I am just going to copy that symbol and come over
02:00here in Working, and I am going to say printf("the constant is %d, put in a new
02:09line, because that's always a friendly thing to do, and paste in my symbol.
02:12That symbol is defined in that include file, and so when I save this, and run
02:19it, it finds the constant just fine because that is defined in this include
02:23file, and this is run as if that entire include file was just typed right there.
02:28The #include directive is an essential part of C and C++ programming.
02:32While it's certainly not required, virtually every source file we use at
02:37least one #include directive and often more.
02:39Even if it's just for your standard library headers.
02:41Now, let's delete the working files and run Clean to get set up for the next lesson.
Collapse this transcript
Exploring conditional compilation
00:00The C preprocessor provides a number of directives for conditional compilation.
00:05There you see a list of them.
00:07#if, #ifdef, #ifndef--which is the negative of #ifdef--#else, #elif, and #endif.
00:15There's also this other version of # ifdef called #if defined which some
00:19people prefer to use. Let's take a look at how this works.
00:23Let me take a copy of conditional.c and conditional.h, and copy and paste those
00:29into the Working project, and open them up in the editor.
00:32Here is conditional.h, and you'll notice in here that it defines the number 2,
00:37and it has an #ifdef for a symbol called FOO which we know is not defined, and
00:42then it redefines the number to be 47 inside of the #ifdef and #endif.
00:49You'll notice over here that we don't have that symbol defined.
00:52So, when I compile and run this, I get a number 2 which is the number that's
00:57outside of the #ifdef.
00:58Now, if I go ahead in here, and I define the symbol foo, #define FOO, you notice
01:06it really doesn't change anything.
01:07I will compile and run this, and we still get the number 2.
01:10The reason for that is that my symbol is defined after the include, and you
01:14remember that the include, all it does is it includes everything right there in
01:18line, and I've got that symbol defined afterwards, and so at this point, that
01:21symbol is not actually defined.
01:23So, if I move my include, and put it down here after the #define, and I run
01:31this, Compile and Run, we get the number 47.
01:34You notice we have a little warning symbol there on the conditional.h, and
01:38that's because what we have is a number redefined.
01:42So, of course, it's actually legal, it's really just a warning.
01:45But there is a better way to do this.
01:48We can use #else, and I can take this # define NUMBER 2, and I can put it down
01:54here, and in between, I can put an #else.
01:56Now, what happens is when I compile and run this, the warning goes away because
02:05only one of these definitions is going to be in effect at a time, and if I
02:11remove this definition, comment that out, and Save and Run, now the number is 2
02:16again, exactly how we expect.
02:19You notice that Eclipse does a nice job here of graying out the parts that are
02:22not in effect and leaving the parts that are in effect ungrayed.
02:26Instead of #ifdef, you can also use #if defined, and put this symbol in
02:32parentheses, and it's just another syntax for the same thing.
02:36If we save and run this, we get exactly the same result.
02:40So, the C preprocessor provides conditional compilation directives.
02:43They're commonly used for separate versions of code, for debug, or for
02:48supporting different target environments.
02:49Let's go ahead and delete our working copies and run Clean to get set up for the next lesson.
Collapse this transcript
Defining macros
00:00The C preprocessor provides a powerful and flexible macro system, let's take a
00:05look at how this works.
00:07Take a working copy of working.c and paste it into our Working project and open it up here.
00:14Now we've seen the macros that look like this.
00:19And that's very common and its use to provide something that looks like a constant.
00:24What we're going to this time is something that is a little bit more
00:28complicated, we're going to define macro we will just call MACRO1, and this
00:32macro is going to have parameters. And so we'll just call those parameters a and b.
00:37And the result that it'll simply a * b.
00:41And so if I come down here into the main part of the program, and I define an
00:46integer so I will call an integer this, and let's say that its 5, and I'll call
00:52an integer that and give it a 7.
00:54And then in my printf I'll just say this is %d that is %d and result is %d.
01:06And let's put this on the next line for clarity here, and I'll say this, and that
01:10and MACRO1 and pass it this, and that.
01:17So, remember in C that white space is mostly non-consequential so putting this
01:22in on another line doesn't change how it works.
01:25Just doing that so that it's easier for us to see on the screen here.
01:29And so I'll save this, and I'll run it and what do we except to have happened,
01:33we'll get a 5, and we'll get a 7, and then we'll get 7 times 5 which is 35.
01:38And there we go, so we got this, we got that, and we got 35.
01:42And so you can obviously do things that are much more complicated with a macro
01:46like this, it's not uncommon to do something like this.
01:49If a is greater than b, then result would be an a otherwise the result will be a b.
01:55And so it'll simply give us the greater of them and so now the result will be a
02:007, we will compile and run that, and we get a 7.
02:03And if we change this around to a less than b then our result will be a 5.
02:09So, as we use these macros again it's important to think about the possibilities
02:14of side effects, so its really common to go ahead and quite everything in
02:18parentheses() especially when you got operators here now you are going to be
02:22dealing with Operator Precedence.
02:23You might be doing something like this times that in the beginning macro, and
02:28then you have to really think, well what is the result of that going to be?
02:32I don't know what's the precedence is it going to evaluate the asterisk first is
02:37it going to evaluate the less than sign first, I'd have to look upon my handy
02:41dandy operator precedence chart to predict it, and I'd just run it.
02:44But if I'd up just put these in parentheses put the a in parentheses and the b
02:48in parentheses and the next a in parentheses, and now the next b in parentheses.
02:54And then I'll often put the entire thing in parentheses which I've done here,
02:58you can see I've got see this parentheses on the outside.
03:01And now when I run it I know that you have got a less than so I'll get that,
03:06I'll get the 7, and if I run that I get a 7, and if change this to a greater
03:11than I'll get a 35, save and run it.
03:14So it is important to think about the side effects when you're using macros you
03:18need to really think it through, The side effects can be very-unexpected and dangerous.
03:23So while the use of function like MACROS is common in C and in fact the
03:27preprocessor was even designed to do this.
03:30For many uses C++ templates are a superior solution.
03:34So if C++ is an available option, templates are generally recommended over parameterized MACROS.
03:40Now let's delete the working files and run Clean to get to set up for the next lesson.
Collapse this transcript
Macro caveats
00:00A common problem with preprocessor macros is the possibility of unintended results.
00:05A common cause of problems is parameters being evaluated more than once.
00:10Let's take a look at how this can happen.
00:12Make a working copy of working.c and paste it here into our Working Project and open it up.
00:18And now we're going to do little bit of coding.
00:20We'll start by creating a function called increment().
00:23All this function does is increment a value.
00:27So we'll start by defining a static int, and then we're going to increment it,
00:32and we'll increment it by 5 and return it.
00:36So every time this function is called it will return 5 more than the last
00:40time, starting with 47.
00:41I'm going to go ahead and put in a print statement so that we can see what's happening.
00:47So printf(increment returns %d, semicolon there, and so now we have a print
00:55statement every time increment gets called, and it will printout, and it's
00:59getting called and what it's returning.
01:00Now let's define a macro and our macro is going to be a very common one, called
01:05MAX, and it's simply returns the maximum value between two parameters.
01:09So we've got a and b, and it returns, a > b, it'll return a and otherwise it'll return b.
01:16And I'm going to go ahead and put these in parenthesis, because that's always a
01:20good idea to do, a in parenthesis, and b in parenthesis. There we go.
01:27So that's our macro, and now we'll come down here, and we'll use it, and this is
01:31where the fun begins. int x = 50; so we've got a number there.
01:37I'm going to change this printf out, we'll say, max of %d and %d is %d. So the
01:47parameters are, I'll go ahead and put this on a separate line just for clarity,
01:51x and increment, an increment() call, and then we're going to say, MAX(x and the increment() call.
02:02It seems to think I've got a typo here someplace.
02:04Let's see what happens when I copy and paste it, because I want two of them in here anyway. Ah!
02:09That's what's it is I'm missing the Comma.
02:12Stare at these things long enough, and it usually jumps out at you.
02:15Okay, so I'm going to save this and run it, and we're going to get some
02:18interesting results here.
02:20So increment is getting called twice here, before the first result, and that's
02:25what we expect because we have it once there, and we have it once there.
02:29Now function parameters actually evaluate right to left, so this one is actually
02:33getting called before this one.
02:35So the first time through it returns a 47 which is what we expect and so that
02:41would be this first evaluation, it would be this b here.
02:45And because 50 is greater than 47 that doesn't get called again, instead it returns 50.
02:51And the 50 actually gets evaluated twice, but that doesn't have any impact.
02:56And so then it calls increment() again, and it says here, increment returns 52,
03:01and that's the one that's getting displayed here in the printf.
03:05So the max of 50 and 52 is 50, which is not exactly correct, but it's the result
03:11we get, because the first time through that evaluation of a and b here was
03:16actually 47, it wasn't 52.
03:19And 47 is less than 50 and so the max of 50 and 47 is 50, but it's displaying 52
03:25because it's evaluating that a second time.
03:28So if that's not confusing enough, let's look what happens the next time through.
03:32Now the next time through, again it evaluates MAX first, and it compares x to 57.
03:42And it says oh 57 is greater than 50 and so it returns 62 because it goes and
03:49evaluates increment() again.
03:52So the first evaluation is here and the second evaluation is there because this
03:56condition was satisfied and b is the one that's being called, and so increment
04:01gets called twice, and it returns a 62.
04:04And yet it gets evaluated even a third time for the printf and so the printf
04:11comes out, and it says max of 50 and 67 is 62, which is completely wacky.
04:19So you can see that we have this unintended consequence, because increment() is
04:23getting evaluated all over the place and its results are getting all mixed up.
04:28If we actually trace through we can see what's happening and why, but it can be
04:32really confusing and especially if your macros are anymore involved than this.
04:37So function like macros are a powerful tool, but like many powerful tools you
04:41need to be conscious of how they work.
04:43If you're using Standard C, and you don't have C++ templates or Inline functions
04:48available, then just proceed with care, you'll need to be conscious of how your
04:52macros are evaluated.
04:53Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with line continuation using the backslash
00:00Line continuation is a convenient function of the Preprocessor.
00:05This is something you may not need very often, but when you do need it, it's
00:08good to know it's there.
00:09Let's start with a working copy of working.cout of our Chap04 folder here, and
00:14paste it into our Working Project and open it up in the editor.
00:18So the interesting thing about this is that it works everywhere.
00:21It doesn't work just in Preprocessor directives.
00:24If I put in a Backslash here right in the middle of the string and press the
00:28Enter key, well of course, Eclipse is going to try and give me what it thinks I
00:33want as opposed to what I actually want.
00:35So I need to come and clean this up a little bit.
00:37But you see that Backslash followed by the new line, and I can't select the new
00:41line there, but that Backslash followed by the new line is the line continuation sequence.
00:48And when I run this I'm going to go ahead and Save it and Run it, and I'm
00:53just going to hit this Run in the Background button, and you'll see that it
00:56says Hello, World! all in one line.
00:59In fact, if I were to move this over there in the middle of the word Hello and
01:06save it and run it, it still puts it all in one line.
01:09And that's because this is what's called the line continuation sequence.
01:12So Backslash followed by new line will be completely folded out and ignored
01:18by the Preprocessor. The Preprocessor will reassemble it.
01:22The real purpose for this is when you're defining Macros if your Macros are
01:27very long, and you want to preprint for your own purposes, a macro needs to
01:32actually be all on one line. This is not a valid macro.
01:37The macro ends at the end of the line, there's no other indication of where a
01:42macro ends, that's just a quirk of the Preprocessor and how it works.
01:46The way that you get around this is with this line continuation.
01:49So I'm going to go ahead and I'm going to define a fairly complicated MACRO here.
01:53This is a common SWAP function that you'll see now and then.
01:57And it actually uses a do loop and the reason that it uses this do loop is so
02:02that it can have a block.
02:03And so it doesn't actually do any looping, it just does that, and we use the
02:08line continuation character to put it all in one line so that the preprocessor
02:13knows what's going on.
02:14And I can put my lines inside of here, I can say, a ^= b;
02:21and then another line continuation character out there, and I'm just going to
02:25copy this line three times because this is the way this macro works.
02:30And so now I've got this MACRO defined with these line continuation characters,
02:34and it's still fairly readable.
02:36And so I can come in here, and I can say, int this = 7;
02:43and int that = 9;, and I can printf(" this is %d, and that is %d with this, and
02:54that, and I'm going to make two copies of that and in between them I'm going
02:58to run the SWAP Macro.
02:59Now when I save this and run it we'll see this is 7, and that is 9, and this
03:04is 9, and that is 7.
03:06So it's a common little trick, it only works with integers, but it's made
03:11readable by using the line continuation sequence.
03:15So the preprocessor provides a useful line continuation feature using the
03:19Backslash new line combination.
03:21This is really convenient for making complex Macros more readable.
03:25Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Including files only once
00:00When a header file is included by other header files, there is a possibility
00:04that it can be included more than once, and this can create errors.
00:08Let's take a look at a simple example.
00:10I am going to go ahead and copy includeA and includeB and working.c.
00:18Make a copy of those and paste them into our Working project.
00:22And I'm just going to go ahead and open up all three of them.
00:28And in includeB, I'm going to go ahead and I'm going to type #include
00:35"includeA.h" and includeA does not include includeB.
00:41And then if I'm going to come in here into working.c, and I'm going to include
00:45both of them, #include " includeA.h" and "includeB.h".
00:54I'll save that, and when I go ahead and build it, you'll notice that I get errors.
01:02And here in includeA, let's see it's got a little x there, I'll select that,
01:06and I'll hover my mouse, and it says - originally defined here - redefinition
01:10of 'struct structA'.
01:12And the reason for that is that I've included includeA here.
01:16And so that structA is getting defined, and then I've included includeA here in
01:23includeB which also gets included here. So includeA is getting included twice.
01:29So the typical solution for this is what's called an include guard, and it looks like this.
01:34Pound if defined, #ifdef. And I'll use an underscore here, and I'll say
01:40INCLUDE_A then I'll go ahead and define INCLUDE_A, actually this should be an
01:47ifndef, if not defined, I'm going to say INCLUDE_A and then down here at end I'm
01:54going to put #endif, and I'll put in a comment. All right?
01:59And now, the first time through INCLUDE_A is not defined and so all of this
02:06will get evaluated, and it'll define INCLUDE_A so that the next time through
02:11that doesn't happen.
02:12So now when I compile and run, you see we don't have any errors.
02:17Of course, we can do the same thing in includeB which would be nice to do, and
02:24we'll call this INCLUDE_B instead, but this is not really where we're having the problem.
02:31And we save that and run it, and it all works just fine.
02:35So that's called include guard, and you will see this pattern very often in
02:39header files actually you'll see it in a lot of the header files in this course.
02:43And if you were to look at your standard header files which I really suggest
02:47that you do, they're often very educational and very cryptic.
02:50You'll see this pattern a lot in them.
02:52Many modern compilers have a nonstandard feature called #pragma once, and if I
02:59take this include guard out of here and instead at the top, I say #pragma once
03:05like that and save and compile, you'll see there it works just fine.
03:10And you are certainly welcome to use this.
03:11It's supported by GCC, it's supported by Microsoft C, it's supported by Apple's
03:17LLVM, it's supported by all of the major compilers.
03:21But it is nonstandard, and if you do use it, then you need to realize that there
03:25may be some environments where your code won't compile yet.
03:30And it was actually buggy in some earlier versions of GCC which may still be
03:34deployed on a lot of computers.
03:36So my recommendation is always to use standard C where you can because it's
03:44going to be more portable, and it's going to be better supported.
03:47So the include guard is very well supported.
03:49It's something that you can type at once or you can cut and paste at once, and it's done.
03:54So it's not really that much of a burden to include it.
03:57But if you prefer, the #pragma once trick also works in most circumstances.
04:02So this is a common problem with a common solution.
04:04You'll see the include guard solution most often although the #pragma
04:08once solution is more succinct and although it's not standardized, it is widely supported.
04:14Now let's delete our working files and run Clean to get set up for the next lesson.
Collapse this transcript
5. Data Types
About the data types
00:00C and C++ are strongly typed languages. This means that every value has a specific type.
00:07The meaning of a value is determined by its type.
00:10A data type consists both the size and the interpretation of a value.
00:15For example, the int type means a natural machine-sized integer value that would
00:19be 32 bits for a 32-bit machine and unsigned int means the same size integer
00:24with no bit reserved for sign.
00:27Built-in types for C and C++ include integer types for representing integer
00:32numerical values, floating point types for representing real numerical values
00:38and the bool type for representing boolean values, true and false.
00:42This type is available on C++, but not in C.
00:45C++ also provides constants called true and false and beginning with C99, C
00:52provides a built-in type _Bool and a standard Header, <stdbool.h> which uses
00:59macros to provide bool true and false.
01:02This is designed to mimic the behavior of C++'s bool type without breaking
01:06existing code that has traditionally provided this capability with macros.
01:10C and C++ also provide some compound types, including arrays.
01:15An array is a contiguous sequential set of objects of the same type.
01:19C and C++ arrays are very powerful, flexible and have very low overhead.
01:24They are also the basis of C strings and the C++ STL container types.
01:31A structure is a sequential set of objects of various types.
01:34A structure may contain scalars, arrays and even other structures and classes.
01:41C++ classes are based on C structures and technically a class is a structure
01:45that defaults to private membership.
01:47In practice a class is a structure that contains function members as well as data members.
01:51We'll discuss these distinctions later in the course.
01:54Classes are available in C++ , they're not available in C.
01:57A union is a set of overlapping object types.
02:02This allows a single object to hold objects of different types of different
02:05times in the same space.
02:08A pointer is a reference to an object of a given type.
02:11The pointer itself typically holds the address of the object it points to.
02:15Pointers are strongly typed in C and C++.
02:18The type of a pointer is used as the type when it's dereferenced, and it's
02:23also used to determine the size of increments, decrements and arithmetic
02:26operations on the pointer.
02:27C++ also provides a reference type. This is not available in C.
02:33A reference is very much like a pointer, but with different semantics.
02:36The major distinctions between pointers and references are that references are immutable.
02:40Once they're defined, they can not be changed to refer to a different object.
02:44And references are accessed as aliases.
02:47A reference is accessed without any syntactic indication that it's a reference
02:52and not directly a variable. This allows for silent side effects.
02:56We'll discuss the C++ reference type in more detail later in this chapter.
03:01Note that neither C nor C++ defines a special string type, but both languages
03:06have provisions for handling strings of characters.
03:08We'll cover both types of strings in this chapter.
03:10C and C++ provide a number of fundamental data types that may be used or
03:16extended for many purposes.
03:17Rest of this chapter we'll cover these types in greater detail.
Collapse this transcript
Introducing integer types
00:00The integer types are simple fundamental data types for representing integer values.
00:04Whole numbers with no fractional part.
00:07The integer types include char, int, short int, long int, and long long int.
00:13Some people pronounce char as chaar.
00:15These are all available in both signed and unsigned versions.
00:19The sizes of these types will vary by compiler and processor.
00:22The char type will typically be the minimum size to contain a character, on most
00:27modern systems that's 8 bits. The char type may be signed or unsigned.
00:32All the other integer types are signed unless modified with the unsigned keyword.
00:37The short int type is the smallest natural size of an integer for the target processor.
00:42It may be the same as int, it may be the same as char.
00:45On most modern systems, it's 16 bits.
00:49The int type is the natural size of an integer for the target processor, and on
00:52most modern desktop systems, it's 32 bits.
00:56Long int is typically double the size of an int and long long int is either
01:00double the size of a long int or the same size as a long int.
01:04Let's take a look at these in code. Make a working copy of integer-types.cpp.
01:10I'm going to paste that into the Working project and open it up in the editor here.
01:15Let's just maximize this so that you can see what it looks like.
01:19Here we are declaring variables in each of the five integer types, they're on
01:23lines 6 through 10, and then on lines 12 through 16, we're displaying the size
01:29of these using the sizeof() operator.
01:31Then starting on line 18, we play around with the character a little bit to
01:35determine if it's signed or unsigned. Let's take a look at how this works.
01:40Bring this back to size, and we'll compile and run it.
01:43You see there's our sizes.
01:46The size returned by sizeof() is in bytes, so char is 1 byte, short int is 2
01:52bytes, and a byte is 8 bit.
01:53So, short int is 16 bits, and int is 4 bytes, long int is 8 bytes, and long long
02:00int are also 8 bytes.
02:03We can see from this that char is signed on this system and the way we would
02:07determine that is by initializing it with a value of 127.
02:10127 is the largest value that you can represent in 7 bits.
02:16And so if we increment that, we know that it will set the sign bit, and it
02:20will turn into a negative number if char is signed, and indeed that's what
02:24happens, so char is signed.
02:26If we try the same thing with an unsigned char, and I just type in the word
02:30unsigned, you'll see, save that, and run it, that when we increment it, it
02:35becomes 128 instead of -128. So go ahead and put that back, and run it again.
02:42Sometimes you get this Launching Working, you can just say always run in
02:46background or do what I do, just press the Run in Background button.
02:50And there we get the -128.
02:53So, literal numbers like this are actually of type int, and in this case, it's
02:58getting adjusted to the size of the smaller space for the character, and that's
03:03normal behavior for C and C++.
03:07So if I wanted to give a value to the variable i which is int, I could say
03:1112345, and that would put the value of 12345 in i.
03:18If I wanted to initialize a long int as an li, I could still use an int to initialize it.
03:24But if I wanted to initialize a little larger value, I'll put a L at the end of
03:28it, and that allows me to type a literal value that's a long int.
03:32Two Ls will make it long, long and a U will make it unsigned.
03:37So, if I just do that, it's an unsigned int.
03:39If I do that, it's unsigned long, and if I do that, it's unsigned long, long.
03:45So, I'm going to save that and go ahead and display it.
03:53Save that and run it, and you can see we're getting the value there in the long int.
03:59So, C and C++ provide a full selection of integer types in many sizes both
04:04signed and unsigned.
04:05Now, let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Understanding floating-point types
00:00C and C++ provide a few basic floating point types.
00:05Let's go ahead and open floating point types.cpp.
00:08I'm going to make a working copy of that, and paste it into our Working
00:13project, and go ahead and open that up, and we'll double-click on this so we
00:17can see the whole thing.
00:18C and C++ provide these basic floating point types.
00:23We have float, we have double, and we have long double.
00:27You'll notice that we have some cout statements here which are listing simply
00:32the size in bytes using the sizeof() operator of each of these different types.
00:37So let's go ahead and run this.
00:39I'm going to double-click on this to bring it back to our regular size, and I'll
00:44go ahead and click the green Compile and Run button.
00:48You see here the size of float is 4, the size of double float is 8, and the size
00:53of long double float is 16, and those sizes are in bytes.
00:59So for bits, you would need to multiply that by 8, and so the float size is 32
01:05bits which has a precision of about 7 digits.
01:09So while it may be possible to represent some very large or some very small
01:12numbers using floating point types, the precision is always limited by the size
01:17of the variable itself.
01:19The number of bits that are available to represent the floating point number.
01:23So a 32 bit float is going to have a precision of about 7 digits, and a 64 bit
01:29float which is the double is going to have a precision of about 16 digits.
01:35The long double is a standard IEEE size which has about 80 bits, at least on GCC it is.
01:43On some other platforms, it's simply an alias for double, like for instance in
01:48Visual C++ at least the last time I checked, long double was the same as double.
01:53The thing that you need to remember about these types is that well, again, you
01:57may be able to represent some very large and very small numbers.
02:00The precision is sacrificed.
02:03So, for example, if I come down here, and I will initialize and use some of
02:07these, let's say f = 0.1, then I go ahead and I add to it.
02:12I will say f += 0.1+0.1. Now, we would expect the value to be 0.3, and I'll go
02:21ahead and I'll print that out, "f is" << f << endl;, and if we go ahead and
02:31compile and run this, you will see it says f is 0.3.
02:35Well, here's the interesting thing about this.
02:37If I now say if(f == 0.3), and that's the literal constant 0.3, then I'll go
02:45ahead and I'll say cout << "yes" <<, and if I say else cout << "No" <<, now
02:57given that it says f is 0.3, we would expect to get a yes here, right?
03:02And given that I asked that question, or I maybe expecting something else, the answer is No.
03:07Even though it's displaying a 0.3, all the way out to the amount of precision
03:13that it has, it is not quite exactly equal to 0.3.
03:17And we can print it out and show you how many digits it is but that's not really important.
03:22This is one of the lower precision versions of this that we have.
03:25What's important here is for you to know that if you're doing something that
03:28requires actual precision, something like accounting, it requires a specific
03:32number of precision, requires that rounding be handled in a specific way.
03:37And you don't want to be using floating point numbers.
03:39You want to be using one of the integer types.
03:42So, C and C++ provide a few standard floating point types, and while it's
03:46possible to represent very large, and very small numbers with these types, it is
03:50at the expense of accuracy, and you need to be aware of that.
03:52Precision is important, as in the case of accounting, you want to use an
03:56integer data type instead.
03:58So, let's go ahead and delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with characters and strings
00:00The C String is an array of characters terminated with a null value.
00:04This is sometimes referred to as a C String or a null terminated string to
00:08distinguish it from object oriented string types.
00:11The character type is an integer type of the size suitable for holding a single
00:15character which is 8 bits on most common systems.
00:19A string in C is an array of these characters terminated with the 0 value.
00:25So this six character string takes up seven values in the array.
00:29Let's take a look at this in code.
00:32Make a working copy of c-strings.cpp, and we'll paste it here into our Working
00:38project, and I'll double-click on that and open it in the editor.
00:42So here we have that same string six characters long, and this is actually
00:46taking up seven bytes inside of the array.
00:49see, we print it with cout, and we also iterate through the array with a for loop.
00:53I'm going to add to this right here. I'm going to say cout << "length of array: " <<
01:01and we'll use the sizeof() operator, (c-string) like that.
01:08So let's go ahead and compile and run this, and we'll scroll up to the top.
01:13The length of the array is 7, even though there're six characters 1, 2, 3, 4, 5, 6.
01:18The length of array is seven, because that seventh byte holds the null.
01:22So you see this is built into the C language. I initialize this array like this.
01:27I make a character array, and I initialize it with a literal string, and it's
01:32actually adding that null byte to it. It's putting all seven bytes of that into it.
01:37So that literal string is actually a c-string.
01:40It's an array of characters with a null terminator, and that's a built-in
01:44paradigm built into the C language and also of course in C++.
01:49So then we print out the string.
01:50We see there's the six characters of the string, and that's line 9 there that
01:54cout, and then we print out each of those characters one by one iterating
01:58through with the for loop. They in lines 11, 12, and 13.
02:03So C Strings are very simple form of strings much simpler than the string class
02:07provided by the C++ STL.
02:10For circumstances where you don't need the power of object-oriented strings, C
02:14Strings are simple, they're small, they're fast, and they're very commonly used even in C++.
02:18Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using strings
00:00The C++ string class is not actually a fundamental type.
00:04This is a class from the standard template library.
00:08These objects are very different and significantly more powerful and useful then
00:12C strings, yet in many ways they work very similarly.
00:15It's important to understand the distinctions.
00:17Let's go ahead and make a working copy of cpp-strings.cpp from the Chap05 folder
00:24here in our ExerciseFiles, and we'll paste this into our Working project.
00:30Scroll down and double-click on that so that we can open it up.
00:34And here we have a C++ string, you'll notice that I simply declare it with the
00:40string as if it were a type, and this is standard in the C++ object-oriented
00:46model that I can simply put the name of a class as if we were a type.
00:50The design goal of C++ objects was that they could be used just as you would use
00:54any first-class type.
00:56And so by including iostream I get these strings, and I simply declare it and
01:02cppstring, and this is a C++ string, and then I can output it.
01:06And exactly as I did, this is exactly the same code that I used in the C
01:11string's example, I'm able to iterate through it as if it were C-array.
01:14Let's go ahead and Save this and Run it, and there we have it this is the C++
01:22string, and there is all the characters in the array, so there's 20
01:25characters in that array.
01:27And if I go ahead here and say what is the size of this, and we run that, we see
01:36that it says the size is 8, and that is simply not even close to reality.
01:42So we see that it actually works very differently, it looks similar, and you can
01:48use it in many of the same ways.
01:50But it's really a very different animal than the c-string.
01:55So I'll go ahead and I'll get rid of that.
01:57And let's see some of the other things we can do here.
02:00Now first of all you'll notice that we're testing for a null byte at the end and
02:05the container class that this is based upon will actually emulate that behavior
02:08so that it can be used just like a C- array, but it's not actually like that, and
02:12it's more correct to do something like this.
02:17To say, well i is less than the size of the string.
02:21We'll see that this ends up working exactly the same, but it's just a little bit more correct.
02:26So what this is this dot size that's actually a method in the string class.
02:33And when you instantiate this C++ string object, then you get all of the methods
02:39in that class and sizes one of those methods in the class.
02:42Even easier you can use the new C++ for iterator loop, and you can simply say
02:54like that, and then obviously you don't have this i any more, so we'll take that
03:00out, and you simply printf c like that.
03:06And so, this is a new paradigm in C++11, this is an iterator loops that's used
03:12with the same for keyword, and you just have any container object.
03:16And its fundamental type, which in this case is c.
03:19So C++ strings are a container of characters.
03:23And this will work just like this except without the index numbers to the left.
03:28So there is each of the individual characters.
03:30So you can actually iterate through that loop just like that.
03:34Of course you can also use C++ iterators, there we go.
03:42So that'll get us an iterator from the beginning, and this auto keyword, this is
03:46also new in C++11, this allows us to not have to type out the very long type of
03:53that particular iterator.
03:56We compare it to the end, as long as we're not at the end we can go ahead and
04:03iterate through the loop, there we go.
04:08So we got a little bit long there, but there it is.
04:10And now we no longer have c here, but what we have is what's pointed out by the iterator.
04:15So the loop ends up looking like that, and I'll bring this down to size again,
04:20and we'll compile and run it, and you see we get exactly the same result again.
04:24So, now we're simply iterating through the container with an STL iterator.
04:28Of course the string class also has a lot of member functions, and we'll be
04:33covering those in the chapter on the STL.
04:35But you can see here, this is just an overview of the C++ string class.
04:41You can see the distinction between these objects in C strings.
04:44C strings are very simple, they're very basic, they're fundamental type in C and
04:48C++ string class is much more rich and has a lot more over ahead.
04:54So now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Creating character escape sequences
00:00Some characters in C and C++ have special meaning or otherwise not normally
00:05accessible using the C language character set.
00:09Escape sequences are used to access these characters.
00:12Let's go ahead and make a working copy of char-escape.cpp, and we'll paste that
00:18into our Working project and open it up in the editor.
00:22Let's go ahead and press the Compile and Run button there, and we see This is a string.
00:27Now if I wanted to insert in here a single quote I could use a backslash
00:34followed by a single quote, and that would display it in the string.
00:38So I save that and run it.
00:41If you get this you can just press always Run in Background or do what I do
00:45just press Run in Background.
00:47And we can use a backslash with a double quote to get a double quote or we can use two
00:52backslashes to get a single backslash or we can use a backslash with a
00:58hexadecimal number x40 to get an ASCII character.
01:03So I'm just going to save this, and we'll run it again, and we see that we
01:08now have single quote, double quote. We have a backslash and the @ symbol
01:13which is hexadecimal 40 in the ASCII table.
01:17You can also get some non-graphical characters, for example, a \n is a new
01:22line, and a \t is a tab.
01:26You notice that I put that right up against the a there.
01:29So we'll see what happens. We'll save that and run it.
01:34And you see we have This is and then tabbing over eight characters for the a,
01:38and that's on separate line because of the new line.
01:40You can also put in Unicode characters if you want to.
01:46For example, I can do backslash and the letter u and 03, b like boys, c like
01:53Charlie, and that should give us a Greek letter Mu.
01:58This is a full table of the standard character escape sequences.
02:01You can see that we have the ones that we've shown, we have a few extras, and we
02:05also have down at the bottom there octal values, hexadecimal values, and single
02:09word and double word Unicode values.
02:14Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with qualifiers
00:00Qualifiers are used to change the default properties of variables.
00:04There are two types of Qualifiers in C and C++, Type Qualifiers and Storage Class Specifiers.
00:11This is an example of a variable declaration with qualifiers.
00:15In this example the const and static keywords are qualifiers.
00:20They tell the compiler that this variable will be immutable, that's the const
00:23qualifier, and that it will be stored in static storage space.
00:28There are two types of qualifiers, there are Storage Class Specifiers, and there
00:32are Type Qualifiers.
00:34The Type Qualifiers include const which makes a variable immutable that means
00:38its value cannot be changed, and volatile which marks an objects that may be
00:44changed by another process, this is commonly used for threaded and multi-user
00:47applications that share memory.
00:49And mutable, this is used to modify a data member from a const qualified member function.
00:55This is only available in C++. The Storage Class Specifiers include static.
01:01Objects stored in static memory have life beyond the execution of a block.
01:05Static variables are commonly used for keeping state between usages of a given function.
01:11Register, register variables are stored in processor registers.
01:15This qualifier is taken as a suggestion by the compiler.
01:18The compiler may or may not actually store the variable in a register.
01:22And extern, extern variables are defined in a separate translation unit and are
01:27linked together at link time.
01:30The auto keyword is deprecated it's actually been removed from the very latest
01:35version of C++ and will probably be removed from future versions of C.
01:40The auto keyword was used to specify a storage class.
01:44In C++11 the keyword has been repurposed as a special type.
01:48Even though auto is still a valid storage class in C, I recommend that you
01:53don't use the keyword.
01:54Auto storage is as the name suggests automatic, and there's no need to
01:59specify it with a keyword.
02:01Let's take a look at a couple of these qualifiers in code.
02:07Make a working copy of qualifiers.cpp, paste this into our Working project and
02:13open it up, and here we've simply declared an integer, and we're displaying it.
02:17I'll compile and run this, and you see it says the integer is 47.
02:22And if I come in here, and I change the value of the integer to 112, and I
02:30compile and run that, you'll see the integer is now 112.
02:33Now if I qualify this as const, and that makes it a constant variable, which
02:40makes it immutable which means it cannot be changed.
02:43And now if I try and compile this, you'll see that I get an error.
02:48And if I hover over that error it says assignment of read-only variable i.
02:53The const qualifier is actually very common.
02:56It's commonly used in objects, for things in the object that should not be
03:00changed even accidentally.
03:02Another very common qualifier is the static qualifier.
03:07And to demonstrate static I am going to go ahead and create a little loop here.
03:16So in this loop we have two variables, i is the iterator that's part of the for
03:21loop itself and j is an automatic class variable, remember automatic class still
03:27exists, it's just automatic, we don't need an auto keyword for that.
03:31And it's initialized the value 12, and then we add the value of the iterator.
03:36So if I run this, see we have i is 0, j is 12, i is 1, j is 13 and so each time
03:43through j begins at 12, but it gets this number added to it.
03:47So here j is 12 plus 2, 12 plus 3, 12 plus 4.
03:52Now if I put the static qualifier here, now j is no longer an automatic
03:58variable, it's not stored in disposable automatic memory.
04:01It's stored in static memory, and it gets initialized once, but it will continue
04:06to accumulate its value, so you'll see it works very differently here.
04:10Now j is 12 plus 0, which is still 12 so here j is 12 plus 1, here j is 13 plus 2,
04:19here j is 15 plus 3 and 18 plus 4.
04:23So j didn't get reinitialized to 12 each time through, it's carrying its value,
04:29it's being stored in a separate space where it doesn't get reinitialized each
04:33time this loop starts.
04:35Static variables are very common for keeping state and functions and in loops.
04:41Qualifiers are used to change default properties of variables.
04:44Some of these like constant static you'll use frequently. Others are good to
04:48know about for when you need them or when you see them in code.
04:51Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using the C++ reference type
00:00C++ references are very much like pointers, but with different rules and semantics.
00:06A lot has been written about C++ references, and there are many opinions about
00:10whether they're necessary or useful or good or bad, but this much is true, they
00:14are here to stay, and you'll need to understand them in order to use them.
00:18So let's make a working copy of references.cpp.
00:21We'll paste that into our Working project and double-click on it to open it in the editor.
00:27And let's take a quick look at this example.
00:29Here on line 6 we're declaring and initializing a variable i, it's an integer,
00:35and we are giving it a value of 5.
00:37And then on the next line, we are declaring a reference variable, this is of
00:41the C++ reference type, and we are calling it ir, and we're initializing that reference to i.
00:49So now ir is a reference to i.
00:51So when we set ir and give it a value of 10, and then we're going to print out
00:57the value of i, Now remember we set i to 5 and our reference got changed to 10,
01:03so when we run this, we'll see that i is now 10.
01:07You notice this syntax, I don't have to dereference it, I don't have to put an
01:12asterisk or anything in front of it, I just say ir = 10, and it actually
01:15changes the value of i.
01:18So reference works very much like a pointer, but with some significant differences.
01:22The syntax of setting a reference is different and does not involve using the
01:25address of operator.
01:27So in other words here on line 7, I don't have to do this, as I would with a
01:33pointer, I would have to set it like that to the address of i.
01:37Here I am just setting the reference to equal i.
01:40The syntax of getting the value referred to by a reference also does not involve
01:44the dereference operator.
01:45So when I want to set or take the value of it, I don't have to put an
01:50asterisk in front of it like that to dereference it, because it's not a
01:53pointer, it's a reference.
01:54The whole idea of references is to make them more transparent, and in some
01:59ways to make them safer and in other ways it obviously also makes them more dangerous.
02:03You cannot refer to the reference itself that is you cannot take a reference of
02:08a reference, you can't have a pointer to a reference, and you cannot have an
02:11array of references.
02:13And a reference cannot be null, it cannot be uninitialized, and it cannot be
02:16changed to refer to another variable.
02:19So in other words, if I were to say ir= j where j is some other variable, it's
02:24really just going to copy the value of j into i, it's not going to change the
02:29reference variable itself.
02:30There's no way to change a reference variable once it's been set.
02:33Now a really common usage of this, and this is actually where you're going to
02:38see these things the most commonly is in functions and methods.
02:42So here I am going to declare a function, I am going to say it's int reference,
02:46so it returns a reference to an int, and we'll just call the function f, and it
02:50takes a reference to an int as its argument.
02:55And I'm just going to return the increment of that int.
02:59So all it will do is it will take that integer reference, and it will increment
03:03it, and it will return a reference to the integer.
03:05So, I am going to get rid of these things here, and I am just going to say f and pass it i.
03:11Now you notice the way that I called it, I am just passing it i like I would
03:16any other function.
03:17And if the function was not taking a reference then the function would make a
03:21copy of i, and it would put it on its stack, and it would create an automatic
03:25variable internally, and it would increment that and return that value.
03:28But instead, it's going to do something very different here.
03:30Notice that we're printing out the value of i, and when I compile this and run
03:35it, you see that i is now a 6.
03:38What the function has done is it's actually incremented i, it's affected
03:42something outside of its own scope.
03:44And it's done that because we're no longer calling by value now, now we're
03:48calling by reference, and we are actually able to affect the things outside of the function.
03:53This gets even more insidious--if I can use that word--when I do something like this.
03:58I am now assigning a value to what's being returned by that function and
04:02remember what's being returned by that function is a reference to i.
04:07So, what happens here is that i is now 42.
04:12And this is commonly how things like operator overloads are done, and we'll
04:16cover that when we get to C++ classes later on in this course.
04:19But for now, you need to know that this is something that can actually be very dangerous.
04:25The intent with references was to make some things easier and to make something
04:30safer, but it also made some things more dangerous.
04:33So here's the solution.
04:35Every time you use references in a function, you return references or you pass
04:40references, you always want to declare them as const unless there's a good
04:45reason not to, and there will be times when there's a good reason not to.
04:49So if I say const int for the return type and const int for the passing type,
04:54notice what happens here.
04:55I am going to save this, and I am going to compile it, and we are going to get a
05:00couple of errors here.
05:01First of all, inside of the function I am no longer allowed to increment,
05:04because that's a constant value now.
05:06So it's not letting the function actually impact the variable that was passed to it.
05:11And likewise, on the return value I am not allowed to assign to it, because I'm
05:18returning a const int.
05:20So in my opinion references should've defaulted this way, but it's okay we have
05:25the qualifier const, and if we just get into the habit of using it all the time
05:30except where we actually intend to have these side effects, then our code is
05:36going to be a lot better, and it's going to be a lot safer.
05:39If you actually want to have side effects, my recommendation is to use pointers
05:43where you can instead of references.
05:44And obviously there are a lot of people who disagree with my opinion on that.
05:48You need to be aware that that there's a lot of code out there that uses
05:52non-const references, including quite a bit of the standard template lib.
05:56So you just need to be conscious of this effect.
05:59References are very powerful and very common in C++.
06:03We'll be using references quite a bit, and you will gain much more experience
06:07with them in the rest of this course.
06:08Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with structured data
00:00In C the struct keyword provides a way to aggregate a fixed set of data member
00:06into a single object.
00:08In C++ struct is expanded to include function members, that usage will be
00:13covered in the classes and objects chapters.
00:16In this movie we'll be dealing with the Standard C struct.
00:19Let's go ahead and open struct.cpp I am going to make a working copy of that and
00:25paste it into our Working project, scroll down and double-click to open it.
00:30Let's go ahead and span that to the full screen so we can take a look at the entire file.
00:37Here we have a struct, and we've name the struct employee, and it has three data
00:42members, it has an int, and it has two character pointers .
00:47And then down here in main we say struct employee, and we give the variable name.
00:54So this creates a variable of the type struct employee.
00:58And we initialize that with this initializer list, and it has these three
01:04members 42, Joe and Boss.
01:06So that's the employee ID, and the name, and the role.
01:09All right, let's go ahead and compile and run this, and then we will take a
01:14looks at some details.
01:15So there we have it runs, in this string prints out, joe is the boss, and has ID number 42.
01:22First thing I'd like to point out here is the use of the keyword struct here in
01:26the declaration, in C this is required, in C++, and you'll often see at this way
01:33you can actually eliminate that, and this will still compile and run.
01:38If I was compiling this with a C compiler that would not work we'd need that
01:42struct keyword there as well.
01:44And so I'll leave that in for now, and it doesn't hurt.
01:48In my personal usage I tend to use the struct keyword and its part of my making
01:53a distinction between struct and class.
01:56In C++ this is actually a fully first- class object you can have a function
02:03members here as well as data members.
02:05In C it doesn't work that way, you can't have the function members because C
02:09doesn't have the object- oriented extensions that C++ has.
02:13And really the only distinction between struct and class in C++ is that the
02:19data members default to being public, in structures so that they work just like C structures.
02:25And in a class they default to being private.
02:28So I tend to use struct in places where I mean just an aggregate of data, and I
02:33tend to use it exactly like a C struck and its works perfectly.
02:37And if I really intend to help function members that I go all the way, and I
02:41created a class with private data members and public function members, and I use
02:46the class keyword instead.
02:48To really make that distinction that this is a data structure and not a class
02:53with function members.
02:55So inside of the struct you can really have any valid type, I have got two
02:59different types, here I've got character pointers, and I've got an integer.
03:02And when you access it you access it with this dot notation.
03:08And so joe.name refers to the name field inside of the employee structure in
03:15the variable named Joe and .role refers to the role field in dot ID refers to the ID field.
03:24If instead I was accessing this view a pointer and so let me create a struct
03:29employee pointer, and I'll go ahead, and I'll assign that to the address of
03:35Joe and so now I have this pointer instead, and I can do this, ep and use that notation there.
03:43And let me just go ahead and duplicate that across here, and we'll compile that
03:47and run it and see that works exactly the same, you get exactly the same result.
03:52And this is a very common idiom, now I have a pointer that points to this type,
03:57and I could have several of these struct employers, and I could simply assign
04:00this pointer loop or however it is I want to do that, and then I can access them directly.
04:06So this pointer dereference operator or structured dereference operator or class
04:12dereference operate however you want to look at it.
04:15That dereference is a pointer and accesses a field all in one operator.
04:21And so that's the dash followed by right angel bracket, and that's the dereference operator.
04:26Now in C and again this works the same way in C++, but it's more commonly used in C.
04:34If you mean to be declaring a lot of these struct employees, and you don't want
04:38to have to type the whole thing each time, you can do this, you can say typedef
04:42struct employee and here you can name the type, and you can call it employee
04:50type or you can even call employee, and that works just fine.
04:54And so then here instead of struct employee like that I can employee type
04:59and I can do the same thing here. And again that will work exactly as expected.
05:07And so this is a away if you're not using C++, and you want to get around that
05:11limitation and not having to type the word struck every time.
05:14I'm not a big fan of typedefs in general, you know there are times when they're
05:18really convenient and handy, and you want to use them.
05:21But most of the times using them in a circumstance like this, it simply
05:25creates more confusion than is necessary, but that capability is there if you want to use it.
05:30So the ability to create data structures using struct is a fundamental tool in C.
05:36And as we learned later it's also the basis of classes and objects in C++.
05:41So let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Introducing bit fields
00:00Bitfields provide the ability to pack multiple values into less space than they
00:04would normally take.
00:06Let's look at an example here in bitfields.cpp, copy that and paste it into our
00:11Working project and open it in the editor here. I'll just maximize this so that you can see it.
00:16So beginning on line 5 you'll see there is a structure called preferences, and
00:20it has five members, four Booleans and an unsigned int.
00:24And you'll notice that each one of these variable has a little bit of syntax
00:27we've not seen before.
00:28After the name of the variable there is a colon and a number.
00:32This number represents the number of bits that that field will occupy.
00:35So a Boolean value doesn't require more than one bit and an unsigned int only
00:40requires the number of bits that it will take to represent the largest number.
00:44And very, very few people I imagine have more than 16 children, so number of
00:48children can be in four bits pretty comfortably for most cases, at least for our purposes here.
00:53And you'll notice that down here beginning on line 15 I initialize this
00:57structure, and I just see this true and false for the Booleans and integer
01:01number for the numberOfChildren.
01:03And it all behaves exactly like you'd expect except that the entire structure
01:07just requires 8 bits.
01:09So let's go ahead and bring this back down to size and compile it and run it.
01:13And you'll see that it works just as we would expect.
01:16So for the true ones like likesMusic and hasInternet, we see that those get
01:21printed because we have this simple if statement here.
01:24And that our test subject homer has 3 children.
01:28So be aware that the language does not guarantee any particular bit ordering or byte packing.
01:33So how your data is actually stored in memory is highly dependent on the target machine architecture.
01:39This especially becomes an issue if you store your packed data in a file and
01:42then expect to be able to read it on a different machine.
01:45It's also worth noting that bitfields can be a source of trouble in concurrent
01:49or threaded programming, because all of the bits in a unit must be read and
01:53written at the same time.
01:54So let's delete our Working file and run Clean to get set up for next the lesson.
Collapse this transcript
Working with enumerations
00:01C and C++ have an enumerated type called enum, and this is actually a very useful thing.
00:06Let's make a working copy of enum.c, not cpp but c, and we'll paste that into
00:13our Working project down here, and we'll double-click and open that up.
00:17enum appeared in C89 or NCC, it does not actually exist in K&R C.
00:23What's really interesting about this is that while it looks syntactically like a
00:27type, and it's even referred to as a type, it is not really a type.
00:31Enumerated names actually work more like constants than like types.
00:35Let's go ahead and maximize this, and we'll scroll through real briefly for
00:39those who are typing along at home.
00:42So up here at the top around lines 4 and 5 you see the two enums.
00:46And what this code does is it defines a deck of cards, and then it lists the deck of cards.
00:50But once you have the data for deck of cards then you can start writing card
00:54games and doing things like that.
00:56And in order to make these symbolic, so in my card deck as I initialize it, I
01:01can have Ace of Spades, 2 of Spades, 3 of Spades, you know 4 of Hearts, Queen of
01:06Diamonds and so that I can use these symbolic names rather than just numbers I
01:11used enums so that they actually work like constants.
01:14Of course I could've defined constant integers, I could've said something like
01:17const int Spade = 0, and then I could've used you know Spade in here.
01:25But being able to do them as enums it allows me to categorize them.
01:29So these are suits and these are ranks, and it just makes it that much more
01:33neater and tidier, and that much more self documenting.
01:36So I really don't need a lot of comments in here at all, and I may not have any.
01:41That's right, I don't have any.
01:43And yet you can read this code, and you can know exactly what it does.
01:46And that's because of the use of constants for these strings and the enums for
01:53those symbols there.
01:54So, let's go ahead and put this back down to size and go ahead and save it--
01:58because I did--I typed in there a little bit, and I took it out, but it
02:03still needed to be saved. And so I'll compile and run it.
02:06And you'll see that all this does is it defines that deck of cards, and then it
02:10just iterates through it, and it lists the entire deck of cards.
02:13I've got Spades, Hearts, Diamonds and Clubs in order, and I've got the Ace
02:17through Jack, Queen, King also in order, and I was able to do that because of
02:22the way that I defined these.
02:24So, when you define an enum the first element is going to get a value of zero,
02:28the second element is going to get a value of one and so on and so forth.
02:32Instead you can assign them, different places.
02:34And so if I assign this Ace to a 1 and then this Jack to 11, Queen is going to
02:40be 12 and King is going to be 13 automatically.
02:43And so when I go in here, and I maximize this so you can see it.
02:48When I come in here, and I start to initializing my card deck, you see I've
02:52got a structure called card_t, card type, and it has two elements has the rank and the suit.
02:59And so for each of these elements of the array, the array is an array of cards
03:03types, and so for each of these elements the array I have a rank and a suit and
03:07a rank and a suit and a rank and a suit.
03:09And this is how you initialize an array of structures like that with the curly
03:14braces for each element.
03:15And so it makes it all very obvious exactly what it is and so the enums help
03:21to make that happen.
03:22In C++, and let me go ahead and I'll delete this one, and we'll Clean the
03:29project, we don't have any problems with that, and we'll bring in the C++
03:34version just copy that and paste it into the Working project and double-click on it.
03:40And again this is very, very similar. It's pretty much the same code.
03:43I'm doing the same thing with the card deck initialization.
03:46One thing that you need to be aware of is that this type of initializing a
03:51structure in C++ actually was not fully supported by the standard until C++11.
03:58And so even though this works in C it would not have worked in C++ until
04:02the latest standard. So I'm still using the enums.
04:06In fact, you know I'm using constant strings for the strings that get displayed.
04:10But I am still using the enums here because it's just a very convenient thing.
04:14And so even though there are some other ways to do some of these things in C++
04:19and the rest of this code is almost exactly the same, it's still very common and
04:23useful to use enums for this kind of a purpose.
04:26Let's go ahead and compile and run this, and you can see that it does exactly
04:30the same thing in C++ that it does in C.
04:33And now we'll delete our Working file and run Clean to get it set up for the next lesson.
Collapse this transcript
Using unions
00:00A union is a data structure that allows you to use the same memory space
00:04for different types.
00:06Let's make a working copy of union.cpp and paste it in our Working project, open
00:12it up here, I am going to maximize it so that you can see.
00:14And you'll notice here that we have a structure except instead of the structure
00:18keyword it uses the union keyword, and within it there's a struct, and that
00:23struct represents one element, and it has four elements inside of it, and then
00:28there is also an integer. So the union has two members, the struct is one of the
00:33members of union and the struct itself has four members.
00:36I am using these type names out of standard int.
00:38And the purpose of this is is that I want them to be in a specific size, because
00:43of the way that I am using this union.
00:45What I am using this union for is I want to pack and unpack IP addresses and an
00:50IP address is 32-bits, and it contains four 8-bit fields.
00:52And each one of those fields is a separate number.
00:55And so this makes a convenient way for me to use that IP address either as four
00:59separate objects or as one object.
01:01And those were separate objects and need to occupy exactly the same space as the one object.
01:05So this is actually a really common solution to problems like this.
01:09So here I'm declaring a variable of my union, my union is called ipv4 and my
01:13variable is called addr.
01:15And I initialize the bytes field, now the bytes field is the structure inside
01:20the union, so addr.bytes, and I initialize that with the four separate
01:24components of an IP address, and then I print it out both as the dotted quad
01:29notation with the four separate fields, and as the equivalent integer.
01:33So let's go ahead and run this and see how it works.
01:35And there we have it, we have the dotted quad version of the IP address,
01:41192.168.0.96, and we have the integer.
01:46And you'll notice that the integer has the bytes in reverse order.
01:49And that's fine, that's actually correct.
01:52So unions are often used to conserve space in data structures, reuse space for
01:57various purposes that are not needed in the same record.
01:59They are also sometimes used for crude polymorphism as we see here.
02:03You need to be careful, using a union often means that you need to take
02:07responsibility for type checking yourself, and because of this
02:09unions are rarely used when C++ objects are available.
02:13Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Defining types with typedef
00:00The typedef keyword may be used to provide an alias for a type name.
00:04This can be handy in instances where a type declaration becomes cumbersome, or
00:09it may vary on different target systems.
00:11Let's go ahead and make a working copy of enum.c and I'll paste that into our
00:18Working project and open that up. I am going to maximize it here so we can see it.
00:24And I'll just scroll through it real slowly so that those who are typing along at home.
00:28This is just a program that defines a deck of cards and prints them all out.
00:37It's a lot simpler than it looks, it's a lot of typing but that's mostly because
00:40there's 52 cards in the deck.
00:43Here I've defined this structure called card, and it has the rank and the suit.
00:49And this array is an array of those cards, so it has rank, suit, rank, suit,
00:54rank, suit, and there's 52 pairs of ranks and suits.
00:58And so rather than having to type out struct card here and struct card here, I
01:03decided to create a typedef and so it's card_t, and it's traditional to put _t
01:10at the end of a name that's a typedef, and that way people know to search for a
01:14typedef and the source code to find out what it is.
01:16And here in Eclipse obviously if I just hover over one of the uses of card_t,
01:21you'll see that it brings up that typedef, and I can see what that looks like,
01:25and really how to use it.
01:27So it's really just a shorthand facility typedef, and it's just a convenience.
01:31But it can be very convenient, especially in C++ when you start working with
01:36iterators and some of those types can get very, very long and a lot of typing.
01:40So the typedef facility can be very convenient for simplifying cumbersome type
01:44definitions and machine dependent types.
01:47It's not as widely used in C++ where other more powerful features may displace it.
01:52But it is still very common, and there are plenty of circumstances where it's useful.
01:56So I am going to go ahead and delete this from the file system, and we'll run
02:03Clean to make sure we are set up for the next lesson.
Collapse this transcript
Introducing the void type
00:00The void type has special meaning in C and C++ where it's used to specify no
00:05value for function returns and function parameters.
00:09Let's go ahead and make a working copy of void-type.cpp.
00:12I'll paste it here into the Working project and open it up.
00:16Here on line 5 we have a function declaration, and this function returns a void
00:21type and takes a void type for its argument.
00:24We have the definition of it down here, and you'll notice that it doesn't actually
00:28return anything, and it doesn't actually have an argument.
00:33So this is the primary meaning of the void type. It's not used for variables.
00:38You can't create a variable of void type.
00:40You can't assign any value to it, you can't take any value from it, and that's
00:44actually what it means.
00:46It's really only used for function parameters and function returns.
00:51So if we save this and run it, you notice it has the void-type.c, and then it
00:58runs the function and says this in his func. So that's the void type.
01:02There's another special usage of the void type, and this is for void pointers.
01:07We'll go ahead and we'll close this, and we'll delete it from the Working
01:11project and run Clean, and then we're going to open a void-pointer.c.
01:18We'll get to void-pointer.cpp in a few minutes.
01:21We're going to copy that and paste it into our project here and double-click on it.
01:26I am going to go ahead and maximize this so that you can see it.
01:29Here we have again a function declaration, and this function returns a pointer
01:34to void, and it takes a pointer to void as its argument.
01:38Here's the definition here.
01:40You pass it this pointer, and it returns the pointer and they both have this void type.
01:46So what the void pointer means in C and C++--
01:51although it's a little more complicated in C++ we'll get to that in a minute--
01:55but what the void pointer means in C is that this is a pointer, and I don't
01:59know, and I don't care what type it is.
02:01So you see here that we do a character pointer with a string, and we pass that
02:06character pointer into the void pointer function, and the void pointer then
02:11returns that same pointer, and it returns it as an int type.
02:16Then we're going to print out the 08 hexadecimal digits of what is pointed at
02:23by this void pointer.
02:24So it's actually going to print out this string, but in hexadecimal.
02:28So let's go ahead and we'll bring this back down to size, and we'll compile and run it.
02:32And you see 34333231, and that's because the byte order of the Intel processor
02:41is backwards, but what we've got there is 1234.
02:44So in hexadecimal that would be 31323334, and that's what's being printed out.
02:53So again looking at this we have a character pointer, we pass that character
02:56pointer into the function, and then the function takes that character pointer as
03:02a void pointer and returns it also as void pointer.
03:06Then we take it back from the function, and we're assigning it to an integer
03:10pointer and then printing it out as a hexadecimal value of that integer.
03:15So we're taking that character pointer, and we're using it as an int pointer all
03:20through this void pointer function.
03:22So void pointers are basically a polymorphic pointer.
03:26Now we're going to look at how this works in C++.
03:29C++ is a lot stricter about how this works.
03:32So I'm going to go ahead and I'm going to delete this and run Clean, and then
03:38we are going to take void-pointer.cpp and paste it into our Working and open it up.
03:45You see the difference here is really just about how strict it is.
03:49When I pass that character pointer into the function, I actually have to cast
03:53it as a void pointer.
03:55And when I take the integer pointer back from the function I actually have to
03:59cast it as an integer pointer.
04:01Let's go ahead and compile and run this, and you see it compiles and runs it has
04:05exactly the same result.
04:06But if I were to take these casts and remove them and make it look just like
04:11our C version, you notice right away I get this little bug symbol, and it says Invalid arguments.
04:17Candidates are void pointers.
04:19If I try to compile this, I get all kinds of errors.
04:22I get an error up here saying that I initialize the argument 1 wrong, and I get
04:28these errors here, Invalid conversion from void pointer to int pointer, invalid
04:33arguments conversion from const void pointer to point pointer.
04:37So all of these errors are mitigated by simply casting.
04:41So when I save this and compile it all those errors go away.
04:45So C++ is a little bit more strict about how you pass around these types, and
04:49that's actually a good thing.
04:51It helps to prevent you from making some costly mistakes and the use of void
04:55pointers in C is actually a place where it's really easy to make some very
05:00costly mistakes and have a lot of debugging on your hands while you're trying to
05:04figure out, why this thing doesn't look the way that it's supposed to look.
05:08So while void is syntactically a type, it's only used in special circumstances.
05:13Its value is return type or is a parameter type is to enforce a rule preventing
05:18use where value would be expected.
05:21And its meaning as a void pointer is different yet again as a
05:24polymorphic type-less pointer.
05:27So let's go ahead and delete this Working file, and we'll run Clean to get ready for the next lesson.
Collapse this transcript
Understanding the auto type
00:00The auto type is actually a new feature in C++, but I'm covering it here because
00:05it's quickly becoming very common.
00:07So we're going to start by making a copy of working.cpp, and we'll paste that
00:12into our Working project and open it up here.
00:16And I'm going to add another include header here.
00:23This one is called typeinfo, and you'll see what that's for in a moment.
00:26And we're going to define a simple function.
00:33We're going to define a variable, and we're going to give it a type of auto, auto x = func();
00:39like that, and then we're going to display what's returned by that.
00:47And this will all make sense in a moment.
00:49And we're going to also look at the type, we're going to inspect the type with typeid.
00:56The typeid is actually an operator that returns a typeinfo object, and that
01:04typeinfo object has a method called name.
01:07And that'll tell us the name that the compiler uses internally for this type.
01:12So it's not going to necessarily be the name that you're used to seeing for, and
01:16it's also not necessarily going to be the same name on your system as what you
01:20see on my system, but it should give us a good idea of what's going on here.
01:24So I'm just going to save this and run it, and you'll notice that we get two things.
01:28We get a 42 because our function returned 42, so our variable got the value of
01:3242, and we're displaying 42 here.
01:35And typeid tells what type this variable is, and it says its i which is integer.
01:41So what the auto type does is it declares an object of a type, and it determines
01:48that type by how you initialize it. Now the object is still strongly typed.
01:53That x is now an int, and I can't use it as a string or use it as a float or use
02:00it as something else. It's always going to be an int.
02:04What happened here is really exactly the same as if I had typed int like this,
02:08and if I save this and run it, you'll see we get exactly the same result.
02:12On the other hand, by using auto, I can change this function, and I can have it
02:16return a string, which is an STL object, right. And I'll just give it something to return there.
02:23And I don't need to change anything down here.
02:26I just save this and run it, and now we have a string, and you'll notice
02:30that the typeid returned Ss, it may be something else on your system, but
02:36it's a different type.
02:37And that type is now a string.
02:39So this auto is now exactly the same as if I had typed string here.
02:43And if I save that and run it, you'll see we get exactly the same result.
02:48All auto does is it allows you to declare a variable when you don't know the
02:54type that you need it to be, but however you initialize it will determine that type.
02:58Now this is just a demonstration of what it is and how it works.
03:02This is not how you're actually going to use it.
03:05But I'm going to give you an example here of how you may actually use this, so
03:09I'm just going to delete these things, and I'm going to delete our little
03:12function, and I'm going to change typeinfo to vector.
03:16And we're going to use an STL object called vector.
03:19And again, you'll learn about these later in our chapter on the STL, but I
03:23want to show you an application for this, we're actually going to see auto types really used.
03:27So we're going to declare a vector, and it's going be a vector<int>.
03:31So vector is very similar to an array, only different and more powerful.
03:36And we're going to call it i, and we're just going to give it five members here.
03:43And I'll put an equal sign there, it's not actually required, but I like it, it makes it clear.
03:49And now I'm going to iterate through this vector with a for loop and here's
03:53where this gets exciting.
03:57I'm going to declare an iterator, I'm going to call the iterator it, and
04:03we'll assign it to i.begin, and this will be while it != i.end, and we'll
04:13increment the iterator.
04:16I'm just going to maximize this while I type so you can see the whole thing.
04:24So what we have here is this iterator, and you see that's a lot of typing, and
04:28it's prone to error, and it's ugly.
04:31And the rest of this isn't so bad, so we'll bring this back down, and we will
04:36compile it and run it, and there's the result that we get and so we're basically
04:41iterating through this vector of all five of these values and 1, 2, 3, 4, 5,
04:46they're each one aligned exactly as we expect.
04:48Now instead of all of this, when you're dealing with the STL, and when you're
04:52dealing with templates, this is not a worst-case example.
04:57These can get a lot worse than that.
04:58I can just type auto, and now it's really clean and really clear, and it's
05:02obvious what it is that I'm doing, because if I know the STL, I know that begin
05:07and end and container objects always return an iterator.
05:11And so here I have an iterator, and I know that it's typed vector<int> iterator
05:16because that's what this returns.
05:17So I can just save this and run it, and I get exactly the same result.
05:22So this is actually I think more clear, it's more readable, and it's a lot less
05:27prone to error in both typing and in reading.
05:30So this auto feature is a real improvement, but it's not without its dangers. Be careful!
05:35Only use auto types where the implications are clear and the usage is concise.
05:40Otherwise, you could potentially sacrifice readability and even introduce errors
05:44that could be hard to find.
05:46So let's go ahead and delete our working.cpp, and we'll run Clean to prepare for the next lesson.
Collapse this transcript
6. Operators
Exploring the assignment operator
00:00The assignment operator is represented by the equal sign.
00:04It is used for assigning values to variables.
00:07Let's make a working copy of working.cpp from the Chap06 folder, and we'll paste
00:13that into the Working project and double-click to open it.
00:18So assignment operator basically works like this, if we have a couple of
00:21variables we'll just create some integers called i and j.
00:25I can assign value to one of them and then when I look at it I could say and
00:32compile this and run it.
00:34And we have assigned a value to i, it says value is 5.
00:37We have this little warning here, because we're not using j, unused variable j,
00:41we'll use it in a minute.
00:43So the assignment operator is the equals sign and what it does is it copies a value.
00:49What it's doing in this case is it's taking the literal value 5 which we just
00:54typed in with the number 5, and it's making a copy of that value and putting
01:00it in the variable i.
01:01So in this context it's operating in its copy mode.
01:06The assignment operator actually has two modes, we're going to talk about
01:09the copy mode first, and we'll talk about the initialization mode in a little bit here.
01:13So another use for it is we can assign i to j, so this copies from the
01:18right-hand to the left-hand side.
01:20In this case it's taking the value that is in i, and it's making a copy of that
01:25and putting it in j.
01:26So let's change this to say i is that, and we'll make another one that says j is that.
01:33Now we save that and run it, we see that they're both the same value.
01:39You can also use the assignment operator to chain assignments.
01:43So if we make a third one called k, I can say k = j = i, and I can even take
01:49out this assignment of i, and then they will all have that same value, so I can
01:55compile and run it.
01:56And this works because the assignment operation actually returns the value of the assignment.
02:02So this makes it possible to chain these operations.
02:06Some of these distinctions that we're making right now may seem very
02:08technical and very pedantic.
02:10The reason we're making these distinctions is that they're actually going to
02:13become important when we start overloading operators in a later chapter.
02:17So just for now understand that the reason we can chain these assignments is
02:22because the assignment operation actually returns a value, and that will
02:26become important later.
02:27So the assignment operator actually works with structures as well, so if we
02:31create a little structure here, and we can create it out here and say struct s,
02:36and maybe it's just got a couple of ints in it, int I, int j, int k.
02:42And then down here we can create a variable with that structure.
02:49And so we've created a variable s1 that's of type struct s, and it has the
02:55three values in it 1, 2 and 3 and those are assigned respectively to the
02:59structural members i, j and k.
03:02And so if we do a little printf here, and then we can look at those structure members.
03:08I'm a big fan of copy and paste for stuff like this.
03:14We'll put in a new line at the end of our printf format and a semicolon at the
03:20end probably will be a good idea.
03:21So now when I save this and run it we have the i, j and k values.
03:26So this is actually the other usage of the assignment operator.
03:31In this case it's actually being used for initialization.
03:34So that equal sign is really the initialization operator in this case as
03:38opposed to this assignment operator.
03:39We're going to go ahead and do some assignment with this as well because we can
03:43declare a couple of other structs of the same type, s2 and s3.
03:49And we can actually assign s3 = s2 = s1,
03:54and again the assignment operator will copy the entire contents of s1 into
03:59s2 and then return that structure so that it can copy the entire structure of s2 into s3.
04:08And so I can make a couple of more copies of this, and I can say s2 and s3 and
04:16come over here and say s2, and I'm just going to copy and paste and s3 and copy
04:24and paste, and you'll see that they all have exactly the same values.
04:27Save that and run it, and that's because that assignment operator here is
04:32actually making copies, and it's operating in that same chain mode again.
04:36So this distinction between initialization and assignment, this usage here in
04:42line 12 is initialization, and it's taking those values and its initializing
04:47s1 with those values.
04:49And the usage on line 14 here is assignment, where it's actually making a copy
04:55of the entire structure s1 and putting it in s2 and then making a copy of the
04:59entire structure of s2 and putting it in s3.
05:02So those distinctions become more important later, but for right now for the
05:06purposes of C specially, you can simply think of it as assigning a value from
05:10the right-hand side of the equals sign to the left-hand side of this equals
05:13sign, even in the case of initialization.
05:16So semantically an assignment operator simply copies an object from right to
05:20left, may be used for initialization or for copying values.
05:24This distinction becomes more important when using classes with overloaded operators.
05:28Operator overloading is covered later in this course.
05:31So let's delete our Working file here, and we'll run Clean to get ready for next lesson.
Collapse this transcript
Using arithmetic operators
00:00C and C++ provide a number of standard arithmetic operators.
00:05Let's make a working copy of working.cpp from the Chap06 folder.
00:10We'll paste it here into our Working project and open it up.
00:14I start out by declaring a couple of integers here, and we're going to just
00:18replace this cout with a printf, because that's just little easier for some of
00:21these things, and I can put the arithmetic operation right in here.
00:25I can say i + j, and I'll say the result is, and it'll come up with a 47. There it is 47.
00:34So this is just a simple case of integer arithmetic.
00:37I'm adding two values, and I'm using the addition operator.
00:42I could use the subtraction operator, and I'll get a negative value.
00:47I think this will come out at -37 if I am not mistaken.
00:50There we go -37, because I'm subtracting a larger value from a smaller value.
00:57We can do multiplication, and I'm not going to try and do this one in my head.
01:01Save that and run it, and we get a value of 210.
01:04And we can do division, and I'm actually going to do the division in the other
01:09way, because this will work better for this purpose.
01:12So 42 divided by 5, now I believe this will give me a value of 8 and the reason
01:18for that is that we're working integer arithmetic.
01:22So it gives me a value of 8, and there's also a remainder, and I can get the
01:25remainder with the modular operator, and that remainder should be 2.
01:30So I'll run that, and there the remainder is 2. So those are the five basic functions.
01:36We have addition, subtraction, multiplication, division, and remainder or modulus.
01:42Now all of these with the exception of the modular operator are also available
01:47for floating points.
01:48So if I just declare these as floats, and I'll start with an addition, and let's
01:54give them a fractional part 5.1 and 42.2. So I'll run that, and you notice we get
02:02this large integer, because I'm interpreting it as an integer.
02:05We also have a warning over here that says it expects int, and we got a type of double.
02:11float gets promoted to double when it's used with printf in C++.
02:14So I'm just going to say f there instead, and we'll run it, and we get 47.29999.
02:24So we get some nice rounding errors there as well.
02:26That's actually to be expected with float.
02:29If we make this double we have a lower chance of having that happen, and there
02:36we go 47.3000. We can do the same thing with subtraction.
02:41I'm going to save that and run it, and we get a subtraction result, and multiplication.
02:45Save it and run it, and we get a 215. 22 and division 8 blah, blah, blah.
02:55And in fact with the floating point we can do division, and we can expect to get
02:59a reasonable result in the other direction, and we get a fractional part.
03:04Of course, the modular operator does not have any meaning in this case.
03:08So if we try to run that we get an error that says that the binary operator
03:13modulo does not apply for double to double.
03:17There're also unary versions of the plus and minus operators.
03:22So I'm just going to comment it out i here, and we'll just take j, and if I
03:28put a unary - in front of it, we'll get -42.2. And if I put a unary plus +
03:34in front of it, we'll get a positive 42.2 which is the same as what it is by itself.
03:40So the unary + in most contexts is semantically null, and it's very
03:45rarely actually used.
03:47There is another use of the binary version of the plus operator.
03:52And in STL containers like the string class.
03:56If I say string "This is a string";, and we'll call that one s1, and if I say
04:03string s2 = "This is another string".
04:07So we'll to use the cout for this, and I'll say cout s1 is, and we'll do the
04:15same thing for s2, and then we will add them together, we'll concatenate them.
04:20So I will call this concatenate, and that's s1 + s2.
04:25So go ahead and save this and run it.
04:29So string1 is This is a string, string2 is This is another string, and you see
04:33the concatenation This is a string and then the second string is jammed right on
04:38the end of it there, and that's another use of the plus operator.
04:42So this is really an example of an operator overload and in the case of the STL
04:46container it is a very, very common usage which is why I'm covering it here and
04:50for some of your own containers that you might define that you might want to
04:54also overload the plus operator, and we'll show you how to do that in the
04:57chapter on the classes.
04:59So the arithmetic operators in C and C++ are simple and effective.
05:02They work with all the basic types and can be overloaded for used with C++ classes.
05:07We'll cover operator overloading in a later chapter.
05:10Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with increment and decrement operators
00:00C and C++ provide unary operators for incrementing and decrementing values.
00:06Sometimes these operators are called increase and decrease operators and they
00:10increment or decrement a value by one. Let's take a look at how this works.
00:14We'll make a working copy of working.cpp out of the Chap06 folder in your ExerciseFiles.
00:21I am going to paste this into our Working project and double-click on it to open it up.
00:25I am going to start by creating an integer i, and we'll give it a value 12, and
00:30we'll go ahead and print out that value, I am going to use printf for this
00:33because it's a little more convenient. So we'll save that and compile and run it.
00:40When you get this you can sometimes just say Always run in background.
00:44I just click on the button there. It just happens sometimes,
00:48it may or may not happen on your screen, it's nothing to worry about.
00:53So it says here that the value is 12 and so now if I increment the value I am
00:56just going to come down here on the next line, and I am going to say ++i; and so
01:01what that does is it increments the value.
01:03Now when we print it out it will say value is 13.
01:06So I'll save this and run it, and it says value is 13.
01:10Now the beauty of the increment operator as opposed to just assigning a new
01:15value, if I were to say i=i+1, that's really two separate operations.
01:21It performs this addition, and then it copies that value and assigns it into i.
01:27So obviously Compiler will probably optimize that down, and it may not actually
01:32make any difference in clock cycles, but it is more complicated, and it is
01:37semantically doing a different thing.
01:39The increment operator is incrementing that variable in place.
01:44But the real beauty of this is that I can increment and print it all in one operation.
01:50This actually returns that incremented value. So if I do this, I'll get the value as 13.
01:56Save and run, it says the value is 13.
02:00And if I do three of these I'll get 13, 14, and 15, save and run, 13, 14, and 15.
02:09There's another interesting aspect to this which is that I can put the ++
02:13after the i and instead of incrementing it first it'll increment it after it returns the value.
02:21So if I save this and run this I'll get 12, 13, and 14.
02:25So what this is doing is it's actually returning the value first and
02:29then incrementing it.
02:31So it returns the value which is 12, and then it increments it so now it's 13
02:34and then in the next printf it returns the value which is 13, and then it
02:39increments it to 14, and on and on and on.
02:42So this is called prefix and postfix versions of the increment operator.
02:47In the prefix version, increments the value and then returns the value.
02:51In the postfix version it returns the value and then increments the value, very
02:56simple, very intuitive, and very useful.
02:59Of course this also works on floating point values, so if I define this as float
03:05we now have a floating value.
03:08So I'll change these to float, and we should get 12.0 and 13.0 and like that.
03:15Save that and run it, and interestingly it also works with pointers.
03:20Now this is a little bit more involved, but it's tremendously useful, and it's
03:25actually used a lot. So let's take a look at how this works.
03:28So I wanted to clear a character array, s1 left bracket right bracket = "string", and that creates a
03:35character array with seven elements, the six letters and a null.
03:41And I am going to create a character pointer and assign it to the beginning of the string.
03:46Now I am going to print this out.
03:48Do reference the pointer so that we can see that it's actually pointing at the
03:54first letter in the array so that is letter s.
03:56So we'll save that and run it, and it says value is s.
04:00So again what we have here is we have an array of characters.
04:04The first element is an s, the second element is a t,
04:07the third element is an r and so on and a character pointer that's initialized
04:11to the beginning of the array.
04:13And here that *c that dereferences the pointer, and it gives us the value that's
04:19being pointed out which is a character c.
04:22Now the beauty of this is that because pointers are strongly typed in C, when I
04:27go and increment that, and I'll just do a postfix increment first, and we'll
04:33make a few copies of that, it will print the s, the t, and the r.
04:38And so we'll save that, and we'll run it, that's the s, the t, and the r.
04:42So what we are doing here is we are incrementing the pointer and then dereferencing it.
04:45So that seems really obvious, and it seems really straightforward.
04:49Here is where it gets interesting.
04:50If instead of a character array I make this an integer array, and we'll call
04:56this i1, and we'll initialize it to 1, 2, 3, 4 and 5, and then we'll make an
05:04integer pointer, and we'll initialize that to the beginning of the integer array
05:10and then these are going to dereference integers.
05:13So we use %d and ip for the integer pointer, and we'll do three of them just like that.
05:20So now what we have here is we have an integer array with five elements and they
05:24have integer values in them, 1, 2, 3, 4 and 5.
05:27We have an integer pointer ip which is initialized to point at the beginning
05:32of the integer array.
05:33So it's pointing at that first element which is the one, and we are incrementing
05:38that pointer and printing out each of the values.
05:42Now here's the interesting thing, an integer is four bytes.
05:46When we were doing this with characters each time we incremented the pointer, it
05:49would increment by one byte in the array to the next element to the array.
05:54Here these elements and the array are actually farther apart, they're four bytes
05:58apart rather than one byte apart.
06:00But the beauty is because the pointer is strongly typed it knows that when you
06:05use the increment operator it's going to increment not by one byte, but by the
06:09size of the object that it's pointing to, in this case, four bytes.
06:13So we will actually get 1, 2, and 3 just like we would expect, but the important
06:18thing to remember is that it's actually incrementing differently, it's
06:21incrementing by the size of the object that it points to, and it knows that size
06:25because the pointer itself is typed to point it an integer.
06:29So I am going to run this, and we'll see what we get the result that we
06:33expect, 1, 2, and 3.
06:34And just like with the integers we can use postfix or prefix increments and get
06:39exactly the same result.
06:41Here it has 2, 3, and 4 because it's incrementing before it's taking the value.
06:46So this usage is actually very common. You'll commonly see something like this.
06:55And I am going to terminate this with a 0 because that's the common pattern for that.
07:03So you will commonly see patterns like this where we have initialized a
07:06pointer to point at the beginning of the array, and we are going to loop
07:10through while there is still a value being pointed at, and we are going to
07:14increment that pointer.
07:15And you can use this for any type of an object as long as you have a terminator
07:19that you can test for.
07:20In this case, it will print out 1, 2, 3, 4 and 5.
07:24And because these pointers are strongly typed if you're able to just use
07:28the increment operator like this and let the pointer worry about how far to increment.
07:32So unary increment and decrement operators are very useful and very common.
07:38Keep in mind that the prefix version increments before returning the value and
07:42the postfix version increments after returning the value.
07:45Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using comparison (relational) operators
00:01The comparison operators are used to compare for equality or from relative value.
00:05Let's open a working copy of working. cpp, copy that and paste it into our
00:10Working project here in Eclipse and open it up in the editor.
00:14We'll start out by declaring a couple variables int x and int y, and we will
00:22just say if x>y, and we'll cout x greater than y and else x is not greater than y.
00:43So if I save that and run it we will get x is not greater than y, and we can
00:48delete this line down there, and that's because x is 5 and y is 6.
00:54So if I make x equals to 7 then we save it and run it, now we get x is greater than y.
01:01Also, test for equality.
01:03So if we can say if x == y, and that's a double equal sign, and say x equal to
01:15y and then here we can make this an else/if.
01:20And now if neither those is true then we know that x is less than y, and
01:26save that and run it.
01:30And we get x is greater than y, and if we make them the same, save that and run
01:36it, we get x equal to y. We can also test for inequality.
01:41So we can say x is not equal to y and test for that, and we can test for that
01:48separately when we still want to know if one is greater than the other, and
01:52we'll make y =9.x not equal to y, x is less than y.
01:56And if we make X = 9, then we just get x equal to y.
02:01There's also greater than or equal to which looks like this, and there's
02:06less than or equal to which looks like that . I'm just going to save that.
02:11So these are the comparison operators.
02:13They work of course on integers as we see, floating point.
02:16They work on any scale or type and they will even work of objects by overloading
02:21the operators, and we will talk about operator overloading later in the course.
02:25So the comparison operators are used to compare for relative value or for equality.
02:29They are simple and effective and they work on any scale or type.
02:33For a more complex type that may be overloaded and overloading operators is
02:37covered later in this course.
02:39So let's go ahead and delete working.cpp, press the Delete key, and Clean to get ready for the next lesson.
Collapse this transcript
Using logical operators
00:00The logical operators are distinct from the comparison operators or the bitwise
00:04operators, these are for logically combining conditions.
00:07Let's take a look at an example, we'll make a working copy of working.cpp out
00:12of the Chap06 folder of the ExerciseFiles and paste it into our Working project and open it up.
00:18First of all, to understand what a logical condition is if I say if(true), I
00:23have a logical condition that is true, and I'll just say puts("true");
00:28and else puts("false");, and if I save this and run it, it'll say true, and if
00:35change that true to false then it will say false.
00:39So true and false are keywords in C++ that represent a logical state.
00:45In regular C you can use 1 and 0.
00:47So if I say if(1) that will be true, and if I say if(0), that will be false.
00:55And you can have it be the result of a comparison or any kind of an operation
01:00really that returns a 0 or a not 0 value.
01:03So if I say int x = 7, and int y = 9, and then I can say if(x == y), and we
01:13would expect that to be false. All right! So that's what a logical condition is.
01:18It's really just the result of an expression that is either 0 or not 0.
01:23And for most intents and purposes it's the result of comparisons or things like
01:28that, that are either going to be true or they're going to be false.
01:31So for our purposes for testing these logical operators we're going to use true and false.
01:35Again this is a C++ idiom and does not work in C.
01:38And so if I say, if(true && true), since both of those things are true then the
01:45logical & of them is also true.
01:47So I can run that, and I get it true.
01:49And if I say if(true || true) and so OR is two vertical bar.
01:54One of them has to be true in order for this to be true, and so if I run that--
01:59I didn't save it, I'll go ahead and say Save--then it comes out as true.
02:03I am going to delete these lines because they are giving me warnings, there we go.
02:07Now if I say (false || false) then because both of these are false, we'll get a
02:14false as a result, it says false.
02:16If I say if(false || true) because one of them is true we'll get a true, save
02:22that and run it, and we get true.
02:24And if I say (false && false), that's two ampersands for AND, then that will
02:31be false because in order for & to be true both sides of it have to be true, so we get false.
02:36Finally, we have the logical NOT operator, which is simply an Exclamation Point.
02:41So if I say (!true) that's going to come out to be false.
02:45So I'll save that and run it, and it's false.
02:47If I say (!false) then it returns the inverse of that, which is true, and I'll
02:52save that and run it, and I get a true.
02:55So logical operators are NOT, which is a single Exclamation Point, and which is
02:59a double ampersand or OR which is a double vertical bar.
03:05The logical operators are simple and straightforward, they operate on logical
03:08conditions or they maybe overloaded for working with classes.
03:12Operator overloading is covered later in this course.
03:16So let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Exploring bitwise operators
00:00C and C++ provide Bitwise, Boolean, Arithmetic operators for use with integers.
00:06Let's start with a working copy of our working.cpp program, and we'll paste this
00:12into the Working project, and we'll create a couple of integers.
00:16These are unsigned integers x = 5, unsigned int y = 10.
00:24And I'm going to use printf so I can format this in hex.
00:27So %08x, and I'm going to do three of those and a new line, and that will be x
00:36and y and our operation, in this case we're going to go ahead and do x & y and a
00:41single ampersand is the bitwise and.
00:45And so what that'll do is it will go through the integer x and the integer y and
00:50bit by bit it'll compare the corresponding bit in the corresponding variable.
00:54And for the and operation if they're both set, then it'll set the bit in the result.
01:01Now, I happen to know that 5 is 0101 in binary and 10 is 1010 and so the and of
01:11these two will be 0, because they don't have any common bits set.
01:15So I'll save this, and I'll run it, and we see that the and is 0.
01:20So we have 5, we have a, which is hex for 10, and we have 0 as the result.
01:26On the other hand if we say or and that'll be true if the corresponding bits are set.
01:31And or is a single vertical bar, and this is a bitwise or so I'll save this and
01:36run it, and we see we get an f which is all the bits set.
01:40There is also an exclusive or exclusive or is the caret symbol, and this will
01:47set the result if the two operands are different.
01:49In other words, if a particular bit is set on x and clear on y, it'll be true.
01:54And if a particular bit is clear on x and set on y, it'll be true.
01:58So we'll save that and run it, and we see we get f again.
02:02There is also a bitwise not.
02:06And so that one look like this is a tilde, and that will simply flip all of the bits.
02:13So any bit that is set in x will be clearing the result and any bit that is
02:18cleared in x will be set in the result. And so when we run this, we'll see we get ffffa.
02:24There are also shift operators for shifting left.
02:27So this will take any bits that are set, and it will shift them left by four
02:31bits, and it will leave the bits clear to the right of all of that, and so we'll
02:36run that, and we see the result is 50.
02:41And we can do the same to the right, and I'm just going to change this to make
02:45it 0x50, and when we shift to the right it'll be 05.
02:52So in their natural state these bitwise operators only work on integers, but
02:57they can be overloaded to work on different types.
03:01Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with compound assignment operators
00:00As a convenience C and C++ support compound assignment operators that allow you
00:06to combine an assignment with an arithmetic operation.
00:09There are 10 of these operators they are for addition, subtraction,
00:13multiplication, division, modulus, bitwise shift left,
00:16bitwise was shift right bitwise and bitwise or and
00:21bitwise exclusive or. Let's take a look at how these work.
00:24Let's take a working copy of our working.cpp and paste that into our Working project.
00:32I'll double-click on that and open it up.
00:34So I'm going to come in here and declare a couple of integers int x and int y.
00:40And if I give them values I'll say x = 5 and y = 10.
00:46And now if I wanted to add x to y and put the result in x I could say
00:51something like x = x + y.
00:54And then I can print that out, I'll just use a printf for this, x is %d, and now
01:01our result should be something like 15.
01:04So I'll save that and run it, and it says x is 15.
01:08The equivalent way to do this with a compound assignment operator is to say x +=
01:14y, it looks much simpler and cleaner, and it gives us the same result, save it
01:18and run it and x is still 15.
01:21There's one important distinction though, in this other expression I'll just go
01:25ahead and I will put them both here as you can see them both really clearly.
01:29In x = x + y the x is actually evaluated twice and in x += y, x is
01:37only evaluated once.
01:39So here's an illustration of how this can have the impact.
01:42I'm going to create a very contrived function here.
01:44It's going to return an integer reference, remember references were covered
01:48in our last chapter. And I am going to pass it an integer reference.
01:53And I am just going to printf inside of it actually we can use a puts for
01:58this, puts this is f.
02:01And I'm just going to return an incremented i, so it'll increment it first
02:06and then return it.
02:08So whatever you pass this function it gets incremented and returned, but what gets
02:12incremented and returned is actually a reference to the original variables.
02:16The original variable itself will be what's return all right. All right!
02:20And so down here I am just going to delete these for now, and I will do
02:25that, that for now. And down here I say f(x) += 1.
02:32What its doing is it's taking that x, and it's incrementing it out here and also
02:37incrementing it inside of the function. So result should be self 7.
02:40All right we'll save that and run it and the result is 7.
02:45And actually x itself is also 7 at this point.
02:48So I'll just make a working copy of this, and I'll say x is, and I'll just put x there.
02:54And this one here is actually result it's not x.
02:57All right, and so if I save that and run it we see that x is now 7.
03:02And this is f that means we've evaluated that function once.
03:06Now if I were to do this instead and say f(x) = f(x) + 1, now this function is
03:14getting evaluated twice.
03:15Right? I'll save that and run it, result is 8 and x is 8.
03:20So that's to say that this x = x + y is not the same as x += y, ostensibly
03:29they do the same thing.
03:31But one of them evaluates x twice and one of them evaluate x only once.
03:35This can become significant in cases where you are using objects and what is
03:39going on inside of those objects may not be terribly apparent.
03:43And you need to know that when you're using a compound operator you're only
03:48evaluating that left-hand side once, whereas when you're using a separate
03:52operators for the mathematical operation and the assignment that you're actually
03:56evaluating that left-hand side twice.
03:59So the compound assignment operators as we know they're available for the 10
04:02operators plus minus multiplication division modulus shift left shift
04:08right and 3 bitwise logical operators and or and exclusive or.
04:13In most cases using the compound operator will be an advantage and the side
04:17effects will reduced. You just need to be aware of how it works.
04:20These compound assignment operators are there for convenience, feel free to
04:23use them whenever you would use the equivalent expression just be aware of the distinction.
04:28Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using the array subscript operator
00:00The array subscript operator is really very simple, let's take a look.
00:04Make a working copy of working.c and paste it into our Working project and open
00:10it up in the editor here.
00:12I'm going to start by defining an array, and we'll make an array of ints,
00:16because that seems pretty easy to do, and I'll just put some values in here, and
00:20then I'm just going to replace this with a printf here.
00:24We'll go ahead and we'll put in, say, ia sub 0, and so that's the subscript
00:29operator right there.
00:30The square brackets and the digit inside is the subscript and so, like so many
00:37things in C, it's normally written this way with those spaces, but you could
00:40put all these spaces around it, and it would still do exactly what it supposed to do.
00:45So I'll just save this and run it, and you can see, it says value is 1, which is
00:49the first element to the array and arrays are always zero-based and so the
00:53subscript operator will always start at zero for the first element of the array.
00:58Of course, you can also use an integer or any integer type, you could use
01:02anything character, short, integer, long, I am going to just use an integer
01:07because that's traditional, and I'll just give it a value of 3, and if we use
01:11that integer to subscript the array, C will get element number 3 which is the
01:15fourth element which will be number 4, save that and run it.
01:19Of course, if we were to make this a 5, and I'm not going to run that, I have
01:24no idea what will happen, and I hate surprises, because that is what's called undefined.
01:28There are five elements in the array and 5 would access the sixth element and
01:32so it would somewhere out here in nether-nether land, and we don't know what
01:37that would be, it could crash our program, it could create a security hole, it
01:40could allow people to come in and hijack our computer and send out bazillion
01:44pieces of spam with it.
01:45So we're not going to do that, but just know that subscripting past the end of
01:49an array is what's called undefined behavior.
01:51Now the subscript operator also works on STL containers.
01:56We're going to cover STL containers in a later chapter when we talk about the
01:59standard template library, but I just want to show you this right now because we
02:03actually commonly use an STL container, that is the string type in C++, people
02:08think of it as a type, it's really just an STL container, and it's part of the
02:12Standard Template Library.
02:13So I'd say string s = and just type the word string, and I come in here, and I'm
02:20going to change this to a character, because this is now going to be from s, and
02:25if I say s sub 5, now we have something there, that's the sixth element that'll
02:29the letter g, and I've got my integer 5, and I'm subscripting like this, and I
02:34just run it, and I actually get a letter g.
02:37So, you can subscript STL containers using the subscript operator even
02:42though they're not arrays.
02:43Why does that work, because the STL containers have overloaded the subscript
02:47operator and so you can do this too as you create your own objects, and we'll
02:51get into containers in a later chapter, and we will cover operator overloads
02:56in a later chapter, but just know that that's what's happening when you see
03:00that common pattern.
03:01So the subscript operator it used for indexing arrays and containers, and it's
03:06simple to use, you just need to remember that it's zero-based.
03:09So let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using pointers, members, and indirection operators
00:00C and C++ offer a number of operators for working with pointers and members
00:04of compound data structures, and I group these together because they're so
00:08often used together.
00:09Let's make a working copy of deref.cpp, and we'll paste that into our Working
00:15project and open it up in the editor here.
00:17Here we have a structure called S with a capital S, and it's got three
00:22members, and we've declared an initialized variable called lowercase s, and
00:27we've initialized it with 1, 2 and 3 and members a, b and c.
00:31And we're printing it out, if we go ahead and run that, we see s has members a,
00:36b and c as 1, 2 and 3.
00:39So this period in between the s and the a, and the s and the b and the s and c
00:45is actually a member operator.
00:47And it's for accessing the members of a structure or a class.
00:52And C++ structures and classes are almost exactly the same thing.
00:56We'll get into C++ structures and classes in a later chapter.
01:00But for purposes here we want to know how to use this operator to access members.
01:04And so it is an operator, in fact you can put spaces around it just like that
01:08just like any operator, and it still does exactly what you expect it to do just save and run.
01:15And so that's easy, that's how you access the members of a structure.
01:20Now suppose we have a pointer to this structure instead and so we say struct
01:24capital S* which is to declare pointer, and we'll call our pointer sp, and we'll
01:31assign it to the address of s, right.
01:35So this ampersand here is the address of operator, and it takes the address of
01:40that variable there, that s.
01:42And it allows that to be assigned and so here it's being assigned to this
01:46pointer of the same type so that works great.
01:48Now if I want to access those numbers through pointer I can say sp and use the
01:54pointer access operator and say a, and I'll just copy and paste that for the
01:59other two, it starts getting a little bit long, so we'll go ahead and we'll put
02:05it on a separate line here.
02:06And that will be c, and that will be b, and now we're dereferencing that
02:12through the pointer.
02:13So we are dereferencing the pointer and getting to the members all in one operator.
02:17And so this dash greater than operator, that's the operator there, so you
02:21can't have any spaces between those or to look like a minus and greater than
02:25and the compiler doesn't know what do you mean, you can see right away it's got the syntax error.
02:30But if I take that space out in between those two characters, now we have this
02:34pointer dereferencing operator, and that dereferences and gets to the member
02:38all in one operator.
02:39So I'll save that and run it, and we see we get exactly the same result.
02:44So if I make a copy of this and paste it in here, and we can use s.
02:51for each of these, so we can get at the members of the structure directly, and
02:57that's what the membership operator or we can get at them indirectly with the
03:01member dereference operator.
03:04Save that and run that you see we get the same result with both of those lines.
03:08So even see with no object-oriented extensions, it's so very common to
03:12dereference pointers to structures.
03:13In C++, structures and classes use the same syntax and are actually
03:18interchangeable, so these operators are very common there too.
03:22Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Exploring the function call operator
00:00The function call operator is used to make function calls.
00:03It can be used with functions, pointers and even with objects.
00:07Let's make a Working copy of funcop.cpp, and we'll paste that into our Working
00:12project and double-click on it to open it up in the editor.
00:16So here we have a simple little function.
00:18It takes an integer, and it returns an integer and so we've declared an integer
00:22here, and we're assigning to that integer from the function passing it a 47 and
00:27of course it will return a 47.
00:29So we'll go ahead and run that, and we see it says this is f, when it's running
00:34the function itself, and it says i is 47.
00:37So that's what we expect to have happen, and this is the function call operator.
00:43It's the parentheses, and you can put inside of the parentheses any arguments
00:46that you have to send to the function.
00:48Now if we were to declare a pointer to this function, show you a lot of what
00:54goes on here with that operator, so the function returns an int, and we need to
00:58know the exact function signature, because it will not work if we don't get that
01:02straight, and I'll show you what happens.
01:04So a pointer to a function looks like that, and I can assign to it, I can say
01:10pFunc = &f and remember the ampersand operator is the address of, so it's taking
01:16the address of our function called f.
01:18And so a function is effectively a type, and I have this variable of type
01:23function which is f, and it refers to this function here.
01:27I am simply taking the address of it, and I'm assigning it to this pointer.
01:30Now the syntax for the pointer to a function is admittedly a little bit obtuse,
01:36but it's not that hard to remember.
01:38You have the function pointer itself inside the parentheses, and that's just
01:41because if you just say *pFunc, it doesn't tell the compiler that this is a
01:47function type and so we need a pointer to the function type.
01:50So, we put it in the parentheses, and then we have whatever parameters reported
01:54that function signature and remember that the function type itself includes what
01:58it returns, and it includes the function signature what goes inside of the
02:02parentheses so that's all part of the function signature.
02:05So here we have a pointer to a function that returns an int and takes an int as a parameter.
02:10And I take that pointer, and I assign the address of the function to it,
02:13and then I call it.
02:15And so, I call it like this, and that will call the function through the pointer
02:20rather than directly.
02:21So we'll save this, and we'll run it, and we see that we get the exactly the same result.
02:26Now obviously we can do the assignment on the same line.
02:30So we do the initialization there, on the same line that we declare it, and that
02:34still works just fine.
02:35I'm going to save that and run it, and you'll notice that if I take this int out
02:40of the parentheses, I now have a different type and so it's not compatible, and
02:45that assignment will not work.
02:47So I'll save that and try to compile it and run it, and you see that I get
02:51an error right here.
02:53Invalid conversion from, and there you've got the two types.
02:56The function call operator is commonly used for calling a function, but as you
03:00can see, it's actually very powerful and flexible in its own.
03:03We'll cover function objects and overloading function operators in more detail
03:07later on in the Classes and Objects chapter.
03:09Let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with the ternary conditional operator
00:00The ternary conditional operator is a great name for a simple shortcut for
00:05choosing a value based on the condition.
00:07Let's make a working copy of working.cpp and paste this into our Working project
00:13and open up it on up.
00:14I'll go ahead here and declare a couple of variables int i=5 and int j=47, and
00:21then I am just going to change this to printf ("is the condition true? %s",).
00:29So what I need here is a c-string.
00:31I'm going to put this on a line by itself, and I'm going to say, if i > j ? "yes" : "no");.
00:42So that is the ternary conditional operator right there.
00:45See it's ternary because it has a left- hand side, it has a right-hand side, and
00:50it's got a middle side.
00:51So if the condition to the left of the question mark is true then the
00:56operator will return the first operand, and if it is not true then it will
01:01return the second operand. So if I save this and run is the condition true?
01:06No, because i is not greater than j. j is 47, i is 5.
01:11If I say it if i < j then the conditional return save it and run it, and it's true.
01:18So it's really very simple.
01:20It's kind of looks a little bit obtuse the first time you look at it, but it's
01:25very simple, and it's extremely convenient, because the alternative is to do a
01:28complicated if/else, and this is a simple expression that just returns either
01:33one or the other value. Very convenient.
01:35So this can be really handy in cases where you just need to select a scalar
01:40value, and you don't need the complexity of a block oriented if/else construct.
01:44This operator cannot be overloaded.
01:46The ternary conditional operator is a common shortcut for testing a simple
01:50condition with a simple scale result.
01:52So let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Determining the size of a type with sizeof
00:00The sizeof operator is used to determine the size of an object.
00:04Let's take a copy of working.cpp and paste it into a Working project.
00:09Double-click on that to open it up, and I'm going ahead and declare an integer,
00:15and I'm just going to take the size of that integer.
00:18So we will use printf for this, and we are going to use the sizeof operator.
00:23Sizeof is as an operator, and it seems a little strange sometimes that it
00:26would be an operator, because it's a word, and it's not a symbol, but still
00:30actually an operator.
00:31Now the size of operator returns a type called size T and If I go ahead and run
00:36this just like this.
00:38I am going to save this and run it, we will get a warning about a conversion
00:42from long unsigned int and to int.
00:45And that's because size T in this implementations is a long unsigned int.
00:49It can be different in implementations, and it's actually spelled size T.
00:54And I can put it here as the argument to sizeof, and because it's a type it has
00:59to go in parentheses.
01:00I can say size t like that, and I'm just going to cast this to in int, and that
01:05way the cast is explicit, and we won't get this warning anymore.
01:08So I'll save that and run it, and we see size is 8.
01:11So indeed it is a long unsigned int.
01:14So I can say size of int, and I'll get the result of that, and that's 4.
01:20So the number that size T returns is in bytes, and it's not in bits.
01:24So 4 bytes for size for the size of int, 8 bytes for a Long or for a size T.
01:29The operand here in the case of a variable I can just say size of i without the
01:35parentheses, and that works fine.
01:37Save that and run it.
01:39But if I'm taking the size of a type that it needs to be effectively cast.
01:44So we have to put that inside a parentheses. So I save that and run that, and that works.
01:48Of course, you can use it to take the size of other things if I declare
01:52struct, and I put a few things in it, a couple of ints, couple of chars, a
02:01couple of long ints, and then inside of here I can say size of struct S like that, a capital S.
02:08I am going to delete that int, because I am not using it anymore.
02:12Save that and run it, and we see the size is 32 bytes, and that's how much
02:16storage space it takes place for all of those different types.
02:19And of course, if I were to declare a variable of struck S, then I could put
02:24that in here, and I don't need the parentheses.
02:26I tend to use them anyway, because it just seems simpler to not have to remember
02:30when I need them, and when I don't, and it doesn't have anything to use them.
02:34So I save that and run it, and we get the same result.
02:38The size of operator can be useful whenever you need to find out how much memory
02:42is occupied by an object.
02:43It is commonly used for determining the amount of storage to allocate.
02:47So let's go ahead and delete our Working copy and run Clean to get set up for the next lesson.
Collapse this transcript
Determining the type of an object with typeid
00:00The typeid operator is only available in C++ it returns a type info object which
00:06is defined in the typeinfo header. Let's take a look at how this works.
00:10Make a working copy of typeid.cpp and paste it into our Working project and
00:15open it up in the editor here I'm going to just maximize this, so you can the
00:19see the whole thing.
00:20And you notice I have also included the type info header, its really only needed
00:24if you're using the members of the objects that typeid returns, but we're going
00:28to do that here so we will take a look at that.
00:31You notice I have got a couple of structs define they don't have anything in
00:35them, but they are still considered types and here I'm testing to see if the
00:39type of the variable a1 which is a struct A is the same as type of the struct A
00:45itself and so I should get either same or different in the result.
00:48Let's go ahead and save this and run it.
00:51You notice I get a few little warnings here for the variables I'm not using, and that's fine.
00:57And you see it says same.
00:58So the typeid of a1 which is this variable here is the same as the typeid of the structure.
01:05So this is really useful for finding out what type something is if it's this
01:09type or if it's that types.
01:10So if I checked to see if it's type of struck B, we can run that, and you see it is different.
01:16I can check to see if it's the same type as a2, which it is.
01:20So we'll save that and run it and see that it's the same, and I can check it
01:24against one of Bs, I'll check it against b2, save that and run it.
01:29And we see that one is different.
01:32So this is very useful and really easy to do, so if I really need to find out
01:37what type something is now I know how to do it.
01:40There's one other use for this, and I find it much less useful, that I'll show to anyone.
01:44So I'm using the name function member of the object that is returned by
01:50typeid, and this is just a shortcut for doing that without creating an extraneous variable.
01:55And so I'll save that and run it, and you see that it says 1a now my variable
02:01is called a1 and its type is struck A and so interestingly this says that the
02:08type name is 1A.
02:11So internally somewhere in the compiler that's the way it's keeping track of it.
02:15Different implementations will print out different things for this, so I find it
02:19less than entirely useful.
02:21If I take the type of say an int, save that and run it, you see I get a letter
02:28I, and if I say take the typeid of struct B the save that.
02:35And if you get this launch working you can always just press always run the
02:39background if like I am just going to put the run on the background button.
02:43And I get 1B so that's kind of what I'd expect.
02:46Let's take one more, let's say the typeid of the string object rather the string
02:51class and save that and run it, and I see a capital and a lower case.
02:58And so we see that what we get out of here that's not going to be consistent across implementations.
03:02And really we can find whatever we need to find out by comparing it to the types
03:06that we think something might be.
03:08So the typeid operator is only available in C++, and it is not available in C,
03:13it returns a type info object, and you can use the name function member of that
03:17if you like, and that is defined in the typeinfo header.
03:22So now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using the cast operator
00:00The cast operator is used to convert an object of one type to another compatible type.
00:06Let's make a working copy of our working.cpp and paste it here into our Working
00:12project and double-click on it to open it up.
00:15So I am going to go ahead and create a variable of type int, and I'm going
00:19assign to that size of int.
00:23I know the sizeof returns a size T value, which on this machine with this
00:29compiler is an unsigned long int.
00:32I am going to go ahead and printf out " value is %d\n" i, and we will save that
00:40and run it and see what happens. Now that runs just fine, and it says value is 4.
00:45Now if instead here I just take this, and I put it there, interesting things happen.
00:52Save this and run it. This launching thing comes up.
00:57You can just hit the Always run in background if you like.
01:00I'm just going to hit the Run in background.
01:02And it says values for, and I get a little warning here, and you notice the
01:06warning says format "%d" expects argument of type "int", but argument 2 has
01:09type long unsigned int".
01:11So what we have here is a slight incompatibility, and it's really just a
01:15warning, and it's not a big deal along int converts just fine to an int.
01:18You lose some information, but sizeof isn't really returning any numbers that
01:22are big enough for that to matter.
01:25So the way that I get around this is I tell the compiler use this as if it's an int.
01:30Go ahead and make sure you convert this to an int, and I do that by putting
01:36the word int in parentheses left of the thing that I wanted to force a conversion on.
01:40Just like that.
01:41I save that, and I run it, and it solves the problem.
01:44My warning goes away.
01:45So this is called a cast, and this is the traditional C form of cast which is to
01:50put the type in parentheses to the left of the object that you want to convert,
01:55and that's the formula I used them most often.
01:58There's also another version, that is C++ only, and that is to take the type and
02:03put the value in the parentheses instead, and that looks like that, and I can
02:07save that and run it, and it works exactly the same.
02:10So this form looks like I'm declaring a variable of a class is what it looks like.
02:17For some people that might be a more familiar paradigm.
02:20I'm an old C programmer from way back, so I like this one.
02:23Really, it's just a matter of style.
02:25The other thing I like about using the C form is that it's compatible.
02:29I can use it both in C, and I can use in C++ and the function form is
02:34only usable in C++.
02:37The cast operator is used to force a type conversion between two compatible types.
02:42There are two forms, the traditional C form that puts the type in parentheses or
02:46the newer C++ function form which puts the value in parenthesis.
02:51You may use whichever form works for you.
02:54Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with the new and delete operators
00:00The new and delete operators are used to allocate and free memory in C++.
00:06Let's make a working copy of new-delete.cpp and paste it in our Working project
00:12and open that up on.
00:14I'm going ahead and maximize this so you can see the whole thing, and let's take
00:17a look at how this works.
00:19You notice that I am also including C standard def, and that's because the null
00:23constant exists in that header file in C++.
00:26In C it's usually kind of declared everywhere, because it uses it so much.
00:32We start out here at the top, we use the new operator to allocate memory
00:37for count integers.
00:39So there is int, and there is count and our count is 100.
00:43So this will allocate space for a hundred integers.
00:45The new operator takes as operand a type and optionally a count in square
00:52brackets to tell you how many.
00:53So if I were to just say new int like this, it would allocate space for one
00:57integer, and this allocate space for count integers which is a hundred and the
01:03new operator returns a pointer.
01:05So in this case I am declaring and initializing a pointer to int called IP.
01:11I'll then check if IP equals null, and if it does I put out an error message
01:16that new failed, and I return a failure code.
01:19Otherwise, I step through a count pointers incrementing the pointers and
01:24populate this data structure with integers, and then I print them out.
01:29Then I use Delete to delete the space.
01:32It's important for every new that there be a corresponding delete.
01:36If I allocate something with new, and I do not delete it with Delete I'm going
01:40to have a leaky program, and it's going to crash and have weird problems.
01:44So whenever you use new it's important to also use Delete.
01:47So we will go ahead and put this back and save it and run it, and we see that we
01:52have 100 integers printing.
01:55Now if I go ahead and make this a really big number, and I'm going to make this
02:00fifteen zeros-- One two three four five, one two three four five, one two three four five.
02:06Let's save that and run it. I get an exception.
02:09It says is malloc size blah, blah, blah failed.
02:12Set a breakpoint, terminate after throwing an instance of bad_alloc.
02:17So we got an exception, and we didn't really get to get to our test here to
02:22see if new failed.
02:24So there is an option to new called nothrow which you put in parentheses after
02:31the keyword and before the type, and I'll go ahead and save this and run it, and
02:35you'll notice the GCC isn't really obeying here.
02:39It still gives me its error message, but it's not throwing the exception.
02:45It still prints out the error message though. That's not terribly useful.
02:48But you notice I do get my new failed, because I am able to actually test for new failed.
02:53So the new operator is used for allocating space for objects in C++.
02:59Every object allocated with the new operator must be destroyed with Delete,
03:03otherwise your program will leak memory.
03:06So let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Understanding operator precedence
00:00Operator precedence is the order in which operators are evaluated in an expression.
00:05This expression could have different results depending on what order it's evaluated in.
00:10For example, using parentheses to bind parts of the expression together if we
00:14give precedence to the addition then the multiplication, we get this result.
00:19And if we move the parentheses around a bit, we get a different result.
00:22And if we remove the parentheses we can get yet a different result.
00:27The order of evaluation without any parentheses is that the division happens
00:31first, then the multiplication, and then the addition.
00:34It's as if it were parenthesized like this.
00:37The point of understanding operator precedence is to be aware of the rules.
00:41You don't need to memorize the rules,
00:43there are plenty of handy reference tables available, but you do need to know
00:47that this is how it works.
00:49Ultimately, if you care about the order of evaluation of an expression it's
00:53always best to use the parentheses.
00:56So here in your ExerciseFiles there's a PDF file that is an Operator Precedence table.
01:01I am just going to maximize it up here so that you can see it.
01:05I've included a copy of this in the ExerciseFiles or it's easy to find online.
01:09I keep a laminated copy of this actually by my workstation just for quick
01:13and easy reference.
01:15So this shows all of the operators available in both C/C++ with the highest
01:20precedence operators at the top and the lowest at the bottom.
01:23So if we have an expression that has several operators in it, the ones that are
01:28closest to the top here will give evaluated first, and the ones that are closer
01:33to the bottom will get evaluated last.
01:36Here's a simplified version of the operator precedence table.
01:39Most operators are evaluated left to right except prefix unary and assignment
01:44operators which are evaluated right to left.
01:47It's important to understand operator precedence, but it's not so important to memorize it.
01:52Most of the time it's a good idea to use parentheses to specify the order you
01:56want your expressions to be evaluated in, and it's easy to keep a chart near
02:00your workstation for when you need to read someone else's code who may not have
02:04been so considerate as to use parentheses.
Collapse this transcript
Using operator synonyms
00:00C++ provides a few interesting synonyms for some of the logical and bitwise operators.
00:06Let's take a look at how these work.
00:08Let's make a working copy of working.cpp and paste that into our Working project.
00:14Open it up in the editor, and let's consider this expression here.
00:18I am going to declare and initialize a couple of integers.
00:26So, that's fairly simple. We have two integers, a and b.
00:29One of them is false, one of them is true, and then we test if they're both true
00:34with the And operator, that's the logical And the &&.
00:38And if they're true, we'll put a true, and if they're false, well, I will put a false, very simple.
00:43We'll go ahead and delete this line down here, save it and compile and run, and
00:48we see we get the result false.
00:50Now, using an operator synonym, I can take this && for And, and I can make it
00:57into the much more human friendly word and you see even Eclipse knows about
01:02it and highlights it.
01:04Then I can save this, and I can run it, and we get exactly the same result. Very slick, right?
01:09Now, consider this expression.
01:14Look how funny Eclipse gets when I forget a semicolon.
01:19So, if I go ahead and save this and run it, we get this 32, and this is the
01:25bitwise And of and b.
01:28There's another handy-dandy synonym, it's called bitand, and I can put it there,
01:33and save this, and run it, and you see we get the same result.
01:38Now, if I were to simply forget to type this a here and just accidentally type c = bitand b
01:45and save it and run it, look at the error that I get.
01:51It says I'm trying an invalid conversion from an integer pointer to an int.
01:56That doesn't seem like what it is that I'm trying to do.
01:59There's a reason for that.
02:00The reason for that is that bitand is not actually a synonym, it's a text alias.
02:05If I replace this with the &, you'll notice that what it is is that I'm trying
02:11to assign the address of b to c, and so bitand is not really a synonym for the
02:18bitwise And operator, it's actually just a text alias.
02:22This is very, very confusing, and the problem gets even worse.
02:26If I do something like this, and I save this and run it, look at that, no error at all.
02:31C equals 112, because what this is again, if I take that bitand out, and I put
02:37in an ampersand, we see it's simply a reference.
02:40I've declared a reference, a C reference, and I've assigned it to b, which is
02:44perfectly legal, and bitand makes no sense there whatsoever.
02:48So, it's very important to understand how this works.
02:51Officially, these are synonyms for logical operators, but in reality, they're
02:55text aliases just like macro expansion.
02:58Frankly, I don't see their value, and I never use them, and I suggest that you
03:02don't use them either. But if you do choose to use them, be careful.
03:06This is a table of the operator synonyms that are defined in the C++ language.
03:10Keep in mind that these synonyms are actually text aliases, and they can be a bit dangerous.
03:16Because it doesn't really add anything substantive to the language, and it can
03:19provide confusion, I recommend that you do not use this feature.
03:23Now, let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
7. Defining Functions
Overview of functional programming
00:00Functions are fundamental to both C and C++, even C++ as object-oriented
00:06programming model C functions with the basis of class methods.
00:11All code in a C or C++ program happens in functions, starting with the main function.
00:17In C and C++, functions are blocks of code that may be called by and may return
00:23values to other code.
00:26This is analogous to procedures or subroutines in other programming languages.
00:30Functions allow you to generalize and modularize your code by creating
00:34containers for logical subsets of code and by allowing code to be reused.
00:41In C and C++ arguments are always passed to functions by value.
00:46So when you call a function pass it a variable, a copy of the content of the
00:50variable is passed to the function.
00:52If the function then changes that value the caller's copy remains unchanged.
00:56For example, here we have a variable a, with the value 1, this variable is
01:02passed to a function f, after the function returns we print the value.
01:07Here is the function which takes that value and assigns it to a local
01:12variable also named a.
01:15But this is absolutely a different variable, it's in a different scope, and it's
01:19separate in every way.
01:21The value 1 is copied and passed to the function, so when a is incremented in
01:27the function only its local copy is affected, the caller's copy remains
01:31unchanged and the printf will print the number 1.
01:35The alternative to call by value is call by reference.
01:38To implement call by reference you must do so explicitly, the advantage here is
01:43you will know by reading the code that a reference is being passed and they are
01:47very likely be side-effects.
01:49In this example the Ampersand of the function call parameter means to pass a
01:54pointer to a, instead of the value of a.
01:56The Ampersand is called the reference operator or sometimes the address of operator.
02:02And in the function the variable p carries as its value a pointer to a, so
02:08we want to increment the value of a, we do so by dereferencing the pointer,
02:12the Asterisk is called the Indirection Operator or sometimes the dereference operator.
02:17So this time by passing a pointer we're explicitly using call by reference,
02:22and the value in the caller's variable a will be incremented and the printf
02:27will print the number 2.
02:28In C++ you may also use the reference type to implement call by reference.
02:34This makes call by reference appear more implicit, this feature is not available in C.
02:39In C++ functions are identified by their function signature.
02:45In C++ this function which returns the volume of a cuboid is different than
02:51this function which returns the volume of a sphere, even though the two
02:54functions have the same name.
02:56The return type, the name of the function, and the types of the function
03:00arguments are all combined to form the function signature.
03:03This function signature is used to identify the function.
03:07In C this distinction does not exist and these two functions would cause a name
03:11collision, because a function is identified only by its name in C.
03:18Understanding functions is fundamental to both C and C++, even in C++ is
03:23object-oriented programming model, C functions are the basis of class methods,
03:28all code in a C/C++ program happens in functions.
Collapse this transcript
Defining a function
00:00Defining your own functions is a fundamental part of C and C++ programming.
00:05Let's take a look at how this is doing.
00:07I am going to start by making a working copy of func.c. I am going to use the C
00:12version here, not the C++ version and paste that into our Working project and
00:17open it up in the editor.
00:18Now we're using C for this example, because it's the lowest common denominator
00:24but this is exactly the same in both C and C++, and it's a fundamental building
00:29block of all C and C++ programs.
00:33In fact, the function is the basis of methods in C++ classes.
00:38As you'll learn when we cover C++ classes and objects later on.
00:42So here we have a simple function. It's called func.
00:45It returns void which means that it does not return a value at all, and it
00:50takes no arguments.
00:52In fact, inside of the parentheses there we could put the word void in the
00:56definition and also down here where it's actually defined.
01:01The above is actually a declaration, not a definition.
01:04We can put the word void there, and that would mean the same thing that it does
01:08not take any arguments, but this is commonly done this way.
01:12So we're doing it this way this time.
01:15So if we save this and run it, you'll see that it runs the function and the
01:20function is defined down here.
01:21It's declared up above, and it's defined down after the main, and it has this
01:26printf in it that prints the words this is func.
01:30Now the reason for this is because it's called before it's defined.
01:33So it's called here in main, and it's defined here after main.
01:38In order for that to work we have to declare it before the place where
01:43it's actually used.
01:44If I were to remove this declaration, and I can just comment it out here with a
01:49couple of slashes and try to compile it and run it, you see we get errors.
01:55And these warnings, they say implicit declaration.
01:58Now in this case the compiler is being a little bit forgiving, and it's allowing
02:03us to do it, but in reality this is not allowed at all.
02:07So declare your functions before you use them, and you can avoid the entire need
02:13for a declaration by simply putting the function above the main and defining it
02:18there, and now when we run this we don't need the forward declaration at all.
02:22It just works because the entire function is defined before it's used.
02:26So this declaration here, which just has the function signature, this is called
02:32a forward declaration and these are typically put in header files.
02:36So that's how you define and declare a function.
02:39We'll get into many more details throughout this chapter.
02:41Now let's delete our func.c from our Working project, and we will run Clean to
02:48get ready for the next lesson.
Collapse this transcript
Passing parameters to a function
00:00Parameters are passed to functions by declaring them inside the parentheses
00:04of the function definition.
00:06Let's take a working copy of func.cpp we'll use the C++ version this time and
00:12paste into our Working project and open it in the editor, you see this is
00:16exactly the same as func.c with the difference that we're including iostream
00:21up here instead of stdio.h. So let's save this and run it and see there's
00:26working that's great.
00:29And now let's go ahead and pass a parameter, so we'll start by changing our
00:32function declaration, and we will save it, its going to take an int and so we
00:38just put the type inside of the function signature there.
00:41And then down here in the actual definition we can give the int a Name, and then
00:47we just printed inside here, I want to say i is %d and put the i in
00:56here, and we'll say in func so we know.
01:00And now you'll notice that we have a little bug mark next to our function
01:04call here because our function signature shows it with an int.
01:08So given an int here we'll have to define 1, we'll give it a value, and we'll
01:15just put that in here.
01:18So I'll save this and run it, and you see we're successfully passing our integer
01:24value into the function.
01:27So in C and C++ functions always passed by value, so what that means is is that
01:34when I make this function call with the i in it, it actually makes a copy
01:39of that i and passes the copy into the function and inside the
01:43function the copy is called i and so this is a copy that's being used
01:47inside the function.
01:49So if I come in here, and I say, i = 132 and then after the function call
01:55out here I print it, save that and run it, and you see that this i is unchanged
02:02it's still 7, inside the function it's 132.
02:07Now if you actually want to affect the variable outside of the function then you
02:11need to pass a pointer or reference.
02:14And so here we can call this a pointer we'll call int pointer like that and
02:19here we'll call int pointer like that.
02:22And now we're going to use what's pointed at by the pointer not the pointer
02:26itself, by dereferencing with the deference operator.
02:31And I need to pass an address instead of the actual variable here.
02:37So now I am passing the address to i, and I am changing i inside of the
02:41function and so we would accepted to be change in both those printfs there, and
02:47there it certainly is.
02:48Now if you're using C++ you can do this with references instead of pointers
02:54and the advantage and disadvantage of references is that this syntax is much simpler.
02:59So if I change that to a reference there, here I no longer need to send the
03:05address, I just put the variable there and the compiler will go ahead and create
03:09the pointer for me and here instead of the asterisk I am going to have the
03:15ampersand so for it to be a reference.
03:17And now I just use it as if it were straight variable and not a pointer at all.
03:22So the semantics is different and the effect is the same.
03:26Save this and run it, and you see we still have our side effects, we are
03:30still actually changing this variable, and we just don't have all that syntax around it.
03:35The only thing we've changed here is the function signatures.
03:39References are available in C++ they are not available in the C.
03:44Now function calls always passed by value if you pass a reference or a pointer
03:48it's the value of the reference or the pointer that you're passing.
03:52References make this almost completely invisible and therefore more prone to
03:56error, but the function call is still passing a value.
04:00Now given that functions are strictly passed by value when you are passing
04:03something big you'll always want to use a reference or a pointer.
04:07For example, here if I declare a string, that's a really big string with lots of
04:12text in it, and I can pass that as a reference.
04:20So now here I am going to get rid of that integer, and I'm going to pass my string instead
04:26and here we will just display the string here.
04:31And down here in the function we're going to take a string instead of integer,
04:39we need to take the c_str of the string in order use in printf or we could just
04:45used a cout, like that.
04:49And the same thing here, here we will just take the c_str of it.
04:54So you can see both ways to do that.
04:56So now we'll go ahead and compile this and run it, and you'll see we're passing
05:01our string into the function.
05:02Now the probably with this is, is that we're actually passing a reference to the
05:07string so now it's possible for the function to actually modify the string, and
05:12we don't necessarily need for that to happen.
05:14So we're going to change our signature, and it's a good habit to get in every
05:19time you are using a reference to use the keyword const, and this prevents
05:24accidents from happening with side effects.
05:26So we'll save this run it, and we see that, that's how you pass a larger object
05:32into a function using a reference.
05:35Parameters are always passed by value in C and C++.
05:39you can pass pointers or references if you need side effects, but you will
05:42need to do explicitly.
05:44So let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using automatic and static variables
00:01Variables declared in a function default to automatic storage.
00:05Other storage options are available.
00:07Let's make a working copy of func.cpp and paste it in our Working project here
00:12and open up in the editor.
00:14I'm going come down here in our function, and I'm just going to declare
00:17an integer, and as I print it I am going to also increment it, and I'll
00:25do a posting comment on it, and that way every time it's called it will get incremented.
00:29And we will just call it five times here, and we'll save that and run it, and we
00:34get five times that it's 5, and you will notice that each time I print I go
00:39ahead and increment it, but the next time I print it it's 5 again.
00:42The reason for that is this is in temporary storage.
00:45Automatic storage is stored on the stack which is created fresh for each
00:48invocation of a function.
00:50So the value is not carried from one invocation to the other.
00:54If on the other hand I declare this as being static storage then I save that and
01:00run it with no other changes you'll notice that it gets incremented every time.
01:05Static storage is not stored on the stack. It's not temporary.
01:09It's persistent for life of the process.
01:11Now the value is carried from one invocation to another.
01:15Static storage is typically used for keeping state and for other purposes where
01:19you just need to keep the storage around.
01:20Variables declared in a function default to auto storage if you want your data to
01:26be persistent, you may declare your variables as static.
01:28For more storage class options see the movie on data type qualifiers in Chap05.
01:33Now we'll delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using function pointers
00:00Function pointers can be really convenient in a number of circumstances, let's
00:04take a look at an example.
00:06Let's make a working copy of func.c, place that in our Working project and here
00:13we have just a simple function, doesn't take any parameters, doesn't return
00:16anything, and we are calling it like this.
00:20So if we compile this and run it, you see it prints out this is a func().
00:23Now instead of calling it like this I can create a pointer, and I can call it
00:28through the pointer.
00:29I can say void (*func) like that = --look now I am reusing the name there--
00:36I don't want to do that I am going to call this fptr, and then I can run it like
00:41this, and that will actually call the function.
00:45So let's compile this and run it, and we see we have exactly the same result.
00:49So the difference here is that I've declared a pointer, and I am calling the
00:53function through the pointer.
00:54The syntax of the function pointer might look a little bit obscure, well,
00:57it is a little bit obscure.
00:59And you'll notice that the pointer operator and the name of the function are
01:03inside of parentheses, and that's like that because of operator precedence and
01:07then the function operator is on the outside of the parentheses.
01:10So this indicates that we have a function pointer, and we call it with
01:14exactly the same syntax. And that's true with so many other things.
01:17We do reference a pointer with exactly the same syntax that we declare a pointer with.
01:22So that's what a function pointer looks like, and that's how a function pointer works.
01:27Let's take a look at this in action, see what it might actually be useful for.
01:30We'll close this, and we'll delete our working copy of func.c and run Clean,
01:36because we are going to use a different source file here.
01:40And I am going to bring in jump.c, so we'll copy that and paste it into Working
01:46project and bring it up here.
01:48I am going to walk through this in a second here, let me just show it to the
01:53folks who might be typing along at home.
01:55Now I am going to compile this and run it, and you'll see what it does.
01:59It basically puts up a menu.
02:00I am going to maximize this so you can see what it does here.
02:02And if I type a 1, Eclipse is a little bit funny with this, you'll notice
02:06that the cursor is up at the top but when I press the 1 it actually goes after the prompt.
02:10That's just Eclipse, on a real console this will work just fine.
02:14I am going to press 1, and you'll see it runs Function a, which says this is a.
02:18And if I press a 3 you see it runs function c, it says this is c.
02:23If I press something out of range, if I press like a 7 it says invalid choice.
02:28And if I press q, it will actually quit.
02:32So let's bring this back down, and let's take a look at the code and see how all this works.
02:38So we have these five little functions here, and then we have forward
02:41declarations for a couple of functions that we'll look at later.
02:44And then what we have here on line 13 is we have an array of function pointers.
02:49The array is called funcs, and you'll notice that inside that first set of
02:55parentheses there is the asterisk which indicates it is a pointer,
02:58there's variable name which is funcs.
03:01And there is the square brackets, which means that it's declaring an array, and
03:07then we close out those parenthesis, and we have the function operator on the
03:11outside, and this basically says that well this is the way that you declare an
03:15array of function pointers.
03:17Then we initialize the array of function pointers with the addresses of these
03:22five functions and a null pointer to terminate the array, because this is C,
03:26it's not C++, and this is not an object vector, this is a simple C-array with
03:33five pointers in it and a null pointer.
03:37Then main calls the function prompt, and then it says done when it's done
03:41because prompt will turn around and call jump, which actually uses this jump table.
03:45So this structure, this array of function pointers is sometimes called jump
03:49table, and it can actually be really, really convenient for console-based
03:52applications that use a menu, or I've even used in CGI applications where I
03:59have a number of different possible options that depend on a variable getting past through CGI.
04:04So there is the prompt function which basically puts out the prompt which is
04:09that menu and the little prompt characters there, and it gets the response using
04:15fgetln, and it calls jump, and it returns the return value from jump.
04:20Now the jump function, this is where the work is actually done.
04:24It takes the response from the keyboard, and it decides if it's a q or not, and
04:29if it's a q then it returns 0, which means that we're done.
04:33And otherwise it uses this little for loop to get the length of the array.
04:38Line 47 is just a little trick for converting a character into an integer.
04:43The first character of the response string,
04:45it simply subtracts the value of 0 of the ASCII character 0, and then it's got
04:51an integer, it's got a 0 based integer.
04:53And it checks to make sure that it's a valid number that less than 0 or greater
04:57than 8 is checking to make sure it's a valid number.
05:00We've decremented 1, because our number 1 is going to be the zeroth element of our array.
05:06And then down here starting at line 54, we check to see if we are in range, if
05:11we have that many elements in our array. And if so, we go ahead and call the function.
05:16And on line 55 there, it's calling the function from the array, so we have i as
05:22the index into the array and the function operator at the end, the parentheses
05:28tells it to call the function based on that pointer.
05:30So this is a really, really simple way to implement a menu in a console-based
05:35application or to implement any kind of a jump table where you might want to be
05:40calling different functions based on a piece of data.
05:43Now of course this works just as well in C++, and let's just take a quick
05:49look at this in C++.
05:50We are going to go ahead and delete our working copy of jump.c, and we will run
05:54Clean, and we'll make a working copy of jump.cpp and paste it here into our
06:00Working directory and open it up, and we'll run it.
06:04And you can see here this works exactly the same, if I type 1 I get this is a, 2
06:10this is b, 5 this is e. If I type 6, I get invalid choice.
06:16If I type a q, it quits.
06:18So this works exactly the same, it's mostly the same code.
06:22You'll see our functions look exactly the same.
06:25Instead of our jump table in an array we're actually using an STL vector here,
06:31and we'll cover this in the chapter on STL, but basically that's how you declare a vector.
06:36And the type is a pointer to a void function so that's the type that goes in the
06:41template for the vector.
06:43We just have the 5 here because this is a vector, and it knows how long it is we
06:47don't need that terminator. The Prompt is pretty much the same,
06:50we are using cout instead of printf, because this is really convenient to be
06:54able to do cout like that, all in one statement with one semicolon.
06:59And our string response cin, this is actually all a whole lot simpler than it is in C.
07:04And our jump function is almost exactly the same.
07:08You notice we are able to test against the size of the vector using the size
07:13method out of the vector, so we don't have to figure how long it is.
07:16And we are calling it, exactly the same way that we would call it out of the array.
07:21So that's how you create a jump table using an STL container in C++.
07:26So function pointers can be really useful, you're not going to need them often,
07:30but when you do it's really convenient to know how to use them.
07:33Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Overloading function names
00:00In C++ it's possible to have different functions with the same name.
00:04The compiler selects would function call based on the entire function signature,
00:08not just the function name. Let's take a look at this feature.
00:12We will open func-overload.cpp, and we'll paste that into the Working project
00:19and double-click on it to open it in the editor.
00:22I'll just maximize this so we can take a look at it and scroll down so you can see the whole thing.
00:29In this program you'll notice I have three functions, each of them called volume.
00:36They differ by their function signatures.
00:37A function signature includes the return type, the function name, and the type and number of parameters.
00:44So here we have int volume int, here we have double volume double int, and here
00:50we have long volume long, long, long.
00:53So those are three different functions in C++. In C this just does not work.
00:57In C functions are identified only by the function name, and this would cause a
01:01name collision, and it would not compile. But here it works fine.
01:05The first one calculates the volume of a cube, and it only takes one integer
01:09for the dimensions of the one side and all three dimensions of a cube are the same by definition.
01:15The second one calculates the volume of a cylinder.
01:18So it takes the radius and the height of the cylinder.
01:22And the third returns the volume of a cuboid where the length, width, and height
01:27are all different numbers, and it simply multiples them together and returns the volume of the cuboid.
01:32So they're all called volume, and you can see down here in main where they're
01:36called, this one is just called with one integer, this one is called with a
01:41floating point and an integer, and this one is called with three integer.
01:45So the compiler knows which one based on the number and types of parameters, it knows which one to call.
01:53So let's go ahead and run this.
01:56Compile and run, and we see cube of 2 is 8, cylinder of 2 x 2 is 25.1327, and a
02:05cuboid of 2 x 3 x 4 is 24.
02:09So there are some rules to this, like the return type cannot be the only
02:12distinguishing factor, but the constant of the return type can be and often is.
02:17And there are rules about how types are promoted to distinct parameters, so it's
02:20a good idea to test your overloaded functions thoroughly, and keep in mind that
02:24none of this applies to C.
02:26In C a function is distinguished only by its name, and this example would not compile.
02:31So in C++ functions are distinguished by their function signature.
02:35So it's possible to have multiple functions with the same name that operate with
02:39different parameters and with return types.
02:42Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Overloading operators with functions
00:00When you're dealing with simple built-in scale or values, it's usually pretty
00:04obvious what most operators will do, 2+2 will generally get you 4.
00:09But when you're dealing with classes in C++, it's not obvious at all.
00:13In fact, C++ operators don't work with classes unless you tell them how.
00:18For this purpose, you'll want to write your own code for some operators, this is
00:21called Operator Overloading.
00:23There are basically two ways to overload operators in C++, one is with class
00:28methods, the other is with functions.
00:31In this movie, we'll discuss overloading operators with functions.
00:34We'll discuss C++ class methods in the chapter on C++ classes and objects.
00:40Let's make a working copy of func-operator.cpp, and I'll paste that into my
00:46Working Project and open it up in editor.
00:48I'm going to double-click on this to maximize it so that we can see the entire file.
00:54Here we have a simple contrived class called class A.
00:59Down here in main I'm declaring two objects of class A, one of them is a is one of them is b.
01:05One of them has a value 5, and one of them has a value 42.
01:08This class simply contains an integer and initializes the integer and will
01:12return the value with the class method value.
01:16So if we want to add these two objects together like on line 20, we need to
01:20overload the Plus operator.
01:22So there in line 12 is the operator overload, and it's constructed like this:
01:26int is the return value, the operator keyword tells the compiler that this is an
01:33operator overload, and then the Plus symbol is the operator being overloaded.
01:38The parameters left-hand side and right-hand side are both references to an
01:43object of class A, and on line 14 we use the value method which is called an
01:50accessor, because it's used to access a private variable.
01:53So we use the value method to get the value of the integer a from inside the
01:59class A, that integer is declared on line 6, and we add those two values
02:04together and return the result.
02:07So it's really a very simple function, and it works effectively.
02:10Let's go ahead and run it.
02:12Bring this back down to size, and I'm going to click on the big green Compile
02:17and Run button, and you see here the first line of our results says "operator + for class A",
02:23and that's simply this cout on line 13, and then it returns a value.
02:28That just tells us that the method is getting called.
02:31And where is that method getting called? It's getting called right here.
02:35When we add up these two objects, the Compiler sees that, and it looks for an
02:40operator + overload that takes those two types as its arguments, and so here
02:45we have left-hand side and right-hand side, and so it calls that function, and it
02:50returns the value as the result of that expression.
02:55So this feature of course is not available for built-in types, so I can't create
02:59an Operator Overload for two ints, for example.
03:02Well, I can see where that may be an entertaining thing to do, it wouldn't
03:06really be useful or a very good idea. So you can see this is pretty easy to do.
03:10As I said, this is only half of the story. For the rest of it be sure to watch
03:15the movie on Operator Overloading in the chapter on Classes and Objects.
03:19Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Defining a variable number of arguments
00:00For those times when you need a function that may take a varying number of
00:04arguments, C and C++ provide variadic functions.
00:07Let's get a working copy of variadic.c, and we'll paste this into the Working
00:13project, and I'll go ahead and maximize this by double-clicking on that tab at
00:17the top, and scroll down so you can see the whole thing.
00:21So, you notice on line 3, I'm including a header called standard arg dot H, stdarg.h.
00:28In C++, the equivalent header is cstdarg.h, and of course, this technique works in both C and C++.
00:37We're showing the demonstration in C this time.
00:39So this file shows two examples of variadic functions,
00:43an average function for computing the average of a variable number of
00:47arguments, and a message function that actually passes the variadic arguments
00:52on to another function called vfprintf, and this is actually how functions like printf are implemented.
00:59So, starting with the average function, you'll notice on line 7, I declare a
01:03variable called ap that's of type va_list.
01:06va_list is actually a macro that's used for implementing the variable argument list.
01:13Every function that uses a variable argument list must declare a variable of
01:16this type, and must also call va_start and va_end.
01:20va_list, va_start, and va_end are defined in stdarg. va_list is actually a typedef.
01:27So, on line 11, we call va_start, and this is actually a macro.
01:31The first argument is the va_list itself, and the second argument is the last
01:36parameter in the parameter list before the "...".
01:40Now, looking at our parameter list, you'll notice that, that "...", that
01:45indicates the variable argument list, and that's actually three dots.
01:49It's not a single character that represents an ellipsis that you might get as an
01:54automatic replacement in a text editor or a word processor.
01:56This is actually three dots, there's no space between the dots, and these three
02:00dots must be the last thing in the argument list, and it cannot be the first thing in the argument list.
02:06So, there needs to be at least one other variable before it.
02:09And this is so that va_list can do its magic.
02:14And so in va_start, you notice that we pass it that last argument before the
02:19three dots in the argument list, and this tells va_start the thing right after
02:25that is where the variable argument list begins.
02:28In line 13, we get the next argument in the list with va_arg, and we give it
02:33the va_list variable, and we also give it the type of what that argument is going to be.
02:39That will get returned by va_arg. Then in line 15, we call va_end.
02:44Every va_start must be matched by a va_end. If you don't do that, you may get leaky code.
02:52Before we go and run this and test it, I want to show you also this other function on line 19.
02:58This is another type of variable argument function.
03:01This one is called message, and it actually calls another function called
03:05vfprintf and passes it that variable argument list.
03:10So, here on line 20, of course we declare the variable of va_list type.
03:15On line 21, we call va_start.
03:18We pass it fmt, or format which is the last argument before the variadic list.
03:23Then on line 22, we pass all of that to the vfprintf function;
03:29vfprintf function is actually how functions like printf are implemented, and it
03:35takes the standard out, and a format, and a variable argument list.
03:40And it then prints those results to standard out or to whatever file handle you pass it.
03:45Then you'll notice on line 24, there's a matching va_end for the va_start on line 21.
03:52Then down in the main function, we call message once with just a message, and no
03:57variable argument list at all, and that works fine.
03:59Then on line 30, we call message, and we pass it the results of average, which is
04:05its own variable argument list.
04:07The first number is the count of arguments, and the next five arguments are
04:13floating-point numbers which get passed to the variadic function.
04:18So now, let's go ahead and bring this back down to size, and we'll press the big
04:22green Compile and Run button.
04:24You'll see first line is "This is a message", and second line is the average of
04:29these five floating-point numbers.
04:31And of course that function gets passed to five, which is the count of the
04:35arguments in the variadic list.
04:38So for those times when you need a function that may take a varying number of
04:41arguments, C and C++ provide variadic functions, and that's how they work.
04:47Let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using recursion
00:00A recursive function is a function that calls itself.
00:03Let's take a look at an example.
00:05Let's open up recursive-factorial.cpp, we'll copy that and paste it into our
00:11Working project and double-click on it to open it in the editor.
00:15This is an example of a very simple and--a very common example actually--of a recursive function.
00:21A factorial in math is typically defined in recursive terms.
00:24It is the product of n(n-1)(n-2), all the way down to 1.
00:31So here if you look at how this function works, it first tests if n is less than
00:35than 2, and if it does, it just returns a 1 because we know the answer to that.
00:40And if not, it goes ahead and it returns the factorial of (n-1)n. And in order
00:47to get the result of the factorial (n-1) it has to call itself, and it passes at
00:52n-1, and that will happen over and over until n is 1, or less than 2.
00:59So let's go ahead and run this by pressing the big green Compile and Run button,
01:03and you'll note that the factorial of 10 is 3,628,800.
01:09This actually called itself ten times.
01:12Now there is a limit to how many times you can do this, obviously there is a
01:17limit of the size of unsigned long integer, but there is also the limit of the
01:22amount of resources that are available on the computer.
01:24Every time you call a function, memory is allocated for the parameters, for
01:30any local variables, and for the return value and all the other function called overhead.
01:35If you do this recursively, it could happen many, many times, and all of
01:39those resources keep getting allocated and not deallocated until the last one
01:44is returned, and then all of those resources get deallocated, so this can be very inefficient.
01:51So if you have a choice between a recursive function and a function that works
01:56with a loop, oftentimes the loop will be a lot more efficient.
01:59For example, for this function I could do it like this. Of course that first
02:05line is going to stay the same.
02:08We can declare a variable for our result and our starting place is n.
02:14And then there is a simple while loop.
02:16So for every value of n > 1 it will multiply the result by the decrement of n.
02:23So first it'll decrement n, and then it'll multiply the result for each one of those.
02:27And then it'll return result. We see that the result is exactly the same, 3,628,800.
02:36Now this version of the function takes up a lot less resources.
02:39It simply allocates all the stuff that it allocates for one function call, and it
02:43allocates one more long int, and then it sits there and loops and multiplies the
02:49result for a moment, and it returns that result.
02:52Whereas the recursive version allocates everything that's necessary for the
02:56entire function call as many times as the value of n.
03:00So C and C++ support recursive functions, but you should be careful for problems
03:06that may require a lot of iterations. Recursion can quickly use up a lot of
03:10resources, it's often better to find a different solution.
03:13Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
8. Classes and Objects
Overview of classes and objects
00:00In C++, classes are like custom data types. They are designed to be used just
00:05like the fundamental types provided by the C++ language.
00:09Let's start by defining the terminology that we will be using in this section.
00:13First, let's look at the words class and object.
00:17The definition of a class, using the class keyword is the class itself.
00:22You can then use the class to declare an object;
00:25the object is also called an instance of a class.
00:28Sometimes you'll hear the verb form instantiate to describe the process of creating an object.
00:35Members are the contents of an object. There are two types of members.
00:39Data members are the members that represent the encapsulated data.
00:44Data members are sometimes called properties.
00:47Function members are members that represent functions associated with the class.
00:52Function members are sometimes called methods.
00:55Constructors and destructors are special function members that are called when
00:59an instance of an object is created or destroyed respectively.
01:03A constructor is called when the object is created. There may be several
01:07constructors defined, but only one is called depending upon how the object is created.
01:13The destructor is called when the object is destroyed. There may only be one destructor defined.
01:18C++ classes are based upon the C struct. In fact, a C++ class is identical to a
01:26struct with one difference.
01:27In a struct, members default public access, whereas in a class members default private access.
01:34This matches how they are commonly used.
01:36If you're looking to access data members directly, you probably want a struct.
01:41Because the members of a class default to private, accessing those private members is not allowed.
01:45Of course, you could set the members to public access, but if you're going to
01:49use it as a struct you should probably just declare it as one.
01:53If you're using a class, you'll probably want to define accessor methods for data
01:57members you want access to.
01:59Accessor methods are function members designed to set values in and get values from the data members.
02:06These accessors are sometimes called getters and setters.
02:10It's good practice to use the struct keyword for plain old data structures,
02:14sometimes called pods, and to use the class keyword for classes with member functions.
02:19C++ classes allow you to create fully-realized types that work exactly how you want them to.
02:26Using C++ classes you may create constructors for a variety of different types and numbers of parameters.
02:33You can even disallow the default constructor if that makes sense for your class.
02:38You can allocate and deallocate memory appropriately so that your objects run smoothly.
02:44Overload operators so that your objects can use those operators intelligently.
02:49Overload the function operators so that your objects can operate like a function
02:53itself, or you can create conversion operators so that your objects behave as you
02:58expect them to in different contexts.
03:01The C++ class model allows you to define rich and complex data types and use
03:06them just as you would a fundamental built-in type.
03:09In this chapter we will cover how to define and use these features in your own classes in C++.
Collapse this transcript
Exploring namespaces
00:00As we begin to create lots of classes and objects, the possibility of naming collisions increases.
00:07Namespaces in C++ are a great tool for managing this.
00:11Let's take a working copy of namespace.cpp.
00:14I'll copy that and paste it into our Working project and open it up in the editor.
00:19I'll just maximize this so that you can see the entire file.
00:23You notice on line 3, it says namespace BWString.
00:28We'll cover the details of the classes and methods and things like that in the
00:33rest of this chapter, but we're just concentrating right now on the namespace.
00:36So you notice I declare a namespace BWString, and then there's an open curly
00:41bracket, and then on line 15 is the matching closing curly bracket.
00:45The closing curly bracket on line 13 actually matches the opening on line 7 and
00:51unfortunately it's just the way that Eclipse works.
00:55So, inside of those curly brackets between line 4 and line 15 is the namespace BWString.
01:02So everything inside of that curly bracket that doesn't have another namespace
01:07declared as in the case of the string on line 6 and on line 8.
01:12Everything else is in the namespace BWString.
01:17So I'm going to bring this back down to size here, and we're going to ahead
01:21and we're going to look at the usage of all of this line 17 through 24, and
01:28we'll just go ahead and we'll do the compile and run, and we'll see what happens here.
01:32On line 17, I declare a BWString version of string.
01:36I give it the name s1, and I initialize it to This is a string, but if we look
01:41at the code for the string class in the BWString namespace--and that begins on line 7--
01:48you'll see that the constructor on line 10 and the constructor on line 11,
01:54they both simply set it to the constant string bws, which says "This is BWString::string".
02:01And so no matter what we initialize this to, even in this case, initializing it
02:06to This is a string, it's always going to say This is BWString::string.
02:11So if instead I take off this BWString here, and I change it to std, which is our
02:17standard namespace, and I compile and run this again, you'll see that now I get
02:23a standard string which says This is a string.
02:25By using the BWString namespace, I'm actually able to declare a class that has
02:31the same name as a class in the standard namespace, string.
02:35We can differentiate it by using the namespaces here.
02:38So you notice that I don't have in this anywhere using namespace std;
02:44which we normally have at the beginning of all of our C++ files.
02:48So see I don't have that up here because I'm actually using several namespaces.
02:53I could--if I wanted to--I could say using namespace BWString, and then I
03:00wouldn't need this at all.
03:02And then when I declare a string, I get the BWString, and I'm going to save
03:07this and run it, and you see that we get the BWString version because I said using namespace BWString.
03:13So using namespace means from here to the end of the file--or until we see another using statement--
03:19I am going to be using this namespace unless I say otherwise.
03:23So here I've actually declared a standard string and standard cout and standard endl.
03:28Those names, those tokens actually exist in the standard namespace.
03:32And so since I haven't declared using namespace standard like we normally do, I
03:38actually have to specify those.
03:40If I take those off, if I were to remove this one here, it wouldn't be able to find that symbol.
03:45You see right there, symbol cout could not be resolved.
03:50Instead of using namespace BWString, it's also possible--and you don't see this
03:54as often but I want to show you that how this works.
03:57You can say using BWString::string;. Every time it sees the word string,
04:01it'll look in the BWString namespace, but it won't look for other things in the BWString namespace.
04:07So if I were to take out this one here, for example, it wouldn't find that one
04:11but I could say using std::cout, and that would find both of those.
04:17I'll Save that and run it, and click the Run in Background button there.
04:23So you see that it's looking for string in the BWString namespace, and it's
04:26looking for cout in the standard namespace.
04:30So if I remove these, which is actually the more common way to do it, and it's
04:34more explicit, I can specify which one is which.
04:37And you'll often see code written without any using statements at all.
04:42So we'll save this and compile and run it. There we have it.
04:48Namespaces are very valuable in C++, and they are very commonly used.
04:52Typically, they're defined in header files with the class definitions that use them.
04:57Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Defining a class
00:00Classes in C++ are very powerful and flexible.
00:04This is the fundamental unit of object-oriented programming.
00:07So let's take a working copy of class.cpp, and we will paste it into our Working project here.
00:14I'll go ahead and double-click on that and open it in the editor, and we'll
00:18double-click on the tab there to maximize this so you can see the entire thing.
00:22So here we have a very simple class definition beginning on line 6.
00:25You notice it has one data member, int i, it's a private data member because
00:30it's not specified otherwise, and members in classes in C++ default to private access.
00:38We have two public members, and you can see they are declared as public on line 8.
00:42And those public members are both function members and they're called setters and getters.
00:47One gets the value of i and one sets the value of i.
00:51So you can see these are defined just as normal functions would be defined.
00:56setValue returns void, and it takes a value as an argument and integer.
01:02And it assigns i to that integer, and i is the private member in the class.
01:08So this member function has access to the private members in the class.
01:14The next one returns an int getValue, and it simply returns the value of i.
01:21So that's our very, very simple class. We can see it's used at line 15.
01:26An object is declared using that class, so this is called Instantiation, that's an
01:31instance of that class, it's an object of that class.
01:34And on line 17 we actually call the member function setValue with the value of i
01:40from main and i from main is 47. This is not the same as i from the class.
01:45The i from the class is not visible here at all, because it's a private member.
01:51And so object1.setValue, that calls the setValue method in the object1 object,
01:59which is of type Class1.
02:01And it passes the value of i, which is that i = 47 from line 14.
02:07And then cout calls object1.getValue to get the value, and it should print value is 47.
02:14So let's go ahead and compile this and run it, and you see it says value is 47.
02:22Normally it's considered best practice to separate interface and implementation,
02:25and what that means is that these functions here, these are actually implementation.
02:30The function signatures of them, that's considered interface.
02:35But the actual code, that's considered an implementation.
02:38So, typically how this is done is we take these and move them down here and
02:43leave inside the class, we would leave just the function signature, and if we
02:48take off that actual function definition, then when need a semicolon here.
02:52So I'm going to do the same with getValue.
02:56And then we have two functions out here, let's go ahead and format them like we
03:00would in normal functions.
03:02Now you notice we have syntax errors here, because symbol i could not be
03:07resolved for both of these.
03:08And that's because the compiler does not yet know that these are actually
03:12implementations of methods that are defined in class Class1.
03:17And we tell it that by giving the name of the class and two colons
03:21as if it were a namespace.
03:23Name of that class has a 1 on it, and there we go.
03:26So I'll take that, and I'll copy that, and I'll paste it down here.
03:31And now the compiler knows that these are implementations of function members of
03:36methods that are defined as part of Class1.
03:40So up here from line 6 through 11, we have the interface, and that tells us
03:45how our class is used.
03:47And then in lines 13 all the way down to line 19 we have the implementation.
03:53This is the code that actually makes the class work.
03:56Now normally all of this would be in really three separate files.
04:00I'll maximize this again. We can look at it.
04:03The class definition, the interface, would be in a header file, and it would be
04:09probably named Class1.hpp.
04:12And the class implementation would be in a separate file called Class1.cpp.
04:19And those would get compiled together and they would get linked with the code
04:23that actually calls it, and that would be in one or more other cpp files.
04:27But for our purposes, for teaching purposes, as you're learning the basic
04:32syntax of C++ classes, we're going to be using really simple examples, and we're
04:36going to be putting them all in one file like this just so that you can see how
04:40all this stuff works, and it makes it simpler for our purposes. Just know that
04:44normally these things would be in separate files.
04:48So let's go ahead and save this and run it, and you can see that it works just
04:51fine, and it works exactly as we expected.
04:54So sometimes we'll do it this way with the implementation separate from the
04:58class, most of the time we'll do it that way, but it'll all be in one file, and
05:03occasionally just for simplicity's sake, we'll go ahead and put the
05:05implementation if it's really small.
05:07Oftentimes we'll go ahead and put that inside the class definition.
05:10That usually happens for constructors in very, very small functions.
05:14So let's go ahead and delete our Working file, and we'll run Clean to get set up for the next lesson.
Collapse this transcript
Using data members
00:00C++ objects are based on C structures.
00:03In fact, you can create objects using either the struct or object keyword.
00:08Let's open up working.cpp out of the Chapter08 folder in your exercise files and
00:15double-click on it to open it in the editor.
00:17I'm just going to go ahead and declare a C type struct using the struct keyword
00:24called struct A, and we'll just give it a few members here.
00:30And then when I come down here in the main function, and I'm going to create an
00:35object based on that structure.
00:36If I just say A a = and initialize it, I am going to use printf, and we'll see
00:47that when I save this and press the button there to Compile and Run.
00:51You see that that works just fine so I'm able to create the structure.
00:55I'm able to create an instance of that structure or a variable of that type,
01:00and I'm able to access the data members of that structure simply with the
01:06structure member operator.
01:08Couple of other things to notice here, you'll notice that I didn't have to
01:12type struct A like this.
01:13In C, you have to type struct A as the type.
01:17In C++, you can just use the name there, and you don't need the keyword struct
01:23or the keyword object.
01:25The distinction between structures and classes, there's really only one distinction.
01:30If I change this to class and save it and run it, the only reason this doesn't
01:37work is because these data members are private. See, it says ib is private, ic is
01:43private, could not convert and within this context, that means that these
01:48private data members, I'm trying to access them in that context.
01:53And if we look at the actual error message out of the compiler, we see ia is
01:58private and then within this context for line 13 and character position 45,
02:04character position 51 and 57 and those are these separate usages.
02:09So that's the only difference. In fact, if I were to just type public here like
02:14this--and this declares that these data members will be public--
02:19this now will work exactly like the struct, and if I can compile and run that,
02:23everything works exactly as we expected.
02:25Really, the only distinction between class and struct is that data members in a
02:30class default to private and data members in a struct default to public.
02:35I'm going to go ahead and make these public again.
02:37We can actually declare any type in here.
02:40This middle one could be a string called sb, and then now printing it out needs
02:47to be a type s, and we need to actually use the c-string method of that string.
02:52This is actually a sb now and c_str() method, and that will allow us to print that out.
03:01I'm just going to put all these on the next line so that we can see them.
03:06c-string is a method of the String class, and it gives us back a c-string
03:09that's usable with printf.
03:11And now when I initialize it--we'll just give it a string that says two--and if
03:17I save this and run it, you'll see that it works exactly as we expected.
03:22But typically, most data members are kept as private in a class.
03:27If you want public data members, you probably want a struct. If you want a
03:31class, you probably want private data members, and you want to use accessors.
03:34Accesssors are public function methods that are used to access private data members.
03:41And for an example we can just bring up this accessors.cpp.
03:44I'm just going to double-click on it here. We are not going to actually compile
03:47and run this because we're going to cover function members in our next movie.
03:51But I just want you to see that this is typically how this is done.
03:54Here's exactly the same class that we have in the movie that we're looking at right now.
03:59And you see we have an integer, a string, and an integer, and then we have these
04:03public methods for dealing with it.
04:06We have a constructor, we have setters--seta, setb, setc--and we have getters, geta, getb--
04:12getb is a c-string--and getc.
04:16And so we're actually able to do the same thing here and use it in the same way,
04:22but we're using function members to access these data members, and that's
04:26typically how it's done in a class.
04:29So if you actually want publicly accessible data members, then you probably want to struct.
04:34If you want to use the encapsulation of object-oriented programming, then you want to use a class.
04:40You want to have private data members, and you want to use function methods as
04:44accessors to access those private data members.
04:48And again, we'll learn more about member functions in the next movie.
04:51So I'm going to close this, and we'll bring this back down to size.
04:55C++ classes are based upon C structures.
04:59In fact, C++ structures and classes are identical except the structure members
05:03default to public access where class members default to private access.
05:07It's good practice to use struct when the structure will have only data members,
05:11and it's good practice to use class when there are also function members.
05:16So let's now delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Working with member functions
00:00C++ classes can have member functions that act as methods for the class.
00:06Let's go ahead and make a working copy of working.cpp. We'll paste this into our
00:10Working project and open it in the editor.
00:12I'm going to go ahead and just create a quick and simple little class here,
00:17we'll call this class A, and we'll give it one data member, and remember that data
00:23member is private because we haven't declared it otherwise.
00:26And I'm going to type the word public here, and you'll notice that Eclipse is
00:30really nice about flush-lefting that for us, and we'll go ahead and declare a
00:34couple of public interface methods.
00:37And these are what are called accessors, these types of methods, because they're
00:40going to be used to access that private data member.
00:44First one is setter, so this will set A, so it returns void, and it takes a
00:50const int a as its argument. We'll just say ia = a;
00:58and so that's a simple setter and all that it does is it takes this argument and
01:02use it to set the value of the private data member ia.
01:05So we'll go ahead and declare a getter.
01:07Now this one will return an int, and it'll be called getA, and it has no
01:13argument, and it'll simply return ia like that.
01:19And so it's a very simple setter and getter. These are called accessor methods.
01:22They're used for accessing private data members and they're very common, and so
01:27that's a very simple little class for our experimenting with here.
01:32Now we'll declare an object based on that class, so we do that like that.
01:37The capital A is the class type and the lowercase a is now the object that's an instance of that class.
01:44And we'll use our setter to set the value. I'm going to give a value of say 47,
01:50and then we'll use our getter to retrieve the value, and we're going to use cout
01:57to display it like that, and we'll just compile and run this, and you'll see
02:03that it prints up 47 exactly as we expected.
02:07Now we can easily set and get values from our simple class.
02:12Now it's common object-oriented practice, and it's considered best practice,
02:16actually, to separate the interface from the implementation.
02:19This is done by declaring the member functions in the class definition and defining them later.
02:25So if I take these member functions, and I just copy them and paste them down
02:29here, I'm going to go ahead and adjust these first so that they're proper
02:34declarations and they're not definitions.
02:36So I simply take out the code and the curly braces and put in a semicolon.
02:42Now they're definitions instead of declarations.
02:45And then I'll take these, and in order to make these actual implementations, I
02:49need to declare that they're of this type, that they're part of this class.
02:53I do that by giving the class name with two colons, like that.
02:59Now this is actually proper code, and I'm going to go ahead and format it a
03:03little bit so that it's formatted like normal functions.
03:09So now what we have is we have our class interface, which is the definition of
03:13the class without the definitions of the function members, and we have our
03:18implementation which is the function members by themselves.
03:20Normally these would be in separate files.
03:23The class definition would be in a file called something like a.hpp and the
03:30class implementation would be in a file called something like a.cpp.
03:35And then everything else would be in other files, so it would be linked to the
03:39object file after the compilation process.
03:41But for our purposes, for the purposes of teaching, it's really convenient to
03:44have all these small little examples in one file.
03:46So just note that this is not normally how it's done.
03:50There's one other very important detail here that you need to understand at
03:54this point, and that's the concept of something called const functions or const-safe functions.
04:00So we're going to illustrate that by creating another A object, and this one
04:06we'll call b, and we'll simply assign the first one to it.
04:10So we now have an object b that's of type A, and we have copied object a into b.
04:17So it's got exactly the same data members.
04:19So we would expect that we would be able to do this and simply say b, and then
04:26we would get the same value.
04:27I'm going to go ahead and put a string in here so we know which is which.
04:32And when I compile and run this, you'll see that we've got, a is 47 and b is 47.
04:38Now if I take b, and I declare it as a const object, like that, with the const
04:43keyword, now you notice we immediately get an error.
04:47So the error message says overload of 'endl', which is just weird, and
04:52Invalid arguments ' Candidates are: int getA() '.
04:55So the problem here is really with this, Invalid arguments, and it's not a very
05:01helpful error message.
05:03If I save this and compile it, and we'll see what comes out of the compiler--I'm
05:07going to go ahead and click the Run in Background button on that;
05:10if you get that you'll do the same thing, Errors exist in project. Continue launch? No.
05:14Let's take a look at what the errors are here.
05:18Here we get a slightly more intelligible error,
05:21passing 'const A' as 'this' argument of 'int A::getA()' discards qualifiers.
05:27You'll see that discards qualifiers every time you accidentally do something like this.
05:31That's why I wanted to show you that error message.
05:34And the problem actually is that this getA function member is not what we call const-safe.
05:42So in other words, when the object is declared as a const, we cannot use
05:48function members that are not const-safe. So what does const-safe mean?
05:53Const-safe means that it's been declared as const-safe like this, with the const keyword.
06:00And of course, we need to do it also up here where it's initially declared.
06:06So when I do that, and I just hit Save, that makes this function member
06:10const-safe, and now I'll be able to compile and run this, and it'll work just
06:16fine, exactly as we expect, b is 47. So what exactly does const-safe mean?
06:22Const-safe means I guarantee that I will not do anything in this function that
06:28is not safe to do on a const object.
06:32And for the most part, that means that I won't change anything, and then if I
06:35do change anything, I'm going to do it very explicitly, and I'm going to use special keywords.
06:40But for the most part, it really means I'm not going to do anything that's not
06:44const-safe in this function.
06:45I'm not going to actually change anything in this const object.
06:50So the rule is a non-const object may use any of the const-safe or not
06:56const-safe methods in the class.
07:00But a const object may only use const-safe methods in the class.
07:07In fact, it's possible to declare two separate versions of this.
07:10So I'm going to do this right now.
07:13One of them const-safe and one of them not const-safe.
07:17And then I can come down here, and I can duplicate this, and I can make the
07:22duplicate not const-safe.
07:25And just so you can tell which one is being called, I'm just going to put out a
07:30little message from each of them, calling this the mutable getA because mutable
07:33is another word that's sometimes used for not const-safe.
07:39And this one is the const getA.
07:41Now because there are two versions, and one of them is const-safe and one of them
07:47is not, the mutable version of A-- which is this one here, the one that's not
07:52declared as a const--that will prefer the mutable version of getA.
07:58And the const version of A, the one that's called b, is actually only allowed to use the const version.
08:04So we'll go we'll run this, and you'll see that we get the mutable
08:07getA for the first one, and this is the const getA for the second one.
08:11So the const function is called for the const object, and the non-const or
08:15mutable function is called for non-const objects.
08:18So you can remember this simple rule of const functions.
08:22Const-safe functions may always be called.
08:25Non-const safe functions may only be called by non-const objects.
08:31So member functions are what make object-oriented programming possible.
08:35As we go through the rest of this chapter, you'll see that most of the other
08:38features of C++ objects are based on the ability to create member functions.
08:43Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Pointing to the current object with the *this pointer
00:00Object member functions in C++ make use of the keyword This to provide a pointer to the current object.
00:06Let's take a look at how this works.
00:10Make a working copy of class.cpp and paste it into our Working project, and you
00:16see we've our very simple class here. I'll just go ahead and maximize this so
00:21you can see the whole thing.
00:22It has one data member i, and it has two public function members which are setters and getters.
00:27They are accessors for setting and getting the value of i.
00:31We declare an object of Class1.
00:34We set its value, when we print out its value, and when we run it, it looks like
00:39this, value is 47, that's exactly what we expect here.
00:43So now we're going to go ahead and we're just going to add a function member here.
00:48We'll give it a void value, and we'll call it lookAtThis.
00:53And it will take one argument, and it will be an int call i, and we'll just do
00:59the implementation down here, void Class1::lookAtThis( int i ), and we're just
01:09going to print out the value of i here, printf("i is %dn", i); like that.
01:17Now we'll come down here, and we'll say object1.lookAtThis, and we'll give it, say, a 9 like that.
01:29And now when we Save this and Compile and Run it, you'll see i is 9 and of
01:35course, the value down here in this getValue is 47.
01:39This is an interesting result because you'll notice that our class has a data
01:45member called i and yet we've passed an argument called i, and it printed out
01:51the argument, it did not print out the data member.
01:53So that's kind of what we would expect.
01:55The i from the local scope overrides the i from the larger scope, from the class scope.
02:01But what if we wanted to actually also be able to access the i from the class scope?
02:05We don't want to say, Class1::i because that's the class, that's not the object.
02:12What we really want is the object i, and that's done like this.
02:17So the This keyword actually gives us a pointer to the current object.
02:23And we can say here our object i is that, and so when I run this, we have object i is 47 and value is 47.
02:35So the This pointer can actually be really, really handy, it can be handy in circumstances like this.
02:41It can be handy when you're trying to do more complex things to get out objects within your own object.
02:48And it is actually a pointer to the current object.
02:52If I say printf, this is and give it a %p, which is printf is for print out a
03:00pointer, and then I also come down here, and I say object1 is, and I give this
03:10object1 or the address of, like that.
03:14We'll need a semicolon in both of these places in order for that to compile and run.
03:20And so I will press the big green Compile and Run button, and we see our
03:26addresses that are printed out about those two pointers are exactly the same.
03:29So within the object, we're able to access a pointer to the object with the This keyword.
03:36So the This pointer is very useful in some circumstances.
03:39For example, when overloading an assignment operator, you'll want to return a
03:43reference to the current object so that your assignments can be chained.
03:46We'll see some examples of this later in this chapter.
03:49For now, let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using constructors and destructors
00:00Constructors and destructors are special member functions and serve a particular purpose.
00:05There are several types of constructors in C++ and one type of destructor.
00:09Let's take a look at class.cpp for an example.
00:12We'll copy this and paste it into our Working project and open it up in the editor.
00:17I'm just going to maximize it so you can see it here.
00:20Here is our very simple class, and you'll notice that among other things it has
00:23no constructors or destructors defined, and so C++ in a case like this where you
00:28don't provide any constructors or destructors, it implicitly provides a default
00:33constructor which is a constructor that takes no arguments, and you'll notice
00:36the way this is constructed in line 15, there are no arguments.
00:40And so the default constructor is the one that's being called, and that's the
00:43implicit default constructor that's provided by C++.
00:46There is also a Copy Constructor provided and a Copy Operator provided and a destructor provided.
00:53So let's go ahead and run this for a second here.
00:56We'll push the Compile and Run button, and you see that value is 47, and that
01:02happens on line 18 where the value is printed.
01:04Go ahead and make a copy of that line 18, and I'm going to paste it in before
01:08the setValue line and so now it looks like this. I'm going to Save and Compile and Run.
01:14And you'll notice that the default-- the implicit default constructor has
01:18actually set the value of our private data member to zero.
01:22And what the implicit default constructor does is it actually calls the default
01:26constructor on any of the data members in the class, and so in this case we had
01:301, it's an int and the default constructor on an int sets its value to zero.
01:34So that's the Implicit Constructors and Destructors. Let's go ahead and close
01:38this, and we're going to delete our class.cpp from our Working project there,
01:43and run Clean, and now we're going to really get into this.
01:48Let's make a copy of constructors.cpp, and I'm going to paste that into working here.
01:53We're going to maximize that so we can see it. I'm just going to page through real quick.
01:58It's a bit long for the folks who are typing along at home.
02:01I'm just going to point out a few things here to start.
02:04You'll notice we have our class Animal, and you'll notice it has a number of
02:07constructors and a destructor defined and even has a copy operator defined.
02:11And we're going to get into all of that in a moment, and then you notice the
02:15Implementation section here where we have actually provided the implementation for
02:19all of these member functions, and there is our operator overload and then down
02:23at the bottom there there's a main function which constructs a number of
02:26different versions of this, and it constructs them in different ways.
02:30So a constructor looks like this.
02:31Let's take a single or default constructor on line 13.
02:35The default constructor has no arguments, and so it's the name of the class.
02:38When the name of the class is the name of the function that means it is a constructor.
02:43So constructors are just the name of the class as the function name and then
02:47whatever arguments and whatever implementation you have.
02:49So in this case we have a default constructor because it has no arguments.
02:54So line 13 is the default constructor, line 14 is the constructor with
02:58arguments, and you'll notice that this constructor has three arguments and they are all strings.
03:03Line 16 has what's called a copy constructor, because this constructor has as
03:07its single argument another object of the same type.
03:11Line 17 is our copy operator, and this is an operator overload.
03:15It returns a reference to the object itself, and it takes as its parameter a
03:20reference to an object of the same type.
03:22Line 18 is the destructor, and the destructor is indicated by a tilde in front of
03:26the function name and then the function name after the tilde is exactly the same
03:30as the object or the constructor.
03:33And finally, we have a print method that we're going to use for printing out these objects.
03:37So let's take a look at the implementation for the default constructor on line 22.
03:42So this is a syntax that you probably haven't seen before.
03:45You notice we have this colon, and then after the colon we have these things that
03:49look like constructors or function calls before the opening curly brace.
03:55This is what's called the constructor initializer list.
03:59So the colon sets it apart, and then you can actually initialize your data
04:04members without ever actually getting into the body of the function, and
04:07whatever is here is actually executed before the body of the function.
04:11So you may actually not even have a body of a function.
04:14In this case we only have a body so that we can print out this string.
04:18So the way these initializers work is you have the name of the object that's
04:22being initialized--in this case it's that string type--and then in parentheses
04:25you have whatever value you're going to be initializing it as.
04:28This is actually the same syntax as if you were going to call a constructor or an object.
04:33If we come down here into the body of our main, you'll see that we construct
04:37this b object which is of type const Animal, and we construct it with
04:42parentheses and then parameters inside the parentheses.
04:45And so the same syntax is what's used in the constructor initializer list,
04:50and so they're separated by commas, and you can initialize whatever you want up there.
04:54And then in the body of the function we just have this cout, and the purpose
04:57of that is so that as we call each of these constructors we have an idea what's happening.
05:01We can kind of follow the flow.
05:03It's really just for educational purposes. You wouldn't put that in an actual constructor.
05:07So moving along in line 26 we have the constructor with arguments, and here we
05:12have the arguments list, we have type, name, and sound, and these are strings, and
05:17we were simply initializing in our initializer list those corresponding
05:21variables in our data members.
05:23We have the copy constructor starting at line 31.
05:26This takes a reference to an Animal object as its argument.
05:30We print out a string that says this is the copy constructor, and then we do the assignments.
05:35We assign the data members from the object being copied to the data members in
05:39our own object, and you'll notice here on line 35, we're prefixing this
05:43clone_prefix, this is from our constants up on lines 5 and 6.
05:47The unknown constant on line 5 is being used in our initializations on line 22,
05:51and the clone_prefix constant is being used in our copy constructor down there on line 35.
05:58Then we have our destructor, and again, we just have a string that says we're calling the destructor.
06:03There isn't really anything for the destructor to do here.
06:05We have our print function down on line 44, which simply prints out the name, the
06:10type, and the sound of the animal.
06:13And then on line 49 we're actually overloading the assignment operator and the
06:17reason that we're doing this it's something called the Rule of Threes, and this is a C++ thing.
06:23You might--you hear it referred to now and then.
06:25The Rule of Three says that if you find yourself needing to overload any of the
06:29implicit methods that C++ normally provides--the copy constructor, the destructor,
06:34or the copy operator--if you find yourself needing to overload any one of those,
06:38you should probably think about overloading all three.
06:40And in fact, especially because we're overloading the copy constructor, we want
06:44to overload the assignment operator so that you can see the distinction.
06:48You can see when we run it.
06:50A difference between what happens on line 66 and what happens on line 69.
06:54Line 66 is a copy constructor and line 69 is an assignment operator.
06:58So we'll be able to see what happens there. So let's go ahead and run our code.
07:02I'm going to press the big green Compile and Run button here, and here we
07:08have what goes on, and we're going to come down here into main, and we'll see what happens.
07:13In line 60 we construct an object with a default constructor, and that's because
07:17it has no arguments, it's just Animal a like that, and so we'll notice our
07:21default constructor up here on line 22, it simply initializes our three
07:27variables with the unknown constant string, and there is our unknown constant
07:31string up there has the word unknown in it on line 5.
07:35So our default constructor, and then we call print, and we see it prints out
07:40unknown the unknown says unknown.
07:41So that's exactly what we expect to have happen with or default constructor.
07:45Next we call the constructor with arguments with goat, bob, and baah, and so we
07:50get the string constructor with arguments, so we know that we're calling the
07:53right constructor and the print prints out, bob the goat says baah.
07:57Then we call our copy constructor on line 66, and we see we get the string copy
08:02constructor on our console, and then it says clone-bob the goat says baah.
08:06Because our copy constructor is copying object b as it constructs object c.
08:12And so our copy constructor, you'll remember here-- let's go up and take a look at our copy constructor.
08:17On line 35 it copies the name, but it prefixes that clone_prefix and
08:22clone_prefix again is up there on line 6, and it says clone- and so we get
08:28clone-bob the goat says baah.
08:30And just to see the difference, on line 69 we have the assignment operator.
08:35We're assigning the value from c, which you remember it says clone-bob the goat says baah.
08:40We're copying that object into a using the assignment operator.
08:44And so if we look up in our assignment operator, right there we see on line 53
08:50it copies name with the clone_prefix again, and so when we print it out on line
08:5470 we get, clone-clone-bob the goat says baah. That's this one right here.
09:00Now we're at the end of our function and all of the destructors get called
09:03because all these objects go out of scope and so they all get automatically
09:07destructed, and they get destructed in reverse order.
09:09So the first one to get destructed is c, and remember c says clone-bob the goat.
09:14Then b gets destructed which is just bob the goat, because it doesn't have any
09:18copy operations involved in it, and then a gets destructed, and remember a was
09:23assigned with the assignment operator, and it got a copy of c, and it got
09:27clone-clone-bob the goat. And so that's our last destructor there.
09:31So just one more thing that we need to cover here, and I'm going to maximize
09:35this so that we can see this.
09:37You remember that C++ provides implicit constructors, and for example, the
09:40default constructor here--which I've highlighted here on line 13--if I don't
09:45define one C++ provides an implicit one.
09:48If I want the object to disallow the default constructor--in other words, coming
09:52down here into main--and the way that I've constructed the a object on line 60.
09:57If I want that to be illegal, if I want that to be disallowed, that's not a
10:01valid use case for my class.
10:04I can do that by simply taking this default constructor and instead of declaring
10:09it there in public, if I declare it in private, now it cannot be called.
10:13And if I do that of course, I need to get rid of this because I have no
10:17implementation for it, and I need to provide it with an empty set of curly braces.
10:22So now I have a default constructor, I've defined my own default constructor.
10:25I've overloaded the one that's provided implicitly, but it's in private so it cannot be called.
10:31It cannot be seen from the outside.
10:33So if I try to compile this, I'll get an error, and we'll need to go back out,
10:38we'll need to minimize this so we can see the errors here.
10:41The error says 'Animal::Animal()' is private, and so that simply disallows it.
10:46It makes it so that if I try to do this I get an error in my compilation, and I realize, oh!
10:51I need to actually give that some parameters.
10:53So you can overload your implicit constructors in the private section to disallow them.
10:58This was a lot, but it's important to understand the constructors.
11:01Constructors and destructors are important parts of any C++ class.
11:05It's always worth thinking carefully about how your objects are constructed, and
11:09crafting constructors and destructors that handle all the necessary use cases.
11:14So let's go ahead and delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Exploring implicit vs. explicit constructor type conversions
00:00When a constructor has only one parameter, it can be used to provide implicit type conversion.
00:06The explicit function modifier prevents this behavior.
00:10Let's take a look at how this works.
00:12Make a copy of implicit-explicit.cpp and paste it into our Working project and
00:16open it up in our editor.
00:18I'm going to maximize this so that we can see it.
00:21I'll just scroll through here briefly for those who are typing along at home.
00:25So this is a partial class, this is hypothetically the beginning of
00:29the roll-your-own-string class, and it's getting a length, a string length parameter.
00:35And really that's all the class does at this point.
00:37It just has the one data member;
00:39its size data member, and it's of type size_t, and it's going to be eventually
00:44used as some kind of a string thing. And so we have two constructors.
00:47We have a constructor from a size_t which gets automatically converted from
00:51int, and we have a constructor from a c-string which will take the size from c-string.
00:55And then we have this little getter, this little accessor in Line 11, it'll
01:00return the size so that we can see what's going on.
01:03So it's really just for experimental purposes.
01:05So the first constructor is implemented beginning on Line 14, and you see it
01:10says it takes a size_t variable, and it checks to make sure that it's not
01:14greater than maxlen, and it assigns it to size.
01:17And then you can see the constructor beginning on Line 19 takes a string and
01:20finds the length of that string, and it uses that for size.
01:24And then we have our little getter on Line 30 and then starting on Line 34, we have our little test bed.
01:29So there's two things in here, in the main function
01:32we construct an object using s =, and I assigned a character by mistake.
01:36It was supposed to be a string of one length, but I assigned a character so
01:39that's going to get converted into the size_t, and it'll take the value of that.
01:42And then you see the other implicit conversion that happens is in the function call.
01:46You notice that the function is declared as requiring a BWSize object and
01:51instead I'm just passing it this character.
01:53Again, by mistake, it is supposed to be a string, but it's a character, and
01:57that's getting automatically converted also into this unsigned integer that is size_t.
02:01And so we have these implicit conversions going along, and in both cases they're
02:04really something that we didn't intend, but they're happening by accident.
02:07And you'll notice that when I compile and run this that it actually works.
02:11It doesn't do what I intended.
02:13Instead of giving me that one length that I might have meant, this character is
02:16getting converted to the integer value 120, and it's getting assigned to size.
02:20So we can make this not happen by using the explicit keyword. So both of these
02:26syntaxes are actually designed to do implicit conversions.
02:29When you initialize an object with the equal sign instead of the parentheses,
02:34it's designed to do an implicit conversion.
02:36And when you initialize an object by passing something into a function like
02:40this, it's also doing an implicit conversion because the function is
02:44requesting a BWSize object, and I'm actually giving it something else, and so
02:48it tries to do a conversion.
02:50So we can prevent these implicit conversions by using the explicit keyword.
02:53So if I just type explicit here and here, now none of this will work anymore,
02:59and we won't actually be able to compile.
03:01If I try to compile this, I get errors and the errors look like this:
03:05conversion from 'char' to non-scalar type 'BWSize' requested, invalid
03:10initialization reference 'const' from expression type 'char'.
03:13So we're having problems here.
03:15There's our conversion problem, there's this weird initialization of type from
03:20char that's also a conversion problem, and here we have passing argument 1, that problem there.
03:27So this no longer works because we have explicit.
03:29Once we have explicit, we have to actually match things.
03:32In fact, let's comment out the second one and just start with the first one.
03:35So I'll comment that out. And then this one here, let's just try to give it a number, 125.
03:40And if I save that and try to compile it, we still have an error because it's
03:45still trying to do an implicit conversion for two reasons.
03:47One is that I'm using this syntax with the equal sign, and the other is
03:52that that's an int; it's not a size_t.
03:54So I can make this a size_t and try that, save that and compile it, I get the
03:59little--and just hit Run in Background if you get this.
04:02And you see we still have an error because it's still trying to do an implicit
04:06conversion because this syntax here is actually the syntax of the copy
04:11constructor, and that's not the kind of a constructor we have.
04:14We have the parameterized constructor.
04:16So I need to actually even do this in order for this to work.
04:19So now I save this and run it, and now it works because I'm calling the
04:25constructor that I intended, and I'm calling with the type that I intended.
04:28That's a little bit inconvenient to have it be a size_t.
04:31If I want this to be an int, I can come up here and instead of the size_t, I can
04:36say const unsigned int.
04:40And I'll come down here into the implementation and do the same thing, const
04:45unsigned int, and now I should be able to initialize it like that, and there we have it.
04:53Now with func, let's try to get it to use this other constructor here.
04:58Obviously, if I just uncomment this and put in a string instead of that
05:02character, we're not going to expect that to run.
05:05Why? Because we're still trying to do an implicit conversion.
05:08This function is requesting a BWSize object, and I'm passing it a string.
05:13And so if I compile this, I get errors, and the error looks something like this:
05:18invalid arguments, invalid initialization of reference type, and here we have passing argument.
05:25So it really needs for me to pass it a BWSize object, so I need to do it like this.
05:30And what this will do is this will construct a temporary object and pass it.
05:34So this constructs a temporary object of BWSize type, and it initializes it with
05:38that constant character string, and so if I compile this and run it, we get a
05:42size of 1, which is exactly right.
05:44And so if I give this five of them and compile and run that, we'll get a size of 5.
05:51So here we see that by using the explicit keyword, we have prevented implicit
05:55conversions in our constructors.
05:57Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Overloading operators with member functions
00:00Operator overloading is not unique in C++.
00:03In fact, it was one of the original concepts borrowed from ALGOL for C++, but
00:08how C++ does it is fairly unique and extremely powerful.
00:13There are two distinct ways to overload operators in C++,
00:16one with member functions as part of a class definition, and the other as
00:20separate non-member functions.
00:22In this movie, we'll discuss operator overloading with member functions in your class definitions.
00:26We'll discuss the non-member functions in another movie.
00:30Let's make a working copy of rational.cpp, and we'll paste that into our working
00:36project and open it up and maximize it here.
00:39I'm just going to page through this briefly for those who are typing along at home.
00:43So here we have a class that implements a simple rational number, that is a
00:48number that has a numerator and a denominator, and we want to be able to operate
00:52on these rational numbers, we want to be able to use the four-function arithmetic operators on them.
00:56And so we have our member functions defined to do that.
01:00So first, we have a couple of constructors.
01:01We have one that constructs with the numerator and denominator, and that one is
01:05entirely implemented here in the class definition.
01:08So this separates out the initializer list, and then we have the initializer
01:11list right here that initializes n as the numerator and d as the denominator,
01:17and we have an empty function body.
01:19So this fits really nicely here.
01:20Sometimes I'll break my own rule, and I'll have some implementation in the class
01:24definition if it's that simple, and it fits that concisely.
01:27And again, with the copy constructor we did the same thing.
01:31And there's a destructor, and the destructor is defined here, but it's
01:34actually implemented down below, and we have a couple of getters for numerator and denominator.
01:39Again, since they're so simple, I went ahead and implemented them here.
01:42And then we have five operator overloads.
01:45We have the copy operator, and we have the plus, minus, multiply, and divide operators.
01:51So let's take a look at these implementations. Here's the copy operator.
01:55The copy operator returns a reference to itself, that is to its own object, and
02:01it does that using the this pointer.
02:03It also uses the this pointer to compare the address of the object that's being
02:08passed to it to make sure they're not the same. If they are the same, it does nothing.
02:12If not, it prints out the word assignment so that we know that it happened, and
02:16it copies over the data members.
02:18Our 'for' function arithmetic operator overloads are incredibly simple.
02:22We have on Line 29 the plus operator, on Line 33 the minus operator, on Line 37
02:28the multiply operator, and on Line 41 the division operator.
02:32These are all defined as being const- safe because they don't actually have to
02:37modify anything in the object and they use very simple formulas for doing the
02:42multiplication, division, addition, and subtraction of the rational objects.
02:47Then on Line 45 is the destructor, and it simply prints out that we're calling
02:52the destructor so that we know that it happened.
02:54On line 50 is something else again, and this is simply a convenience function
02:59for making these objects work with the outstream.
03:03This makes it possible to do what we're doing on Line 71 through 74, which is
03:08actually printing out these objects using cout.
03:12And in fact, this function beginning on Line 50 is an example of an operator
03:17overload as a non-member function, so we'll cover the details of how that works in our next movie.
03:24For now, let's go ahead and bring this back down to size and compile and run
03:28and see how this works.
03:31So starting at the top, we're constructing object a, and we're giving it a value
03:36simply of 7, and it responds by saying a is: 7/1. So let's see how this is working here.
03:44You'll notice the first constructor listed here on Line 8, it takes two
03:49arguments, a numerator and a denominator, and you'll notice that these have default values.
03:54So this syntax here where it says int numerator = 0, that gives it a default value.
03:59If I don't pass it a numerator, then it'll assign the value 0, and it'll use that instead.
04:04And so what I've done here, you'll notice that the denominator default is 1, and
04:09I constructed it with simply a 7, and so it presumed the one because rational
04:15number that's equal to the integer 7 would be 7/1. Rational b I initialized with
04:205/3, and again, we see that in our results down here, b is: 5/3.
04:24We use the copy constructor for c and so that gives it also the value of the b.
04:31There on Line 61, c = b so that is the copy constructor, and it gives c the same
04:36value as b, 5/3, and we use the default constructor for d which makes it 0 over
04:421, which is a rational number that's equal to 0.
04:45Of course, you can't have a denominator of 0 because that's illegal.
04:48You can't divide by 0.
04:50On Line 65 we then assign a value to d with the assignment operator.
04:56And so we get the word assignment here, I'm going to scroll down, and that's
05:01happening there because of Line 65, and if we come up and look at our definition
05:05of the assignment operator there on Line 20, we see it prints out the word
05:09assignment when it does that assignment.
05:11In Line 67, we assign a reference and so e becomes a reference to d, and
05:17this doesn't call any of the constructors because we're not constructing a new object.
05:21And then on Line 68, we try to assign e back to d, but that doesn't work because
05:27it's an assignment to self.
05:29And so we just get this next line e because nothing happened in those other lines in our object.
05:35Now starting on Line 71, we start to get these strings.
05:38We'll go ahead and scroll down so you can see those.
05:41On Line 71, we are adding a to b and so a is 7/1 and b is 5/3 and the result is 26/3.
05:48But you'll notice that then there's a destructor for the object that has 26/3.
05:53Why is this happening?
05:56Well, what actually happens in this line here, a + b, let's go take a look
06:01at our plus operator, and we see that our plus operator constructs a
06:05temporary rational object.
06:07This here is the class Rational and inside of these parentheses is the
06:13initialization of a temporary object.
06:15And so we have a numerator here, and we have a denominator here, and we return
06:20that temporary object, and once it's used, it gets destroyed because we're not
06:24really assigning it to anything that's going to keep it.
06:26So at the end of this expression, we take that value, and we pass it on to cout,
06:32and when cout is all done, that object gets destroyed.
06:35And so this is the cout line, and there's the destructor.
06:38So the same thing happens for each of these.
06:40Here's the subtraction, this is multiplication, and so that's Line 72 and
06:4673, and then here's the division on Line 74, and there's that object getting destroyed.
06:52And then we're at the end of our main and so all four of these objects, a, b, c,
06:57and d, get destroyed in reverse order.
06:59And you'll notice that e doesn't need to be destroyed because e is simply a
07:03reference, so it doesn't create any new object.
07:06Let's take another quick look at the assignment operator.
07:09The assignment operator is a bit of a special case.
07:12Because you need to be able to chain assignment;
07:14in other words, you need to be able to say a = b = c = d, it actually needs to
07:19return a reference to itself.
07:22So that's what the return what's pointed out by this statement does.
07:26And then the type itself of the operator function is the rational reference.
07:32Also notice the test for assignment to self, this is very common, and you should
07:35do this every time you create an assignment operator.
07:39Also you'll notice that our four-function arithmetic operators do not return references;
07:43they return actual objects.
07:45That is necessary because the results of the expression should not return
07:48a reference, because you wouldn't want to be able to modify the results of an expression.
07:52So it actually returns an object, and in many cases, that object gets
07:56immediately destroyed after it's used.
07:58Operator overloading is a fundamental part of C++.
08:02It's as easy to do as defining a class method.
08:04We'll look at some reasons to use non-member functions for operator
08:07overloading in our next movie.
08:09Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Overloading operators with non-member functions
00:00Operator overloading is fundamental to C++.
00:03It's often accomplished with member functions defined in a class.
00:07In this movie, we'll look at why and how you may sometimes use non-member
00:11functions for operator overloading.
00:13Let's make a working copy of rational.cpp, copy that and paste it into our
00:18Working project and open it up.
00:19I am going to maximize this and scroll through it real briefly for those who are typing along at home.
00:24So what we have here is our Rational number class that we constructed for the
00:30movie on operator overloading as member functions, and it has operator overloads
00:35for the basic four function arithmetic:
00:37addition, subtraction, multiplication, and division there on lines 14 through 17.
00:42And we'll notice if we go ahead and run this that it works just fine.
00:47Come down here to our testing section, we'll see that we test these four
00:51operators there and these couts, and there are our results.
00:55Now there is one important circumstance where this technique just doesn't work,
01:00and we are going to go ahead and make a copy of our cout line where we do the
01:05addition, and I am going to change this to a + 14 instead of a + b.
01:11And if I save that and run it, you'll notice that that works exactly as expected.
01:15Here we have our line 7/1 + 14 = 21/1, and that's exactly what we would expect the result to be.
01:23And the reason this works is if we come up here to our operator overload for the
01:28addition, you notice that the right- hand side is expecting a rational object.
01:33And our rational object has a constructor that allows a type conversion, because
01:38it accepts the numerator, and it has a default value for the denominator, and
01:42you'll remember if a constructor will allow just one operand, then it will try to do a type conversion.
01:49And so this is actually working because we accept that one integer as our constructor.
01:55So this is just using the type conversion that's built into the constructor.
01:59And in fact, what it does is when it gets called for this plus operator
02:04function, and it's expecting this Rational object, it actually creates a
02:09temporary Rational object and uses it in the expression and then discards it.
02:14And so you can see the destructor here, right there is 14/1 destructor.
02:18That's that temporary object getting destroyed. So this is working beautifully.
02:22Let's see what happens if we try it the other way around.
02:25If instead of a + 14, I try a 14 + a.
02:30And I'll go, and I'll switch these around just for clarity, and I'll save that,
02:36and I'll compile and run it, and you see we get a very long cascade of errors.
02:41Look, it finally ended.
02:43And if you were to read through all of those and actually understand it, which I
02:46don't recommend that you try to do because it's a long cascade of errors, you
02:50would find that the reason this isn't working is because 14 is not a rational
02:56object, 14 is a literal integer object, and 14 does not have a plus operator
03:04that will accept a rational object.
03:06So the reason the other one worked is because the left-hand side was the object.
03:10The left-hand side of our overloaded operator is the object itself, and that's
03:15because it's an overloaded object in our class.
03:19So, when you overload an operator in a class, it expects the left-hand side to
03:23be the class itself, and that's how it knows what functional to call.
03:27So the solution is to move the operator overload out of the class.
03:31Let's see how that's done.
03:32We'll start by commenting this out inside the class definition, and then we'll
03:37come down here to our operator itself.
03:39I am just going to move this down, cut and paste, move it down to the end of our
03:44class here, and we'll start fixing it up so that it works.
03:49We are going to take the Rational class designator out of there, and we are
03:53going to take this const designator out of there, because that doesn't work if
03:57it's not part of the class anymore.
03:58And now what we need to do is we need to-- I am going to go ahead and maximize this.
04:03Now we need to have a left-hand side that's also a Rational object.
04:07So I am going to come over here, I want to say const Rational left-hand side and put in a comma.
04:12Now the problem is that here we're depending on having access to the private
04:17member variables, and we don't have that anymore.
04:19So all of these places of in need to become numerator and all of these places of _d
04:24need to become denominator.
04:26And we also need to have for the ones that don't specify right-hand side, those
04:30need to be left-hand side.
04:31So let's start by putting those in. Left-hand side dot.
04:34And obviously, those aren't available, but we'll fix that up in a moment.
04:39So all the places where it has just a bare one, which is really just these two places--
04:44oh, there's one more here.
04:46So now we have left-hand side and right-hand side in all of the places we need.
04:49This is going to get long, so I am going to put this on a line by itself.
04:54Now all the places with an _n are going to get the numerator accessor, there is
04:58numerator, and there's numerator.
05:00Now all the places with an _d are going to get the denominator accessor, there.
05:06And now we have successfully moved this operator outside of the function, and we
05:11have an operator overload that takes a rational number for both its left-hand
05:15side and its right-hand side, using our Rational class.
05:19So this allows the compiler to actually convert our integer constant to a
05:23rational, because of our implicit constructor, and now if we come down here, and
05:27I am just going to minimize this again so that we can run it.
05:31And we have, this didn't work the last time, I am going to save that and compile
05:35it, and you see that now it works just fine. 14 + 7/1 = 21/1, right?
05:43And there we have again our destructor for that temporary object that got
05:47created by the implicit conversion for the left-hand side of our overloaded operator.
05:53So there are definite circumstances where you want to use non-member functions
05:56for your operator overloads. And C++ supports this as well.
06:00In a nutshell, whenever you have a constructor that allows implicit conversions,
06:04you want to think about non-member overload functions.
06:07These functions should still go in your implementation file.
06:10Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using conversion operators
00:00One final type of operator overload that's worth understanding is the conversion operator.
00:05Sometimes called a conversion function, you can think of this like you are
00:08overloading a cast operator for casting your class to another type.
00:13Let's take a look at an example.
00:14We'll open our rational.cpp again, copy that and paste it into Working.
00:19I am going to come down here to the bottom--let's go ahead and maximize this and
00:24page through it briefly for the people who are typing along at home.
00:30I'm going to come down here at the end, and I'm just going to add something.
00:34Let's declare a string, and I'm going to concatenate one of our rational numbers
00:39to the end of that string and then cout with it.
00:44So what we would expect to have happen assuming that we had this functionality
00:48supported is that it would print out Rational as a string, and then it would
00:53print out the value of b in numerator over denominator notation.
00:57Of course, we haven't built the function of for this yet, so we don't expect it to work.
01:02But let's go ahead and compile and run and see what happens, and there we get
01:06a long cascade of errors for that. And it basically says no match for
01:10'operator +=' in 's += b'.
01:14So, the way we get this supported is not by adding an operator to string,
01:19because well that won't work, but rather by allowing a cast of our Rational
01:24class to a string, and we do this by adding a conversion operator to convert
01:29it to class string. So here's what that looks like.
01:32We say operator standard string, and we make it const safe.
01:37Now we come on down here, and we'll come down to the end of our class, and we
01:42will implement it like this.
01:45We have to tell it that this function is in the Rational class, and then we give
01:50it the body of our function like this.
01:51We're going to declare a constant for the size of our string.
01:55I am doing that because I'm actually going to use a c-string for this.
01:59I like this solution because it tends to be faster and use less resources than
02:04the alternative which would be to use a string string.
02:07So that takes a snprintf function which does a printf type formatting into a
02:13string with a maximum length, and it takes our numerator and denominator
02:18values and converts them into ints and prints them out like that, and it
02:22prints them into the string, and then we can return the string as an operand
02:25to a string class constructor.
02:27So it's taking a c-string and then converting it to a string class and returning that.
02:32So now we have our operator overload for this cast of string or our conversion
02:38operator, and we've declared it in our class up here on line 18, and we're using it down here.
02:44So let's save and compile and run, and there we have it, Rational as a string: 5/3.
02:50So you can apply this same technique to cast your class to any type.
02:55The conversion operator overload is a very useful technique that allows you
02:59to use your class as a first-class type, fully controlling how it is cast to other types.
03:04So let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Creating function objects
00:00By overloading the function operator, you can create a class that operates as if it were a function.
00:05This pattern is sometimes called a functor.
00:08This can be a handy technique for circumstances where you need to keep state or
00:12other context information with your function calls.
00:15Let's make a working copy of function-object.cpp and paste it into the
00:21Working project, and we'll open it up here in our editor.
00:24I'll maximize it so that you can see the whole thing.
00:28So we have here is a very simple class that overloads the function operator.
00:32There you see on line nine, operator (), that overloads the function operator.
00:38And so when we construct this object--like on line 13 we have a version
00:42that multiplies by times4, on line 14 we have have a version that MultBy times10, and
00:48on line 15 we have a version that MultBy times15.
00:53So the object is constructed with an argument that becomes the multiplier
00:58and gets stored in the private data member on line 6 called mult, which is the multiplier.
01:05Whenever the function operator is called it returns whatever argument is passed
01:09multiplied by the multiplier.
01:11So we see on line 16 through 21 that unlike a function, we can actually use
01:17different versions of this functor and have several versions of it instantiated
01:21at the same time to do different things.
01:23So let's go ahead and Compile and Run this, and we see that we have the times4
01:30version, the times10 version, the times15 version, and they are all doing what they are supposed to do.
01:36The function operator is a handy way to create an object that works like
01:39a function yet has the ability to keep state and other information between function calls.
01:43We'll see some more practical examples of this when we discuss algorithms in the standard template library.
01:48Now let's delete the Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Creating and destroying objects with the new and delete operators
00:00The New and Delete operators were covered in the chapter on operators;
00:03they are used to allocate memory in C++.
00:07Let's make a working copy of new-delete.cpp. We'll paste that into our Working
00:13Project and open it up here.
00:14We'll go ahead and maximize this so that you can see the whole file.
00:20It's worth noting here on line 28 that Eclipse is giving me an error with the Null Pointer keyword.
00:26This is a new keyword in C++.
00:29The problem is is that with this new version of GCC, null has been removed, the
00:36old NULL macro has actually been removed from the iostream header.
00:42And so this won't work.
00:44There are a number of workarounds. We could just use a void* pointer, and
00:48that'll work fine, or we can say if(!a), and it just gets promoted to a bool,
00:54and that works just fine.
00:57Really the correct form here is to use the new nullptr keyword, and Eclipse
01:01doesn't know about it, but it compiles and runs just fine, so that error we can safely ignore.
01:06In the error if I hover over it here, it just says Symbol could not be resolved.
01:12So here we have a simple class, it's got three data members that are integers
01:16and our constructor that are in line 17 simply constructs them with 0, 1, 2,
01:21and 3 as the default constructor, or if we pass it an argument it will start with
01:26that integer number and initialize them with that number +1 and +2. We also have
01:32defined a destructor and the destructor just prints out a message that says
01:37a destructor was called, and of course, the constructor also prints out a message
01:40that the constructor has been called.
01:41So it's a very simple class. And down here on line 27, we're allocating space for
01:47one of these using the new operator.
01:49The new operator of course returns a pointer to this new object.
01:52The nothrow parameter to the new operator simply tells it not to throw
01:56exceptions if it fails.
01:58And then the new operator takes the name of the class that it's allocating, and
02:02it allocates space for that class, and it calls the constructor.
02:06In this case it's calling the default constructor because we're not passing it a parameter.
02:10And then down on line 33, we destroyed the object that we've created by passing
02:15the pointer that was created by new to the delete operator.
02:19And so let's go ahead and Run this.
02:22Press the Compile and Run button there, and you see the message, allocating
02:26space for one A object that comes from line 26, and then we actually
02:30allocate space for an object, and it gets constructed on line 27 and so we
02:35see A constructor called.
02:37It didn't fail, so we're not getting our error.
02:39And on line 32, we're simply using the accessors a, b, and c to print out the
02:44value so we can see that we actually have successfully created an object.
02:47You notice that we're using the pointer member dereference operators there for
02:51a, b, and c right there on line 32, and then we destroy the object with the
02:55delete operator passing it the pointer that was created in line 27.
03:00And we can see A destructor called and space for A object deleted.
03:04If you want to, you can pass arguments to the constructorl right here.
03:08So we'll pass it a 5, and we'll Compile and Run.
03:12We see now it's printing out 5, 6, and 7, or you can allocate space for an array
03:18instead of just allocating one.
03:20So I can say 5 in brackets here, and that will allocate space for an array of five objects.
03:27If I do that I need to change the form of delete to match, and I need to give
03:31it empty brackets there, and it'll know how many objects were created by this pointer.
03:37So you have to make sure that you save your pointer to pass to delete.
03:41So now we're allocating space for five of these.
03:43It will still say one because I'm not going to change that.
03:46And you'll see that we get five constructors called, and five destructors called.
03:51And in fact, if I want to I can call printf on all five of these.
04:00We'll go ahead and just dereference with the I, rather than using this pointer operator.
04:06That looks like that, and then when I compile and run this you'll see we're able
04:14to see all five of those.
04:16When you're using new to create an array, you cannot pass arguments to the
04:20constructor, so it will always use the default constructor.
04:23And you always need to remember to use the array form of delete to correspond.
04:29The new operator is used for allocating space for objects in C++.
04:34Every object allocated with new must be destroyed with delete, otherwise your
04:38program will leak memory.
04:40For more details, see the New and Delete operators in the chapter on operators.
04:45Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Reporting errors with exceptions
00:00In C++, exceptions are used to report errors, especially in circumstances where
00:06errors cannot be reported locally.
00:07Let's take a working copy of exceptions.cpp from our Chap08 folder in our
00:12exercise files, and we'll go ahead and paste this in our Working project and open it up.
00:17I am going to maximize this so we can see the whole thing.
00:20I'm just going to take a moment and page through this for the folks who are typing along at home.
00:28This file is based upon the constructor's example from earlier in this chapter.
00:33The C++ language has complete support for exceptions.
00:36For our purposes, this movie is just a quick introduction.
00:40In this case we want to do some error checking in a constructor, and exceptions
00:44make that really easy.
00:45So let's start at the bottom, and you'll see that we're constructing this object
00:50inside of what's called a try block.
00:52So on line 72 we'll use the keyword try, and that's followed by opening and
00:57closing curly braces with code in between, and everything inside of that block
01:03will be executed in this try block, and so if any exceptions happen during that
01:08block, then the catch block is immediately called.
01:11And the catch block here has an argument which is the exception type, it's a
01:17reference to an exception object, and we'll see what that means in a minute, and
01:21it simply outputs a message to standard error using cerr, and it uses that
01:27exception object, and it calls the method on that exception object called what,
01:31and that will have a description--a human readable description, a string--to
01:36describe the error that happened.
01:38Up here at the top, I have a class that's based upon the exception object, and
01:42this is a very, very common way to do this.
01:45My class is called E, the capital E, and it disallows the default constructor on
01:51line 11 by declaring it in the private scope, and in the public scope it has a
01:56constructor that takes one argument a c-string, and it also has a method called
02:01what, which is overloading the what method in the exception base class--and again,
02:06this is a very common way to do this.
02:08So there is a couple of things here that you might not recognize.
02:11On line 13 in the constructor, you see it says throw with an empty pair of
02:16parentheses before its initializer list, and what this syntax means is it's
02:22specifying what exceptions are allowed to be thrown from inside this function,
02:27and that list is empty and so it's not allowing any exceptions to be thrown from
02:31inside that function, and that's actually pretty important in the exception
02:34class itself that the exception class doesn't throw any exceptions, because then
02:39it could get called recursively, and it could create more problems.
02:42And so we've done the same thing in the what method, and you'll notice that it's
02:46also declared as a const safe method, and it simply returns the message.
02:50So this is a very, very simple way to derive a class based on the exception
02:55class, and you can take this exact code and use it to great benefit in your own programs.
03:02This is pretty much the way that I do exceptions most of the time is just with
03:06that little piece of code.
03:07Now the way that this works, you'll notice our constructor here in our Animal
03:11class, down beginning on line 35, it simply checks the arguments that were
03:18passed, and if any of them are of length zero, it throws an exception with a
03:22message that says insufficient parameters. And so when we run this, because we
03:28actually called this way on purpose-- if you look down here, we're calling it
03:31with an empty parameter there for the sound--and so when we compile this and run
03:37it, you see that we get a message that says Animal x: Insufficient parameters,
03:42and if we look up here at our constructor, there is our
03:44exception that gets thrown, a little temporary E object that's constructed with
03:49insufficient parameters as its string.
03:52And so that'll set it up to have what return that string, and when we come
03:58down here in our catch clause, we see that we call what on that object, and we
04:02get that string there.
04:03So this is really a very simple way to take advantage of exceptions.
04:07Exceptions in C++ have a lot of different ways that you can use and a lot of
04:12things you can do with it, but 9 times out of 10, you just need it to give you an error message.
04:18And so this is a great way to do that.
04:20So this is just a quick introduction to exceptions in C++, but it's a useful
04:24example and the E class can easily be adapted for your usage.
04:27Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
9. Inheritance
Overview of class inheritance
00:00Class Inheritance is the ability to reuse code by deriving a class from a base class.
00:06The derived class will typically inherit and build upon some or all of the data
00:11and function members of the base class.
00:14Let's take a look at some of the terminology involved in class inheritance.
00:18The base class is a class that has members that are to be used in the new class,
00:23sometimes called the superclass or a parent class.
00:27The derived class is the class that is being created and is based upon the base class.
00:32Sometimes this is called a sub class or a child class.
00:38There are three different levels of member access, these access levels determine
00:43what other objects would be able to access class members.
00:46They are specified by the Member Access Specifiers.
00:50Members given public access are available to all objects,
00:54those are the base class, the derived class, and other unrelated objects.
00:59Protected access members are available to members of the base class and the derived class.
01:05And private access members are only available to the base class.
01:09In addition to adding members to a class, derived classes may also overload
01:14members of its base class.
01:16Overloaded members are used for changing or customizing certain behaviors of the derived class.
01:22Class Inheritance is a way to reuse code by basing one class on another class
01:28and customizing behaviors to match usage.
01:30C++ provides complete support for class inheritance, including overloading methods,
01:35polymorphism, and multiple inheritance.
Collapse this transcript
Exploring simple inheritance
00:00Class inheritance in C++ is simply a matter of creating a base class and then
00:05declaring the inheritance in your class definitions.
00:08Let's take a look at the simple example.
00:10So let's make a working copy of simple inheritance.cpp from our exercise files
00:15Chapter 9, and we'll paste this into the Working project and double-click on it to open it up.
00:21I am going to go ahead and maximize this.
00:23In this case we have a base class called Animal and three classes that inherit from it.
00:28We have Dog, Cat, and Pig.
00:31So Animal is the base class, and Dog Cat and Pig are the derived classes.
00:37Some people use the terms parent and child, but that's not as common.
00:40The Animal class is really very simple.
00:43It has three private data members for the name, type, and sound of the animal.
00:48It has a public method called speak and a protected constructor.
00:52The protected access specifier may be new to you.
00:55It means that these members are only accessible through derived classes.
01:00So by having the constructor of protected access and the default constructor as
01:06private access, really making sure that this base class cannot be instantiated
01:11on its own, only its derived classes may be used as objects.
01:16So if you have a class that you don't want to have used by itself, this is a
01:19good way to prevent it from being constructed. Now let's take a look at the Dog class.
01:27Notice on line 28, we declare the class Dog, and we declared as inheriting from Animal.
01:32So there's a colon followed by an access specifier and the name of the class
01:37that is being inherited, the name the base class.
01:40The access specifier here is a little bit different than what we might be used to.
01:45This basically controls how the base class members will be accessed by code that
01:50uses your derived class. This will almost always be public.
01:55It's very, very rare to see any other access used here.
01:58Now notice the constructor for the Dog class on line 31, it has initializers
02:05that call a base class constructor and initialize a private member variable.
02:10So you see right here we're actually calling the constructor for the base class,
02:18and we're providing it with the name and the sound for the Dog, and here we're
02:24initializing our own private data member which is not part of the base class.
02:28And you'll notice I've also provided a public method for walking the Dog.
02:33So the Cat Class is very similar.
02:36It inherits also from Animal, it has its own private data member for how many
02:40times it's been petted, and the Pig class again works the same way and has its
02:44own private data member for its being fed.
02:48So here in main, we instantiate three objects,l 1 Dog, 1 Cat, and 1 Pig, we give
02:54them names, and we go ahead and use them.
02:56So let's bring this back down, and we'll compile and run it and look at the results here.
03:06So here we're calling speak for each of these, and the speak method is in our
03:11base class and its right here.
03:14It says name the Animal says sound so here we have Rover the Dogs says Woof,
03:21Fluffy the Cat says Meow, Arnold the Pig says Oink, and we've seen where these
03:26names come from. The type of Animal and the sound is in these constructors in the derived classes.
03:34And the name of the Animal--in this case Rover, Fluffy, and Arnold--that gets
03:38passed into that constructor for each Animal, and then it gets passed to the base
03:43class in that constructor.
03:46And now here I walk the dog, I pet the cat, and I feed the pig, and you see
03:52that, that increments these counts.
03:54So for instance, if I walk the dog a few more times.
03:57Let's come down here to the end, and we'll compile that and run it.
04:03We see the dog has been walked two times and then three times.
04:07So class inheritance in C++ is really very simple. It's also very powerful.
04:12We will look at some more complex examples in the rest of this chapter.
04:15Now let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Reviewing friendship
00:00Sometimes you want to grant access to a class's private variables to another
00:04object or even a few select objects.
00:07This is accomplished with a friend declaration. Let's take a look at an example here.
00:12We'll make a working copy of simple inheritance.cpp and paste it into our Working project.
00:16I'm just going to maximize this and page through it real slowly for those who
00:21are typing along at home.
00:28Now, if we go ahead and compile and run this, we see that it's working just fine.
00:34And of course, this was described in our last movie on simple inheritance,
00:40it basically has these three classes that are derived from a base class, Dog, Cat, and Pig.
00:45Now each of these classes actually calls a constructor in the base class.
00:50So here we see Dog calls the constructor in Animal and Cat calls the Constructor
00:56in Animal and Pig also calls the constructor in Animal and the constructor at
01:01Animal is in the protected section.
01:03Now, if I move this constructor to the private section, I can just get rid of
01:09that, because that's the only thing in the protected section, and now I've
01:14changed the access from protected to private for that constructor.
01:19So if I save this, and I try to compile and run it, you'll see that it doesn't work.
01:25So one way to grant access is by putting it in that protected section, giving
01:30it protected access. Another way to do this is to add our derived classes as friends.
01:35So we can do this right here, and we can say friend class Dog; friend class Cat; and friend class Pig;
01:51This technique exposes all of the private members of the base class to the derived classes.
01:56So if I now compile and run this, you'll see that our example is working just
02:03fine, and we're able to access those constructors.
02:08So now those derived classes have access even to the private members of the animal class.
02:13This also works for functions.
02:16So, if I come down here and create a function, this function is trying to access
02:33a private data member from the Animal class.
02:36Now I come down here, and I say cout << "The dog is named " << get_animal_name(d), D for dog.
02:52Now of course, this isn't going to work, because my function is trying to access
02:55a private data member.
02:56So, I'll try and run that, and we get compiler errors.
02:59Now we see here within this context that it's trying to access this private
03:06data member right here.
03:09So, if I declare that function as a friend like this, and I can just take its
03:17function signature from down here and copy and paste it, and I'll actually need
03:28the name of the variable there and put in a semicolon.
03:31Now when I try to compile and run this, it works just fine, and it says
03:37The dog is named Rover, and now the function has access to the private data member.
03:42Of course, this function now has access to all of the private data members, and
03:48this can of course be convenient, but it can also undermine encapsulation and a
03:52lot of controls that make object- oriented programming, work so well.
03:56It's usually safer to use an accessor. And so we--of course--we do that like
04:00this, and then I can remove this from the friend and compile and run it, and it works just fine.
04:11So the friend declaration allows you to grant private member access to other
04:15classes and functions, and this can be handy at times, and it may even be
04:20necessary at times, but it needs to be used with caution.
04:23Most of the times it's best practice to access private members through the class interface.
04:28So let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Accessing the base class
00:00When you're creating classes with inherited base classes, it's sometimes
00:04necessary to access member data and functions from the base class.
00:08Let's take a look at how to do this.
00:10Make a working copy of simple-inheritance.cpp, and I am going to paste that in our Working project.
00:16Let me just maximize this and scroll through it real briefly for those of you
00:20are typing along at home.
00:26So this is our simple inheritance example, and it has this base Animal class
00:30that gets inherited by these derived classes, Dog, Cat, and Pig, and we initialize
00:37a Dog, a Cat, and a Pig down here, and we print out some data from them.
00:41And that looks like that, when we compile and run it.
00:43Now let's say, for example, that we wanted to add a method to the pig to speak
00:48its name Pig Latin, so we came down here, and we can say like that, and then we
00:59can write the method itself.
01:04And that will take the name of the animal, and it will append -ay to the end of
01:10it which we all know anything into pig Latin.
01:13Of course there are lots of other fun rules for constructing Pig Latin.
01:16For our purposes, it will do to just add -ay at the end of the word, and we
01:20can call it like this.
01:26And so I will just compile and run it you will see that it works, and it says Arnold-ay.
01:31So in this Pig Latin method, you will notice that I accessed the name method
01:35from the base class, which is Animal.
01:38In order do this, I use the name of base class, Animal, followed by two colons
01:43and followed by the name of the method that I am accessing.
01:47This specifies that the method is in the base class.
01:50So this syntax isn't strictly necessary here because there's no conflicting
01:55name in the derived class, but it's worth noting, and it's actually worth doing it this way
02:00because it can be necessary under other circumstances, and we will see some
02:04examples of that later in this chapter.
02:05Now let's delete our Working file and run Clean to get set up for next lesson.
Collapse this transcript
Understanding multiple inheritance
00:00Multiple-inheritance is the technique of inheriting from multiple base
00:05classes, and in C++ it's simply a matter of listing the base classes in the class definition.
00:10Let's take a look at a quick example. Make a working copy of simple-inheritance.cpp.
00:15I'm going to paste that into a Working project and open here--just take a
00:19moment and maximize this and scroll through it real quickly for those who are typing along at home.
00:27So this is a very simple example of a base classl and some derived classes.
00:31The Base class is Animal and the derived classes are call Dog, Cat, and Pig.
00:36And if we bring this back down to size, and we will compile and run it--press
00:42the big green compile and run button there--and we'll see that, that's how it
00:46works down here in our main function.
00:49We instantiate three objects from our derived classes, a Dog, a Cat, and a Pig, and
00:54they speak, and we also walk the dog and pet the cat and feed the pig.
00:58Now let's create another base class here, and we'll go ahead and we will enter
01:04this right after the Animal class, and we'll call this fur class, and this will
01:07be for the type of fur, and we need a string for that type.
01:14And we'll create a private default constructor so that it cannot be constructed on its own.
01:19And a protected constructor for use by the drive class, and you can call
01:29that with the type of fur in a string.
01:32And then we'll also create a public method to access the type string, and we
01:42actually don't need this namespace qualifier here because we were importing that
01:47entire name space up at the top.
01:50Using namespace standard there on line 3, that means we don't need to that.
01:54So there's our fur class, very simple and straightforward.
01:57Now let's go down to the Cat, and we'll have the Cat inherit the fur class as well.
02:03So put in a comma, and public and fur.
02:07Now the Cat is actually deriving from two base classes, Animal and Fur.
02:12And then in the constructor for Cat-- I am going to go ahead and maximize
02:17here so we can see this.
02:18In out list of initializers, I am going to add Fur, and we'll say that the Cat's Fur
02:26is silky, and now let's add a grooming method to Cat.
02:31Come down here, and we'll define the method, and you will notice that we are
02:40specifying the two different base classes here.
02:42Animal name, which actually does not have a name conflict.
02:46So if I were to just say name, that would work in this case.
02:49But Fur type does have a name conflict.
02:51If I were to omit the Fur::, the compiler would not know what to do
02:56with that because there is a type method in both of the base classes.
03:01I come up here to class Fur, you see there's type on line 33, and you come up
03:07here to the class Animal, and there is a type on line 19.
03:12So we'll come down here, and we will put in and cout for c.grooming--
03:22actually we have the whole cout there in the method, don't we? We can just
03:26put it like this, and we'll bring us back down to size, and we will save it and
03:31compile and run it. And there it says Fluffy grooms her silky fur.
03:36Multiple-inheritance in C++ is really very simple, perhaps too simple.
03:40While sometimes it really is necessary, many times it can create unnecessary complexity.
03:45For example, this example may have been more clear if the Cat class used a fur
03:51object as a property rather than inheriting it.
03:54The code would be simpler and easier follow, and the type method would no
03:57longer be ambiguous.
03:59So let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Exploring overloading methods and polymorphism
00:00Sometimes it's useful to overload a method that's defined in a base class.
00:04Let's take a look at how this is done.
00:06We'll make a working copy of simple-inheritance.cpp from our Chap09 folder of the ExerciseFiles,
00:12and we'll paste that into our Working project and open it up here.
00:16I am going to maximize this and just scroll through it really slowly so that
00:21those who are typing along at home may follow along.
00:27And this is the same example we've been using throughout this chapter.
00:30It's got a base class called Animal that gets inherited by three derived classes, Dog, Cat, and Pig.
00:39And then these are instantiated to objects in main, and we call speak method on
00:47the base class and the walk, pet, and feed methods on the derived class.
00:52So we'll go ahead and just compile and run this, and you can see how it works.
00:57And so down here in main, you see we call speak three times for each of them,
01:02Rover the dog says woof, Fluffy the cat says meow, Arnold the pig says oink, and
01:08then we walk the dog, pet the cat, and feed the pig.
01:11Let's say that we just want to change the speak method just for the cat.
01:16We can do that by overwriting the speak method in the cat class, and that works like this.
01:27First, we create a speak function member in the cat.
01:31And you notice that Eclipse gave us this little purple triangle, and if I hover
01:36over that it says Shadows Animal::speak, and that's because up here in Animal,
01:43there is a member function called speak on line 17.
01:49So now let's go ahead and define it. We have declared it, now we'll define it.
01:57And there we have that same little purple triangle there, Shadows Animal::speak, and
02:02we'll just simply say cout << "purrrrr" << endl;
02:10So now when we compile and run this, we really don't have to do anything else.
02:14When we compile and run this, you'll see that the cat is purring instead of
02:18saying Fluffy the cat says meow.
02:21And that's because this version of speak is being called instead of the
02:24Animal version of speak. That was pretty easy.
02:28In fact, if we want to also call the base class method, we can simply say
02:33Animal::speak right there inside of Cat::speak, and we can compile and run that,
02:40and then we'll get both.
02:42You'll notice here, Fluffy the cat says meow and purrrrr. All right.
02:46For right now I am just going to have the purrrrr in there, compile and run one
02:51more time so we can see that we have that, we have just the purrrrr.
02:55And so that's doing exactly what we expected to do, pretty easy, right?
02:58There is however one problem with this still, and in order to see that problem
03:03let's create a generic pointer and see if we can access all of these methods
03:07from the generic pointer.
03:08So I am going to go I am going to delete all of these calls to
03:11speak that are off of the objects, and I am going to create an array of Animal pointers.
03:19And I am going to initialize that array to the addresses of these three classes.
03:28And I am going to terminate it with a null pointer.
03:30I am using the C++11 null pointer keyword here.
03:35You'll notice that my version of Eclipse is complaining about that, and it says
03:40Symbol nullptr could not be resolved, but in actuality when I compile and run
03:45this because I'm using a version of GCC that understands C++11, it will actually
03:50compile and run just fine.
03:51That's just a problem with this version of Eclipse, and if you have a later
03:55version of Eclipse, it may actually not be doing that anymore.
03:57So now I am going to create a little for loop to loop through these pointers and
04:02call the speak method on them.
04:07And that's as simple as that, and so now rather than calling d.speak, c.speak,
04:13and p.speak, we're actually generalizing this because its code that gets run
04:18more than once, this is a very common thing to do.
04:22And so we have a generic pointer, it's an Animal pointer.
04:25It's a pointer to the base class, which actually should work just fine for each
04:30of these derived classes.
04:32And we have that array of those pointers, and we're iterating through that array
04:35and calling speak on each one of those pointers. So let's go ahead and compile and run this.
04:42So you can see this appears to be working just fine except that oh, you'll
04:46notice it says fluffy the cat says meow, it's not calling the derived class
04:51speak, it's calling the base class speak.
04:54So, we're already using an Animal pointer here, so it appears to just be
04:58calling the Animal method for all of these, and it's ignoring the derived method for Cat.
05:05So there is a way to fix this and the way to fix this is to declare speak as a virtual method.
05:13And so I am going to use the virtual keyword here, and that's a qualifier, and
05:19that qualifies that speak method as being inheritable.
05:23And you'll notice when I add that virtual keyword, that virtual qualifier, you
05:28notice we get a little warning on each of our derived classes here, and it says
05:32has virtual method speak but non-virtual destructor.
05:36So what this means is that whenever you declare a virtual method in a base
05:42class, you need to also declare a virtual destructor, and that looks like this.
05:48And that simply lets the destructor in each of the derived classes also
05:53overload the destructor in the base class. And this is really important because
05:57this makes sure that the destructor that's actually called matches the object
06:03that's being destroyed.
06:05In other words, if we're allowing certain methods to be overloaded in derived
06:10classes through a generic pointer, through a pointer to the base class, when
06:15that object is destroyed, if it's also destroyed through a pointer to the base
06:20class, this will make sure that the appropriate destructor is actually called.
06:27Even though Eclipse put up a warning there, it's not actually a hard class
06:30requirement, but 99 times out of 100 it's the right thing to do.
06:35So now we have our virtual speak and our virtual Animal, and so if I simply
06:40compile this and run it--I am going to save first and compile and run--now we
06:45see that even though we're using this generic pointer, and this pointer has been
06:49declared as type Animal, when we call it on a cat object, it calls the derived
06:56version of the overloaded class.
06:59You'll also notice that up here in this little green arrow, it now says
07:04Overrides Animal::speak.
07:06If we didn't have the virtual in here-- and I am just going to go I am
07:11going to remove the virtual there and save that.
07:13And we'll come down here, and we'll see that the little arrow has a different
07:17color, and it says Shadows Animal::speak.
07:19So that's just something that Eclipse is doing for us to show us the distinction.
07:23Shadow means that it's not virtual and Overrides means that it is virtual, so
07:29the now the little arrows are green and they say Overrides.
07:32So overloading methods in derived classes is a fundamental part of
07:35polymorphism, and this gives you a lot of power and flexibility in how you design your classes.
07:40By using the virtual qualifier, your overloaded methods can even be called through generic pointers.
07:47Now let's go ahead and delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
10. Templates
Understanding templates
00:00C++ templates are marvelously simple and powerful.
00:04In C++ templates are the feature that supports generic programming.
00:08In general terms generic programming refers to programming in terms of
00:12algorithms independent of types.
00:15Generic programming refers to code works independent of type.
00:18While C++ is a strongly typed language, there's still great benefit in being able
00:23to write functions and classes that are type agnostic, that is they operate on
00:28objects without concern for the type of those objects.
00:31Because C++ supports defining your own types through classes of operator
00:36overloading, it's possible to do a great deal of generic programming and
00:40templates while leaving implementation details to class as an operators.
00:45Template declarations look just like normal function or class declarations with one distinction.
00:51They are preceded by the template keyword and a set of type identifiers.
00:56These type identifiers are used as place folders by the template code to be replaced
01:01during compilation with actual types.
01:04When a function or class is instantiated from a template, the compiler generates
01:08a specialization of that function or class specifically suited to the types
01:13specified in instantiation.
01:15Templates are widely used in the C++ standard library which is why parts of the
01:20library are commonly called the standard template library.
01:23The generic nature of template classes makes them a perfect fit for use with containers.
01:28Templates programming is not entirely without its downsides.
01:32There some issues you need to be aware of. Overuse of templates can lead to code
01:37bloat and longer build times.
01:39Because the compiler must generate specializations for every instantiation of the template.
01:43The amount of code to support that template can grow rapidly with use.
01:48Compilers tend to have a difficult time generating sensible error messages with
01:52templates, so debugging can be challenging.
01:55And because templates tend to live in header files, changes to header files with
01:59templates can lead to recompilation of a larger portion of your code than would
02:03otherwise be necessary.
02:05C++ templates are a very powerful feature that is also simple to implement and support.
02:12They have great advantages over other generic programming solutions--in
02:15particular preprocessor macros--and they are widely used to implement containers
02:20and other generic objects in the C++ standard library.
Collapse this transcript
Understanding template functions
00:01C++ supports both template functions and template classes.
00:04In this movie, we will looking at template functions.
00:07Let's make a working copy of template-function.cpp, and we'll paste it into our
00:12Working project here.
00:14Here we have a simple example of a template function that gives the maximum
00:17value of two parameters. The keyword typename is commonly used here on line 5
00:24to indicate the type that will be templated, but the keyword class also works and is often used.
00:30Just be aware that at least in this context, either of these tokens means
00:33exactly the same thing.
00:36The simple template is both type agnostic and type safe.
00:40It's type agnostic in that it'll work for any type that has support for the
00:45greater than operator, and it's type safe in that the compiler will generate a
00:49specialization of the function for that given type.
00:53So if we call it as we have in line 10 with two integers, it'll generate a
00:58specialization of the function that operates on type int and returns type int.
01:04So I am just going run compile and run here, and you'll see that our result is int.
01:09And if I change this so that it has two string literals, now it'll
01:16generate a specialization that works on cStrings and returns a cString, so
01:22compile and run, and we see that it thinks, the aaaaa is larger than the
01:27baaaa, and that's because cstrings don't actually work very intelligently with
01:32greater than operator.
01:33On the other hand, if we tell this to use the C++ string class instead--now we
01:40can do that by specifying it like that-- and now we compile and run it, we see we
01:47get a more intelligent result because the C++ string class actually supports the
01:51greater than operator properly.
01:53So let's take a look at a slightly more complex example.
01:57Go ahead and delete this, and we'll run Clean, make a working copy of join.cpp
02:06there out of our Chapter 10 folder in the exercise files, and open it up, let's
02:11maximize this so that we can see it, and I'm just going to scroll a little bit
02:16so that those folks who are typing along at home can follow us.
02:20So this function will take any container, and it'll join the elements into a new
02:26container with a separator between each element and return the new container
02:31And down here in main, we'll see a couple examples of how this is used.
02:35The first example on line 23 joins the characters of the string with a separator
02:41of a colon into a new string, And the version done on line 27 joins
02:47strings from the vector, and it separates them with comma and a space.
02:52So let's take a look at how this works.
02:54So you see that the template declaration specifies three different types:
03:00the containerType, the returnType, and the separatorType, so these
03:03can all be the same or they can be three different types.
03:07You'll notice the two of them have default types, the second one here,
03:13typenmae retT = cT, and so if a returnType is
03:19not specified it will default to containerType, and the third one is little
03:23bit more complex, separatorType, and if it's not specified, then it'll
03:28default to the value_type of the containerType.
03:33So you can see you can do a lot with this most of the time this level of detail
03:37is not necessary but I just wanted to show you how powerful this can be.
03:41The function itself it returns the returnType, and it takes two arguments
03:47an object of the containerType and an object of the separatorType.
03:51It declares a temporary variable for the returnType called out.
03:56It sets up an iterator, and it iterates through the container and takes each
04:01object and concatenates it into the out container, and if we're not at the end
04:07it adds a separator to out, and then it returns out, it's really very simple.
04:14So let's go ahead and bring this back down and run it. So we'll press the compile
04:19and run button there, and we see how powerful this is.
04:23We taken a string, s1, that says this is a string, and it's taken each character and
04:29separated them out by colons and created a new string with that result.
04:34And then it takes a vector of strings, which is like an array of strings--so
04:39factor is a C++ containerType, and so it's got all three of those
04:43strings, this is a string, this is also strange, yet another string--
04:47and it joins them into a string--see it's output container is specified as
04:53string, and a separator is a string containing a comma and a space--and so our
04:58result here is all these strings separated by a comma and a space all in one string.
05:04So you can see how powerful and flexible this is, and it's just this simple bit of code here,
05:08and it can do all of that, and it can work in all these different types.
05:12It can really work with any containerType that supports those operators.
05:16It just needs to support that plus equal operator, and that's really all that's necessary.
05:24So template-functions are a form generic programming that are easy to create
05:29and can be very powerful and very useful. For many of the purposes that we used
05:33to use C macros, C++ template functions are more powerful, more flexible, and less prone to error.
05:40Let's delete our Working file and run Clean to get set up for the next lesson.
Collapse this transcript
Using template classes
00:00Template classes are commonly used for operating on containers.
00:04Let's take a look at template-class.cpp and make a copy of it and paste it into our Working project.
00:12Open it up in the editor, and I'm going to maximize it here so that we can see it.
00:16So this class, you'll notice at the top here I've an exception class, and that's
00:21explained actually in the chapter on C++ classes, and I'll show you how that's
00:26used, but this is the same class that's used there, and it's one that you're
00:30welcome t