Monday 4 April 2011

Exam Cheatsheet

So my exam for Computer Programming II is this Thursday, and having looked at the course outline my prof made for us, it clearly states that we are allowed to bring in "...one page during the exam time to assist you in memorizing some syntactic matters." So basically this means that we can bring in a page full of examples of everything we learned this semester. Hopefully nobody reminds her about this and makes her change her mind... She's pretty cool though, so I'm sure if we all show up with them, she'll be cool with it. 


Anyway, I decided to share mine with everyone here! Feel free to use it as a reference, or even as study help for your own class!


Download Link 1


Calling by reference:

int x=0;

int *ptr;
ptr=&x;           //ptr now points to x

void function(int *y)
{
       *y++;   //y points to x
}

int arr[5];
arr[3]; //same as *(arr+3)

pointer to function:
double (*fp)(double,double);

fp=pow; //fp now acts like pow

Useful String Functions:
int atoi( const char *nPtr )
char *gets( char *s );
char *strcpy( char *s1, const char *s2 )
char *strcat( char *s1, const char *s2 )
char *strstr( const char *s1, const char *s2 );

Structs:
typedef struct dummyname
{
       int x;
       //elements
}StructName;

StructName identifier;

indentifier.element=value;

Dynamic Memory:
ptr = (int*)malloc(5*sizeof(int));

Linked Lists:
typedef struct node
{
       char data;
       struct node *next;
}Node;

Node *p;
p=(Node*)malloc(sizeof(Node));
p->data=’a’;
p->next=head;
head=p;

Enum:
typedef enum dummyname
{
       sun,mon,tues...
}Weekday;
(sun=0,mon=1,....)

force values:
enum{sun=5,mon=8,...};


Union:
As large as its largest element.
Holds one at a time.
Declare like a struct.

Preprocessor:
#define SQUARE(x) ((x)*(x))
#undef
#if, #ifdef, #else, #endif

#define TOKCAT(x,y) x ## y

Variable Length Args:
int funct(int n,...)
{
       va_list args;
       va_start(args,n);//n is first param
loop()      variable=va_arg(args,type);
       va_end(args);
}

Command Line Args:
int main(int argc,char *argv[])

iostream:
using namespace std;
cout<<”stuff”;
cin>>variables;

Default Args:
int func(int x=1);

Templates:
template <class T>
T square(T value)
{
       return value*value;
}

int x=square(5);
float y=square(5);

Classes:
Class ClassName
{
public:
void func();
       const int x;
private:
      
       void inlineFunct(){return 0;};
       //private ones
};

void ClassName::funct()
{}

//constuctor
ClassName::ClassName()
{/*default values*/}

//destructor
ClassName::~ClassName(){}
Data Initializer:
ClassName::ClassName()
       :x(0)
{/*default values*/}
Composition:
Class1::Class1(Class2 &identifier)
{}

Friend Functions:
class ClassName
{
       friend void func();
public:
private:
}

void func(ClassName name)
{
       //access private stuff
}

new and delete:
int ptr = new int(3.141592654);
int arr = new int[10];
delete []arr;

Static Class Members:
ClassName::var
InstanceName.var

ClassName::ClassName()
{
       var++;
}

