Gillius's Programming

More than just the > and < can use used to make decisions with variables. There are a few more operators.

Comparisions return a value which can actually be stored in a variable called bool, which is short for boolean. Comparisons either return true(non-zero) or false(zero). If the expression in the if statement is non-zero it will evaluate true and execute its code. Variables can be left by themselves in an if to test for this as well:

if (x) cout << "X is not zero" << endl;

! used by itself means "not" which reverses the expression:

if (!x) cout << "X is zero" << endl;

In addition to comparing numbers, boolean expressions can also be compared using the logical comparison operators (use parenthesis to seperate the expressions):

if ((x > 10) && (x < 15)) cout << "x is between 10 and 15" << endl;
if ((x == 5) || (x == 6)) cout << "x is 5 or 6" << endl;
if ((x != 5) && (x != 6)) cout << "x is neither 5 nor 6" << endl;

The comparasions can be assigned to a bool variable like this:

bool xtest = (x>10) && (x<15);
if (xtest) cout << "x is between 10 and 15") << endl;
if (!xtest) cout << "x is not between 10 and 15" << endl;

This last segment could also use an else:

bool xtest = (x>10) && (x<15);
if (xtest) cout << "xtest is true" << endl;
else cout << "xtest is false" << endl;

A very common mistake made by programmers moving from other languages is using the assignment operator, =, instead of the equals operator, == (double equal signs). Both of these operators are valid in an if, but an assignment is rarely used in this case.

if (x = 5)  //this is ALWAYS true since it will evaluate for 5, which is non-zero
if (x == 5) //this is probably what the programmer meant

On most compilers using the assignement instead of the equals will generate a courteous warning.


Functions in C work just like they do in any other langage, except that C programmers tend not to make the distinction between procedures, which do not return values, and functions, which do return values. Like the main function, each function declaration requires 3 parts: the return type, the function name, and the parameter list. A function prototype(some programmers call this the "interface") in C looks like this:

void MyFunction();

This function does not return a value, denoted by void, and its name is MyFunction. There are no parameters, as denoted by the lack of parameter information inside the parenthesis. Notice that the prototype ends with a semi-colon. This tells the compiler that the function exists, but will be declared later(this part is sometimes referred to as the "implementation"). This is done so that the main function is at the very top of the program while the code for other functions is declared below. This is not a nessacity--functions can be declared without prototypes above the main function, but the program becomes harder to read and follow. Below is a short example program demonstrating a basic function call:

#include <iostream>
using namespace std;

void DisplayGreeting();
void SayGoodbye();

int main() {
  DisplayGreeting();
  SayGoodbye();
  return 0;
}

void DisplayGreeting() {
  cout << "Hello user!" << endl;
}

void SayGoodbye() {
  cout << "Goodbye!" << endl;
}

This method for functions is pretty straight forward. Parameters are not much more complex:

void DisplayNumbers(int numb1, int numb2, float numb3) {
  cout << "Number 1: " << numb1;
  cout << "Number 2: " << numb2;
  cout << "Number 3: " << numb3;
}

Notice that each variable in the list needs a variable type in front of it. Call the function like this:

int main() {
  int x = 26;
  DisplayNumbers(50, x, 34.1);
  return 0;
}

Returning values require only changing the variable type before the name and using a return command at the end of the function.

float GetSquare(float numb);

int main() {
  float sq = GetSquare(3.0);
  cout << "sq is " << g;
  cout << "Five squared is" << GetSquare(5.0);
  return 0;
}

float GetSquare(float numb) {
  return numb * numb;
}

