Without ways to store data and manipulate it, a programming language would be pretty useless. Luckily, C can do just about anything you want to with data. Let's first look at the basic types of data, and then at the basic operations you can perform on them.
Whole Numbers
Integers are one of the simplest kinds of data to deal with, so they'll make a good starting place. Integers are things like -2 or 17 -- real numbers without decimal points. In C, as in most languages, you can create variables to hold different types of data. In C, all variables have an associated type. Variables also must be declared at the top of every function, and must be declared before they can be used. To declare an integer, we use
int
. An example of this is below:
main() { int i; int j; /* More stuff ... */ }
This snippet of code declares two integer variables,
i
andj
. These declarations can also be combined onto one line using a comma, like so:
main() { int i, j; /* More stuff ... */ }
This is usually the way you'll see variables declared. It is important to note, though, that a variable declaration in C is not the same as a variable initialization. The two integer variables
i
andj
don't have anything stored in them yet. You have to set them equal to something before you use them. We'll get to that in a minute, after we see the other basic types.There are a few other types of integer variables worth noting in C. The first of these is the type
short
.short
is just likeint
except that it takes up less memory. Memory is not as big of a concern these days as it was before computers were manufactured with huge amounts of memory. Similar toshort
islong
, which takes up more memory thatint
. The advantage to using more memory is that you can then store larger numbers in the variable. The exact amount of memory that each of these types takes up is different from system to system. You can find out how much space each kind of variable takes up on your machine by using thesizeof
operator. For instance,sizeof(int)
returns the number of bytes taken up by a variable of typeint
(more about bits and bytes later).
Floating Point Numbers
The other major type of numeric data is floating point data. Floating point data is any number that contains a decimal point, like 3.14159 or 2.718281828459, or even 17.0. C treats all of these in the same way. The basic type for floating point data is
float
. There is also the typedouble
, for "double precision floating point numbers."double
uses more memory and can store bigger numbers. In this tutorial, I will tend to usedouble
overfloat
, but that's just me; you can use whichever you'd like.
Characters
Characters are the major type of non-numeric data in C (sort of). A character is any value from the ASCII code. Because of this, in some circumstances, characters act like integers, but we'll get to that later. Character literals are denoted in C by enclosing them in single quotes, as in
'a'
or'\n'
(this is the newline character that we've already seen. Even though it looks like two characters to us, C treats escape sequences as one. The is also true for octal representations of characters.). A character variable is declared as typechar
, and is defined to take up one byte of space.
Boolean Data
Boolean data comes in two types: true and false. Unlike many languages, standard C does not have a boolean type. Instead, the number 0 evaluates to false, and everything else evaluates to true. It is customary to use 1 for true and 0 for false, but not necessary. If you find this too confusing, you can add the following lines of code to the top of your program (usually before
main()
):
typedef int bool; #define true 1 #define false 0
This piece of code lets you declare variables of type
bool
, and makestrue
synonimous with 1 andfalse
synonimous with 0. It is worth taking a moment now to explain a bit about this code, because it can be very useful. The second two lines use another preprocessor directive, this time#define
. During compilation, the preprocessor looks at the#define
lines and replaces the first argument with the second everywhere it appears in your program.#define
lets you declare constants usable throughout your program without using up extra memory, and also avoids some of the pitfalls associated with global variables. These are lines, though, that you DON'T want to end with a semicolon, since the preprocessor replaces terms with everything up to the end of the line. Had you instead written#define true 1;
,true
would be synonimous with1;
, which would cause all sorts of problems. I will go into more detail about thetypedef
mechanism later; for now, just trust me that in this case it makesbool
synonimous withint
.
Operations
So now that we've got all these variables, what do we do with them? That's where operators come in. Operators let us manipulate the data we've stored.
First of all, there are the standard mathematical operators:
+
,-
,*
, and/
. These work more or less the same way they did in algebra class, and follow the same order of operations (multiplication and division are evaluated before addition and subtraction). Another necessary operator,=
, doesn't work in quite the same way.=
is the assignment operator; it lets you assign a value to a variable. Look at the following example:
main() { int i, j; double d; i = 7; j = 9; d = 1.3; /* More code ... */ }
Now, we have initialized these variables so that they no longer contain garbage. We can now use them:
i = i + j; /* i now equals 16 */ d = d + j; /* d now equals 10.3 */ i = d * j; /* i now equals 92 */
Notice that in the last example,
i
gets the value 92 instead of 92.7. This is because we tried to assign a floating point number to an integer variable. When that happens, C truncates (it does NOT round) the number back to an integer. In this case, C changed the type of variable automatically. But you can also tell the program to change the type via a mechanism called "casting." Casting changes the type of a variable for one statement, though it does not change it permanently. A cast looks like the following:
i = ((int) d) * j; /* In this case, i = 90 */
As you can see, a cast consists of putting a type name in parentheses before the variable you want to change. In this case, the cast truncates
d
before the multiplication, which setsi
to 90.C also has a modulus, or remainder, operator,
%
. For instance,10 % 9
is 1, while9 % 9
and9 % 3
are both 0.Many assignments are so common in C that there are shorthand forms of them. Recall the statement
i = i + j;
from the above example. This can be rewritten asi += j;
. The two statements are synonimous. The kind of shorthand can be combined with most of C's operators. A list of the operators that can do this is below (don't worry yet about the operators you haven't seen):
+= -= *= /= %= <<= >>= &= |= ^=
C provides yet another shorthand in the increment and decrement operators. Instead of saying
i = i + 1;
, you can usei++;
. The--
operator works the same way. Either of these operators can be used as either a prefix or a suffix, though it does change the meaning slightly. Look at the following example:
int i, j; i = 1; j = 0; j = i++; /* Now, j equals 1 and i equals 2 */ j = ++i; /* Now, j equals 4 and i equals 3 */
When you use the increment or decrement operator as a suffix, the assignment happens first; as a prefix, the assignment happens second.
The last class of operators I'll discuss here are the logical operators. Logical operators produce boolean values as their output. The operators are
==
for equals (WARNING! Notice that logical-equals is a double equal sign; a single equal sign is the assignment operator!!);&&
is the logical-and operator;||
is logical-or;!
is logical-not; and!=
is logical-not equal. The use of these operators will become more clear in later sections.
Back to the Structure of a C Program | On to Basic Input/Output | |
Back to the Outline |