Operator Overloading:
class ClassName
{
friend ostream& operator<<( ostream&, const ClassName&);

ClassName& ClassName::operator=(const ClassName x)
{
       var1=x.var1;
return *this;
}

ostream& operator<<(ostream &o, const ClassName x)
{
       o<<x.var1<<etc;
return o;
}

Sunday 3 April 2011

The Basics of Pointers - Part 1

Now, we've learned to deal with variables. In most programming languages, you'll be able to deal with "references" to variables (more of why we would want to do this in the next post), such a thing in C is called a pointer. Let's just jump right into the code, shall we?

int x;
int *ptr;

Here, we are declaring an integer called x, and after that, we declared what is called "a pointer to integer". A pointer is declared by specifying the type, and then putting an asterisk before the desired identifier. Note that both of the following are correct syntax which do the exact same thing.

int *ptr1;
int* ptr2;

It doesn't matter is the asterisk goes before or after the space.

Last time, we learned about memory addresses. Basically, a pointer can be thought of as a variable which holds a memory address of a specific type of variable. Remember how we used "&" to access the memory location of a variable? Well here's where it comes into play. Let's say we have:

int x=5;
int *ptr;
ptr = &x;

This would make ptr point to x. In a way, this means that we can indirectly access the content of x. To do this, we put an asterisk in front of the pointer's identifier. For example, using the code above...

printf("%d",*ptr);


Result: 5

In the same way, we can modify the content of x by using the pointer.

*ptr = 42;
printf("%d",x);

Result: 42

By putting the star in front of your pointer's identifier, it is like saying: "The content of..."

Note that in order for a pointer to work properly, it must be declared properly as well. By this, I mean that you cannot reference a float from a pointer to integer. This:

float y;
int *ptr3;
ptr3 = y;

will cause a compilation error. Why?

When you declare variables, bytes of memory are taken up. The amount of bytes is determined by what type of variable it is. An integer will typically take up 4 bytes, while a floating point number will take up 8. This means that when we have a pointer to integer, the pointer is expecting a memory address such that 4 bytes after it are taken up. In this example, it sees that it would need 8 bytes, that is, a pointer to integer would only hold half the data, and would be full after "filling up" half way. The compiler sees that this is a problem, and reports and error.

So we know about using pointers now. Great. So why would we ever want to do this?
Stay tuned.

Thursday 31 March 2011

Memory Addresses

When you declare a variable of any type, memory is taken up. Each variable then has what is called a "memory address" which is an indication of where it is stored in memory. The memory address of any variable is indicated in hexadecimal (or honestly, some other number base, it may be octal, but that's not really important for now). Accessing the memory address of any variable is easy.

int x;

&x  //is the memory address of x

So you may be asking yourself why you would ever need to know things like this.
WELL
A simple application in which you're basically required to use memory addresses is the use of  scanf().
scanf() can be thought of doing the opposite of printf(). Instead of outputting information to the user, it takes information from the user and stored it in variables. Here's how we would ask the user to store a value for an integer x;

int x;
printf("Input a value for x: ");
scanf("%d",&x);


Notice how the format string for scanf() is exactly the same as printf(). The main difference here is that the second parameter is asking "where do you want to store this value". The obvious answer is "in x," but really, you're going to want to be storing it in the space that x is occupying in memory - its memory address. Also notice how we cannot print to the screen using scanf. In order to let the user know what he is supposed to input, we must use printf() to print instructions as the program executes.

Monday 28 March 2011

Nested Loops

Just a quick post today on nested loops.

The basic concept is that you will have one (or more) loop inside of another loop. Each internal loop will run and terminate, and then any external loops will then run. Here's an example:

for(int i=0;i<5;i++)
{
    printf("i = %d\n",i);
    for(int j=0;j<5;j++)
    {
        printf("j = %d\n",j);
    }
}


The output would be:

i = 0
j = 0
j = 1
j = 2
j = 3
j = 4
i =1
j = 0
j = 1
j = 2
j = 3
j = 4
i =2
j = 0
j = 1
j = 2
j = 3
j = 4
i =3
j = 0
j = 1
j = 2
j = 3
j = 4
i =4
j = 0
j = 1
j = 2
j = 3
j = 4

So you see that it is really much like a normal loop. Each time a loop runs, it must execute all the code contained within its scope before looping again - even if it contains another loop.

This is just a quick basic concept that should be understood. This is very useful when dealing with multi-dimensional arrays (matrices), but I'll come to that in another lesson.

Sorry for the short post! I need to get back to studying for exams.

Friday 25 March 2011

Loops

Loops are useful for running one or more lines of code repeatedly. The basis of how a loop works is similar to an if statement: There is a condition, and if the condition fails, the loop stops. The first loop I'll show you is a called a while loop, here's its syntax:

while(condition)
{
    //code
}

Pretty simple. Let's see this in an example

int i=0;
while(i<10)
{
    printf("%d\n",i);
    i++;
}

(For those who don't know, i++ is the same as saying i=i+1 or i+=1. It means "increment i")
This will print out the numbers 0 to 9.
Basically we start by initializing an integer to 0. We tell our while loop "Loop the code while the value of i is less than 10". In the first pass, the condition passes the test because 0<10. Good! So we go ahead and call our printf function. Here's the important part: we increment i by 1. So now the value of i is equal to 1 and we return to the beginning of the while loop and run the condition again. Now we're asking "Is 1 less than 10?" Yes it is. We run the loop again. printf, increment, loop again: "Is 2 less than 10" Yes....you get the idea.
Let's look at the last pass through the loop, when i is equal to 9. "Is 9 less than 10?" Yes, so go into the loop, call printf and increment i. Now we go back to the top yet again, but this time we ask "Is 10 less than 10?"
The answer of course is NO, so we skip the loop entirely, just as we would if a condition in an if statement failed.

This is a simple use for a while loop, and in fact, while loops using a simple incrementing variable can be rewritten as another type of loop: a for loop. The syntax is a little more complicated, but in the end, for loops generally end up being easier to manage.

for(initial state;terminating condition;increment)
{
    //code goes here
}

Let's look back at our while loop example for a sec. See how we declared an integer i before the loop? That's our initial state. We then had a condition in the while loop. That of course is the terminating condition. At the end of the while loop, we increased the value of i. That's our increment.

Here's the same loop above rewritten as a for loop:

for(int i=0;i<10;i++)
{
    printf("%d\n",i);
}

Both loops essentially do the exact same thing. The real difference for you is that in a for loop, all the useful loop information is stored in the parentheses after the word "for".
Note that in the for loop, I declared my incrementing variable inside the parentheses. This is a matter of preference, but I do it whenever possible. Basically, I'm saying that the following is still correct:


int i;
for(i=0;i<10;i++)
{
    printf("%d\n",i);
}


While this is still correct, I find it very beneficial to declare your incrementing variable inside your loop. This way, the variable "dies" after the loop ends. This means that you can reuse that variable name for other loops and you don't have to worry about this loose variable floating around your program. This means that I could do this:


for(int i=0;i<200;i++)
{
    //run some code
}

for(int i=0;i<42;i++)
{
    //run some different code
}

And I won't have to worry about which variable I used before. Again, it really is a matter of preference. I showed you mine.

When writing loops, you'll likely accidentally code an infinite loop at some point. For example, take a look at this:

int x=5;
int y=2;
while(x==5)
{
    printf("...");
    y++;
}

With a quick look at the code, you'll see that our condition is always true! This means that the loop will never end. Likewise, the following will be an infinite loop.

while(1)
{
    //code
}

Thinking back to our logical operators, a logical statement return a value of 1 if true or 0 if false. Thus, our condition is interpreted as "While 'a true statement', run this code." No wonder it will loop forever!

It is also important to check your for loops for infinite loops, since for loops especially are usually not meant to be infinite.

for(int i=0;i>-1;i++)
{
}

will be an infinite loop since we are looping as long as i is greater than -1 and each time the loop runs, i is incremented. An infinite for loop can also be forced by writing:

for( ; ; )
{
}

No initial state, no terminating condition, no increment. The loop has noting to worry about and will go on forever.

Next time, I'll talk about nested loops

Wednesday 23 March 2011

More conditions

So yesterday, we looked at if statements and how to use them with simple conditions. To make our conditions more complicated, we need to make use of more of the logical operators. I'll give a real life example:

"It is sunny and I am not indoors."

A pretty simple statement. Not thinking about coding right now, let's let:
p = It is sunny
q = I am indoors

If we wanted to write this as a condition for an if statement, we would have:

p && !q

Pretty simple, right? Now let's look at the statement:

"It is sunny or cloudy, but not raining."

An important note about logic: BUT has the same logical meaning as AND. So we have:

"It is sunny or cloudy, and not raining."

Now, an important point about how this statement is interpreted. Do you remember BEDMAS, the order of operations when doing arithmetic? This states that certain operators must be evaluated before others (the order is: brackets, exponents, division/multiplication, addition/subtraction). Well logical operators also possess a precedence factor as you'll see. Let's look at our statement again. It states that it is sunny or  cloudy, but not raining. At first glance, it may seem at though the condition first checks to see whether it is sunny or cloudy, and then checks to see if it is raining. i.e. this:

(sunny or cloudy) and raining

In fact, when dealing with logic, I like to think of AND as a multiplication symbol and OR as addition (there's a discrete mathematical property that actually says this, but I won't get into that). In other words, AND will precede OR when dealing with operations, so our original statement actually means this:

sunny or (cloudy and raining)

See how it completely changes the sense of our condition? It's like comparing:

(5 * 5) + 10 = 250
and
5 * (5 + 10) = 75

Just a note to be careful when coding.
Great, now that that's out of the way, you are legally entitled to see some code.

Let's say we are writing a program in which we are asking the user for a time in hours and minutes. Obviously, we don't want to deal with hours greater than the number of hours in a day or minutes greater than 60, so a common fix is to set a default value if the user enters invalid data. We'll work from hours 0 to 23

int hour,min;
//prompt user for data
if(hour<0 || hour>23)
{
    hour=1;
}
if(min<1 || min>60)
{
    min=0;
}

Notice how we cannot use mathematical notation like: 0<hour<23. Instead, we must explicitly show each condition we want to include.

I hope this has been useful!

Next time, I'll talk about loops.

Tuesday 22 March 2011

Boolean logic and if statements

Without the need to make "decisions", your program will just be a linear stream of code that always outputs the same type of data. To check conditions, we use the if statement.

Before even talking about the statement itself, it is necessary to cover certain aspects of boolean logic. There are certain operators that you must know when dealing with logic.

Greater than >
Less than <
Negation !
Equality check ==
Inequality check !=
Greater than or equal to >=
Less than of equal to <=
And &&
Or ||

Standard parentheses will also come in handy when dealing with large conditions.

This seems like an eyesore right now, but I'm sure you'll soon find this natural. The basic structure of the if statement is as follows:

if(condition)
{
    //result
}

Seems pretty simple, right?
Let's say I have some integer x, and I want to print a line of text only if the value of x is currently greater than 5. We would have:

if(x>5)
{
    printf("This will get printed!!");
}

Easy!
Likewise, if we wanted to check if it was strictly equal to 5:

if(x==5)
{
    printf("It is equal to 5!");
}

The basic idea behind this boolean logic is that if the statement contained within the parentheses is true, then the condition returns a value of 1. If false, a value of 0 is returned.
This is very important, as new programmers often make a silly mistake, I will show you:

//This is a very common programming mistake
if(x=5)
{
    printf("What's wrong here?");
}

Can you see the difference? Rather than using the comparison operator, I used the assignment operator! Here, we are actually assigning a value to x, not comparing one! Although it is just a one character difference, it completely changes the meaning of the statement. Instead of having the condition return true or false (1 or 0), the condition is returning the assigned value of x, 5! The if statement also interprets this as a "true" value. In other words, no matter what the value of x was before the if statement ran, it will now be 5 when it does run, and hence, it will always return true, defeating the purpose of writing the statement altogether!

The beauty of if statements is that they don't simply end if your condition is false. There's also the option of passing the flow of control to an "else" which runs if the first condition is not true. For example:

if(8<5)
{
    //this will always be false
}
else
{
    //run some code!
}

This way, you can use the else as a "default" execution.
But wait, there's more! You can combine ifs and elses to create a string of conditions

if(condition)
{
}
else if(another condition)
{
}
else if(yet another condition)
{
}
...this can go on for a while
else
{
}

Notice how each consecutive else if will be run if the previous condition is not true. And that in this case, if none of them are true, then the else block will run. Note that it is not necessary to terminate with an else block. Hope this has been useful! Next time, I'll talk more about logic and how to create more complex conditions.