A shortcut method to the function prototyes is to only include the variable type. The compiler does not need to know the name until the function declaration later, however most programmers still include the variable name because not only does the name help to describe what the variable is, but also because it is easy to write the function, then copy/paste the first line to the top of the program and just simply replace the { with ;. Here are several ways to prototype the same function:

float FindDistance(float x1, float y1, float x2, float y2);
//or use:
float FindDistance(float, float, float, float);
//Notice how the names helped to clairify what is being passed

float FindDistance(float x1, float y1, float x2, float y2) {
  return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}

Notice how including the names clarified the function's purpose. Also, on a side note, notice that in the implimentation of FindDistance does NOT use a square function, since C does not have one, however the programmer can choose to write a square function.


The true purpose for the int main() has not yet been fully explained. Like other languages, functions return values in C. Your program is called from a function in the operating system just like it was any other function. An integer can be returned to the operating system to denote an error in the program. Although this is a rarely used feature in Windows, it is used in cases like scandisk, which the main function returns non-zero if the user canceled or if an error was encountered, that is how the computer knew to display the "scandisk was canceled or had an error" message. In UNIX and Linux environments, the return code is often used to control the flow of scripts. The return code can also be used in DOS/Windows batch files. Since some value is always returned, C/C++ gives a warning about void main() being void and not int.


The syntax for loops in C requires three parts, the beginning condition, the test, and counter update. In reality, each of these lines are simply just lines of code that are executed before the loop and after it. Below is a simple C loop:

for (int c=0; c < 9; ++c)
  cout << "Loop counter is " << c << endl;

The loop executes until the test becomes false, also note that if the test BEGINS false the control will never enter the loop. Notice there were no braces on the for loop, but if there were multiple lines the code would need to be in a block.

A while loop continues until the condition given becomes false, and like the for loop, if the condition starts as false control will never enter the loop. The parameters for the for loop can be better understood by looking at how the same code is written as a while loop:

int c = 0;
while (c < 9) {
  cout << "Loop counter is " << c << endl;
  ++c;
}

A do..while loop is virtually the same thing as a while loop, except that the test comes at the END of the loop rather than at the start, so that the control will enter the loop AT LEAST once. Do..while loops are used mostly for input protection:

float x = 0.0f;
do {
  cout << "Enter a number between 5 and 6: ";
  cin >> x;
} while ( ( x > 5.0f ) && ( x < 6.0f ) );

The two major diffences between this loop and the rest are using two keywords, one at the beginning, and one at the end, and using a semi-colon after the structure. Notice that the variable is declared outside of the loop's "scope." A variable declared in a block can only be viewed in that block and blocks inside that block. So if a variable would be declared in the loop, only the loop can see that variable.


User input, espically with menus, will require many decisions. Imagine a menu of choices, and the user enters a number to select which option he or she desires:

#include <iostream>
using namespace std;

void EnterNewUser();
void DeleteUser();
void FindUser();

int main() {
  bool cont = true;//For use in while loop
  while (cont) {   //Contiune until user selects quit
    //Display Menu
    cout << "Network Management--Users" << endl;
    cout << "1 - Enter a new user" << endl;
    cout << "2 - Delete a user" << endl;
    cout << "3 - Find a user" << endl;
    cout << "4 - Exit this menu" << endl;

    int choice;
    cout << "Enter choice: "; cin >> choice;

    if (choice == 1)
      EnterNewUser();
    else if (choice == 2)
      DeleteUser();
    else if (choice == 3)
      FindUser();
    else if (choice == 4)
      cont = false;
    else
      cout << "Invalid choice!" << endl;
  } //End of while loop
  return 0;
}   //End of main()

After some time the if..else if statements can become cumbersome and redundant. C allows for a shortcut decision structure which only works on integer types (char, short, int, long). Below is the same decisions from the program above except in a "switch" statement:

switch (choice) {
  case 1:
    EnterNewUser(); break;
  case 2:
    DeleteUser(); break;
  case 3:
    FindUser(); break;
  case 4:
    cont = false; break;
  default:
    cout << "Invalid choice!" << endl; break;
}

A block of code under the case need not be in braces, UNLESS a variable is declared inside the switch, then braces are needed to define its scope. The break statement tells the computer to exit the swtich instead of continuing the statements. If the breaks are eliminated, control simply passes through any other case statements and continues until the end of the switch or a break statement. This is not used often, but the following is an example of how a switch could be used for this:

int x=0;
cout << "Enter an integer: "
cin >> x;
switch (x) {
  case 1:
    cout << "X is 1" << endl;
  case 2:
    cout << "X is 2 or 1" << endl;
  case 3:
    cout << "X is 3 or 2 or 1" << endl;
    break; //This will stop control from going into default
  default:
    cout << "X is less than 1 or greater than 3" << endl;
}

And an example of using braces (x can ONLY be seen inside the braces and not in other cases or outside the switch, as the braces denote its scope):

switch(x) {
  case 1: {
    int x = 0;
    cout << "Enter for x: "; cin >> x;
    cout << "x is " << x << endl;
    break;
    }
}

When using larger amounts of data, a seperate name for each variable would be redundant and masochisitc at best, so a better method would be to use an array. An array declaration is just like a variable declaration except a number is added:

int myarray[10];

This statement declares an array of 10 integers. The indexes for the array start from 0 and go to 9. For those curious why the indexes are numbered this way, Pointers I will explain in depth the exact reason for this.

A for loop is the best structure for accessing a fixed size array like this one. This program asks the user to enter data into the array above then displays it.

for (int c=0; c < 10; c++) {
  cout << "Enter an integer: ";
  cin >> myarray[c];
}

for (int c=0; c < 10; c++)
  cout << "Element " << c << " is " << myarray[c];

Accessing the array only requires the name, followed by the element number in brackets, which can be a constant (myarray[2]=3;) or a variable (myarray[c]=6;). However, when using variables to access the array, in C there is NO error checking. The statement myarray[50]=10; will execute in the above program despite it being obviously out of range. This will overrun the array, and write in memory which may contain other variables, or even your code! Obviously this will cause major problems and the program may not crash immedately until the corrupted memory is accessed, or may never even crash at all! So if a program is performing weird actions without any other explanation, check for "memory overruns" like this one. Security experts will call this problem a "buffer overrun", and buffer overruns due to user or program input and are the current leading cause of virii and worms.

To initalize an array, braces and data seperated by commas will fill the array with data, like this:

int myarray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

You do not even have to initalize all elements either. If the list stops before the end of the array, the rest of the elements become 0.

int myarray[10] = {}; //All elements are 0

Two dimentional arrays, or matrices work just like their one-dimentional or vector counterparts, just that they use more brackets. The same pattern applies for 3D and so on to infinity.

int matrix[5][5]; //2D array
int space[100][100][100]; //3D array
int wow[3][3][3][3]; //Even 4D and more work!

Keep in mind that 2D arrays are really an array of arrays. For example the matrix above is really a 5 element array contaning int arrays of 5 elements. I mention this for understanding that accessing an array sequentially requires looping the last values, for faster access, since it accesses sequentially and does not jump around. Two ways of looking at the elements is [row][col] or [y][x]. This is best shown in code:

for (int row=0; row < 5; row++)
  for (int col=0; col < 5; col++)
    cout << matrix[row][col] << endl;

This is the fastest way to access the array in memory. If row and col were switched, the computer would jump in memory. The best way to show this is visually. In memory the array is stored like this:

[0][0], [0][1], [0][2], [1][0], [1][1], [1][2]

Going from [0][0] to [0][1] requires only a simple addition to the computer, while going from [0][0] to [1][0] the computer needs to skip over 2 elements.

Initializing an array makes sense when seen--you need to initialize the array with arrays:

myarray[2][2] = {{56, 76}, {12, 78}};

Notice how arrays are the elements, which have elements as well.


Strings in C are MUCH more compicated than in a language like BASIC. Other languages like BASIC tend to hide the fact that strings are arrays of characters and need to be treated that way. In C++, many programmers use the string class which lets the programmer use strings like in BASIC. I will first describe C-style strings.

The asterisk after char means it is a pointer or an array. Until the Pointers I lession, regard both char[] and char* as meaning the same thing. I note this because most programmers refer to a C-style string as char *, and when passed to a function the parameter type is char *. When you declare a string, the easiest way to do it is to declare it as an array.

char mystring[500] = "";

This declares a string of 500 characters. Note the double quotes. Each string must ALWAYS be initialized before using it, since all C-style strings must end with a NULL character (ASCII 0). The compiler interprets strings this way--it contines to process characters (in a cout or cin or string operation) until it hits a character with value 0 -- the NULL character. If this NULL character does not exist, then the computer will process the memory in the string and flow over, until it happens to hit a NULL by chance or runs out of memory. This is also considered a memory overrun and will cause your program to crash or print out random characters.

Strings cannot be copied since they are arrays. This rule applies to any string operation. Below are some things that will not work with strings that might for other variables. Also keep in mind the array needs to be large enough to contain any possible strings that may enter it, or the array may "overrun."

char str1[100] = "Mom";
char str2[100] = "Dad";
char str3[100] = "Mom";

str3 = str1 + str2; //Cannot add strings like this
if (str1 == str3)   //Cannot compare strings

In order to work with strings like this, one needs to use the C library string functions. Below are equalvalent statements to those above that work (the declarations are not repeated):

/* C-only code */
#include <string.h> //For C string functions

strcpy(str3, str1); //Moves str1 to str3
strcat(str3, str2); //Adds str2 to the end of str3
if (strcmp(str1, str3) == 0)//If these are equal

Fortunately C has a way for simplifing this process of processing and comparing strings. Sprintf works just like printf but sends the data to a buffer (the string).

sprintf(str1, "I am a %s and my spouse is a %s", str2, str3);
//str1 becomes "I am a dad and my spouse is a mom"

Sprintf simplifies most string operations. These operations are the reason why the strings were declared with more characters than they really needed, since in this case, str1 grew to be much larger. The size of str1 needs to be big enough to hold the output from sprintf.

With all this work one can see why most programmers in C++ choose to use a string class which allows operations like the first ones listed. The C++ string class helps to prevent buffer overruns and allows high-level operations more easily.

#include <iostream> //for cout
#include <string> //for string class
using namespace std;

int main() {
  string x = "Hello, ";
  string y = "World!";
  string s = x + y; //this is allowed, unlike for char* and char arrays
  cout << s << endl;
  if ( s == "Hello, World!" ) //this also works with C++ strings
    cout << "comparison succeeds" << endl;
  return 0;
}

It is possible to construct C++ strings similar to how cout works -- this invovles using an ostringstream object:

#include <iostream> //for cout
#include <string> //for string class
#include <sstream> //for ostringstream
using namespace std;

int main() {
  ostringstream temp;
  //construct like you might with cout
  temp << "Hello, World!  15 + 20 = " << (15 + 20) << endl;
  string s = temp.str(); //this gets the string constructed
  cout << s << endl;
  return 0;
}

This code is somewhat advanced for this part of the tutorial, so if you do not understand it at this time, don't worry until to read the object-oriented programming tutorial, but you can use the above code as a template to construct C++ strings.