User:Blacken~enwikibooks/C++ Concepts and Programming/Introduction to Programming

= Introduction to Programming =


 * ''Some people may not feel comfortable jumping feet-first into programming without a little understanding of the background material. Others may want to see "the big picture" before they delve into the minutiae. The first part of this chapter is optional; the second, Setting Up Your Work Environment, can be safely ignored if you already have a working toolchain on your computer.

At its most basic level, a computer understands machine code. This is raw data, zeroes and ones, that correspond with circuits in the computer's CPU (a generalization, but not an unfair one). Machine code is hard to read--not impossible, but you wouldn't want to spend your day doing it. A computer cannot understand source code, the lines of mostly-English text that you write in Notepad or some other text editor. The toolchain mentioned above--the compiler and linker, about which we will go into detail later, is the mechanism for translating this source code into machine code.

When we use computers, we deal with them in abstractions. Our working knowledge of a computer is based upon abstractions that hide the deepest complexities from us. The computer contains interpreting layers that turn human-readable code into computer-readable machine language. The computer handles the ugly process of taking many different sources of memory and presenting them to you, the programmer and the user, in a unified fashion that is easy to work with.

These are not, however, the abstractions you'll see most directly as a programmer; you'll have to deal with memory, but unless you're doing something that's probably ill-advised you will rarely ever have to muck about with direct memory addresses--that's one of the abstractions your programming language handles for you (at least if you use C or C++). Each programming language is different in that it tailors its abstractions to a particular mode of thought, a particular kind of abstraction.

Assembly language, also known as assembler or ASM, is a very basic abstraction of the underlying computer hardware--an abstract. Its saving grace is that it allows the use of human-readable names and instructions; the assembly language instructions directly correspond with a machine code instruction, but is named in such a way that people can remember them and use them. The use of assembly is not cross-platform--it is restricted to the kind of computer on which it was created, because the dialects of assembly language used on different computer architectures (such as i386, PowerPC, or SPARC) differs. If a program written in i386 assembly must be ported, or made to run on, a PowerPC architecture, the program itself must be entirely rewritten. The upside of such a limited, localized programming language is that it is generally faster and more efficient than the corresponding program written in a more abstracted language. This is less and less the case, however, as optimizers built into compilers keep improving.

The next step up from assembly language are imperative languages. These include BASIC (Beginner's All-purpose Symbolic Instruction Code), a simplistic programming language included on many older computers, and C, the language you will shortly be acclimatized to. Imperative languages are like assembly language in that they are used to tell the computer what to do directly--"do this, then this, then this." They are a significant step up from assembly language, as they typically are written in a format more approximating a human language. The abstractions an imperative language provides are still limited in that they require the programmer to think in terms of the computer. There is a metaphor shear, a disjunction between the computer you are using to model the situation or problem and the problem itself. Many problems do not lend themselves well to this kind of metaphor translation.

From here, the path diverges a bit. There are many programming paradigms for higher-level languages; the applicability of a higher-level language to any given task depends largely upon its design, its "outlook on life." This makes some higher-level languages more suited to certain tasks than others, based on how they view problems. For example, the Lisp programming language and its derivatives reduce everything to binary pairs, with which lists are made and used. Declarative languages, such as Prolog, turn programming on its head by declaring something to be true and letting the computer figure out how to get there.

Object-Oriented Programming
Languages such as Lisp or Prolog are good for problem sets with definitions that are not always exact. Both have a home in artificial intelligence research. But they, like all programming languages, are built on metaphors, and their metaphors tend to break down when they are presented with problems that are outside of the class of problem they are designed to solve. On the other hand, object-oriented programming, or OOP, in languages such as C++, results in a generalized higher-level language. Instead of limiting a user to a certain set of tools and a certain "view of the world," they provide the tools for the programmer to represent elements of the problem itself. Objects in the problem space, or section of the program that represents the problem or task itself, directly represent elements of the problem.

A trivial example might be that of a car. A car can drive, of course, barring many hundreds of repairs that it could need (that, much like some kinds of bugs in computer programs, remain very well hidden until they explode). If you need, for some reason, to include a car in a problem space, the method of actually using the car changes from language to language. In BASIC or C you would have to say drive the car. This is not to mean some imaginary person jumps in the car and begins to drive it--the program must externally drive the car, must model the firing of cylinders and turning of the wheels outside of the car itself.. A special procedure or section of code that is not part of the car itself would have to drive it. In an object-oriented language, such as C++, you say something subtly different: the car drives. The car models itself. This allows for a metaphor that has less chance of shearing and looks more like the real world.

C++, while directly derived from C, inherits its ideas of classes from Smalltalk, an older language still in sporadic use and the first successful one to support object-oriented programming. Smalltalk espoused a "pure" object-oriented programming paradigm. C++ does not. There is nothing saying that you cannot write C++ like you would write C, in an imperative fashion. This is perfectly legal, and is not a "bad" thing to do. But the flexibility of object-oriented programming always remains available to you. C++ is not a strictly object-oriented language; that's why it is referred to as multi-paradigm. Standard C++ has an eye toward pragmatism, not an academic ideal. Despite this, the central ideas of Smalltalk are good ones and make it easier to understand why object-oriented programming is so powerful.


 * 1) Everything is an object. In this case, an object is a variable--a spot in memory that stores data. An object is a special kind of variable, though, that can also hold functions (subprograms). Essentially, it's a variable that can do things to itself (you'll pardon the lewd implications).
 * 2) Every program is a group of objects that tell each other to do things. In C++, an object is told what to do by way of a public method, which is a special type of function tied to that object that is also available to other objects. An object can have private methods that only it can access, as well.
 * 3) Every object is made up of other objects. For those with experience in BASIC or C, this may seem difficult to understand. In those languages, you do not see the basic variables--integers, floating-point numbers, strings of text--as objects. In Smalltalk, all of those, and every object a programmer creates, is derived from the Object object. This provides every object with a basic interface, in the event (one might call it a certainty) that another object needs to talk to it. In C++, this is not quite the case. Primitive data types such as integers are not objects, but that is an artifact of being originally from the procedural, imperative C language. There are a number of workarounds and methods used to abstract away the difference between these primitive data types and the objects of an object-oriented C++ program.
 * 4) Every object has a defined type. In C++, this would usually be written as "every object is an instance of a class," but that is just a question of terminology. This matters because the type of the object determines what methods the object "knows" how to do.
 * 5) Every object of a particular type has the same interface. In this case, interface is defined as "the set of public methods that may be used with an object." The implications of this statement may not be immediately apparent, but will become clear in time. For now, understand that an object of type  is also an object of type   (in the jargon of C++,   inherits or derives from  ), any messages that you can send to an object of type   can also be sent to any object of type  --or a , or a  , or perhaps a   if necessary. This concept results in extremely flexible code, as we will see later.

A further discussion of objects, as well as object-oriented programming, will continue later. For now, we need to get you started with the tools you need to make programs in C and C++.