Heroes of Might and Magic Community
visiting hero! Register | Today's Posts | Games | Search! | FAQ/Rules | AvatarList | MemberList | Profile


Age of Heroes Headlines:  
5 Oct 2016: Heroes VII development comes to an end.. - read more
6 Aug 2016: Troubled Heroes VII Expansion Release - read more
26 Apr 2016: Heroes VII XPack - Trial by Fire - Coming out in June! - read more
17 Apr 2016: Global Alternative Creatures MOD for H7 after 1.8 Patch! - read more
7 Mar 2016: Romero launches a Piano Sonata Album Kickstarter! - read more
19 Feb 2016: Heroes 5.5 RC6, Heroes VII patch 1.7 are out! - read more
13 Jan 2016: Horn of the Abyss 1.4 Available for Download! - read more
17 Dec 2015: Heroes 5.5 update, 1.6 out for H7 - read more
23 Nov 2015: H7 1.4 & 1.5 patches Released - read more
31 Oct 2015: First H7 patches are out, End of DoC development - read more
5 Oct 2016: Heroes VII development comes to an end.. - read more
[X] Remove Ads
LOGIN:     Username:     Password:         [ Register ]
HOMM1: info forum | HOMM2: info forum | HOMM3: info mods forum | HOMM4: info CTG forum | HOMM5: info mods forum | MMH6: wiki forum | MMH7: wiki forum
Heroes Community > Other Side of the Monitor > Thread: Introduction to Programming ( with C )
Thread: Introduction to Programming ( with C ) This thread is 2 pages long: 1 2 · «PREV
dimis
dimis


Responsible
Supreme Hero
Digitally signed by FoG
posted November 23, 2006 12:49 AM
Edited by dimis at 15:27, 02 Dec 2006.

Conditions [aka Expressions]

Logic is everywhere. Widespread in everything that falls under the term science, as well as everyday life. For example, what makes you carry an umbrella when you leave home? You have to think something like if it rains then I 'll take an umbrella. Similarly, you can read in a math-textbook if a divides the product of p and q then a divides p or a divides q. Examples are endless. Anyway, what I am trying to say is, that making thoughts like that allows us to judge things, make progress, etc. As a result, it should be natural to include this kind of mechanism when we are giving instructions to a computer. This mechanism is going to be the subject of my next post.

Truth Tables
However, for future reference it would be nice if we had some background from math. What we really need is basic facts from propositional logic (don't let my reference scare you, you only need the 1st paragraph!), more particularly Truth Tables. The reason is that not all of our thoughts are "monolithic" as on the examples above. We tend to combine things, like "if I finish my project by Friday and the meteorologists forecast good weather for the weekend, then I 'll have a mini-trip this week!" But what meaning do we give when we say words (the connectives on the link above) like or, and, etc?
The answer to this question comes from logic, and I present on the following the, so-called, Truth-Tables, for the most common connectives:
* The simplest one is the negation which we usually describe with the word not. The meaning is:

In C (generally) this is declared with an exclamation mark '!'.

* Other, every-day life connectives are or and and. Their corresponding Truth-Table is presented below. Note that I also include a column for the connective xor. xor means that something is true if either of the propositions is true but not both! Pinpoint the difference in the final line between or and xor.

Now, let's see the symbols for these in C.
or '||' [two vertical lines]
and '&&' [two ampersands]
xor No equivalent - at least I am not aware of. But then, why did I place the Truth Table above? Well, practically, because we'll refer to these tables in the future when we want to manipulate bits. The point is, that sometimes we don't want to simply use connectives and check for the truth of some statements; we also want to perform some action. But all these will become apparent when we reach the discussion on bit manipulation (which is way ahead). If xor had to have an equivalent just like the ones above, then it should have been '^^'. Anyway, in case you want to use xor you can always use the tautology:
a xor b <--> (a or b) and (not (a and b) ). But this is getting rather confusing, so let's just forget xor for now.

Parentheses
I haven't said anything so far regarding the precedence (priority) of operators. I'll do so soon on a subsequent post. In the meanwhile you can use parentheses just to be sure that things are going to operate just like you want.

Symbols in C
Finally, for completeness, let's see some equivalences between (math) symbols and their C counterparts:

Note, that when we want to check for equality, we have to write down two 'equal' symbols (i.e. '=='). Soon, we are going to implement something like if a equals b then do this, otherwise do something else. But, pinpoint the problem: If we wrote down on code
Quote:
a = b
then, this would result in making a equal to b, because according to our (partly implied) earlier notation a command such as
Quote:
a = b;
implies that we want to set variable a equal to whatever is stored inside variable b. And this is not what we want this time!

Truth Values in C
C treats as true any (binary) non-zero (numeric) value, while false is (binary) zero (0). This will be apparent to its completeness in a post relating number representation; however, you are absolutely correct if you think that all values are decimal (the usual system humans use) as long as you have in mind numeric variables; i.e. 0 is number zero and not a typing character!

Fill me for an example.
____________
The empty set

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
pandora
pandora


Honorable
Legendary Hero
The Chosen One
posted November 23, 2006 04:06 AM

{filler}

 Send Instant Message | Send E-Mail | View Profile | PP | Quote Reply | Link
dimis
dimis


Responsible
Supreme Hero
Digitally signed by FoG
posted November 25, 2006 03:06 PM
Edited by dimis at 01:13, 26 Nov 2006.

Branching

Note: This is going to be another long post. Please be patient till it is complete. However, I 'll try to post "stuff" as long as certain concepts are more-or-less covered in a good extent.

There are two main techniques on branching. One invloves if (...) then ... else .. and the other one is by speculating distinct cases.

IF ( condition[s] ) THEN ... ELSE ...
Introduction
As it has been described earlier, there are cases where we want to do "stuff" based on the validity of some conditions. Let's have a look on the following code, which solves linear equations:

As you can see, in C, the word then is not used (contrary to other programming languages). Whatever you want to be executed is simply placed between curly brackets '{', '}' just like source code inside main() function. For clarity in programs, we tend to indent commands inside ifs or elses. This is usually referred to as block programming because of the intuitive structure the source code has. Moreover, there are cases where you might not want/need an else in your source code. That is perfectly fine. You simply don't have to write else { ... commands ... }. A simple if works perfectly alright on its own.

Nesting
However, you might also want to distinguish cases even more inside the block of an if or an else. For this reason make a duplicate of the above source code and edit this new file on the following lines:

Note that this time we want to distinguish cases between the values that variable b has. In case b is zero (again note that equality check requires two equality characters (=) consecutively - condition @ line 29) then every x can be a solution, since 0*x + 0 = 0 always holds. On the other hand (b is not equal to 0), there is no x that can be a solution of the given equation. Moreover, note that in this latter case curly brackets were not used since what is to be done is described by a single command (line 34).

Compact Nesting
There are many real-world problems that require us to nest if-else blocks inside elses in a manner similar to the following (previous example as well):

But this time, the block programming technique tends to make it a little difficult to realize what is going on. For this reason, we are allowed to use a simple variation, namely else if, as shown in the code below (again, I place code after line 24 since there are no changes earlier):


Combining Conditions
As it has been said earlier we can combine various conditions with the connectives described on the above post. Let's see an example code that generates an executable with exactly the same behaviour as above, but this time is written in a different manner. More specifically, let's change code after critical line 24:

where @ lines 24 and 28 I combined two conditions (similarly you can combine more conditions) with the connective and which is declared by && as it has been already discussed.

Write some simple practice programs to be certain you have the skills described above. As an example, write a program that asks for 3-4 numbers (integers, floating point, you decide ...) and finds out which number is the smallest and which one is the largest. Post below if you have troubles.
____________
The empty set

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
lord_crusader
lord_crusader


Promising
Supreme Hero
UHU!! supreme!
posted November 26, 2006 12:34 AM

hey I love C... specially the graphic mode I remember in school trying to make video games in it with oriented object programming nice work keep them comming!
____________
Dig Out Your Soul

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
dimis
dimis


Responsible
Supreme Hero
Digitally signed by FoG
posted December 02, 2006 08:07 PM
Edited by dimis at 20:39, 02 Dec 2006.

Assignment Conventions

Before we procceed, it is important to describe some conventions when we assign new values to variables. So far, we 've seen programs, where we assign a value to a variable and never change it till the completion of the program. As you might have already guessed, we can assign new values to previously used variables during the execution of the program.

For simplicity assume we want to print on screen values 1, 13, 25; i.e. print 1, add 12, print result, add 12, print result. An obvious solution would be the following (among others):

Of course the problem is so simple that you could have solved it with three simple printf commands. I know. But let's say you want to use a variable for this purpose.

The first point is that when you play with variables, you don't need always some temporary space to perform computation. In the above example I used variable temp so that it would store the running value of variable result and as a consequence this could help me compute the new value of the sequence. However, this is a very common situation in programming. For ease of use, efficiency in time and memory used by your program, you are perfectly allowed to assign a new value to one of your variables based on the value this variable has before the command is executed. Ok, this sounds complex, but is trivial really. You are allowed to use assignments of the form:
Quote:
a = a + b;
which will make variable a have as new value the sum of values of a and b. As a result, the above program can be rewritten in the following way (note that b in the following case can be a constant - number 12):

The above convention (NewValue = OldValue + Something) is used throughout all procedural languages, like C as well as when describing algorithms in pseudocode;

Generalizations
Obviously, you can generalize the above pattern for other operators as well; i.e. you can use more than a plain '+' (plus). Hence the following assignments are perfectly valid:
Quote:
a = a - b;
a = a * b;
a = a / b;
a = a % b;

where the operator % returns the remainder r of the division a / b; i.e. r is a number so that the following holds: a = k*b + r, for some integer k. In other words, % is the modulo operator.


Further C conventions
However, specifically in C we have some further conventions. After all, the above patterns arise very frequently in programming. Hence you can omit the reference on the updated variable on the right hand side of the assignments. As a result, you are allowed to write statements (commands) similar to those:
Quote:
a += b;
a -= b;
a *= b;
a /= b;
a %= b;

Hence the above program can be re-written as follows:


Incrementing / Decrementing by 1
Finally, a very common operation is adding (substracting) (not multiplying, dividing, ...) just 1 to a variable. For this reason, the following conventions can be used:
* Instead of a += 1; you can write a++; or ++a;.
* Similarly, instead of writing a -= 1; you can write a--; or --a;.
Of course, you might be wondering why there are two conventions that make a command simpler. The point is that their effect is not exactly the same!
Ok, let's clear this thing up, once and for all.
a++; and ++a; are equivalent of a = a + 1; when you use them as a single command.
However, when you are also using the variable for another purpose (e.g. in an if-then-else structure), then a++; implies to first use the running value of variable a and then increment by 1; while ++a; means first increment by 1 and then use the value of variable a. Have a look on the following code and output to realize what I mean:

Recall that C understands as true any non-zero value and as false number 0. Hence, you can observe that we never entered the first if since nothing is printed, while we entered the second time in the if structure.

One final note on syntax: So far, I haven't specifically described that you can use commands inside expressions (conditions). However, you can do so as the above program suggests. NOTE, that we do not write ; to indicate the end of a command in these cases.

Comments, questions, ideas, random thoughts ... please feel free to post below! Most likely I have left some ambiguity on what I describe above.
____________
The empty set

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
dimis
dimis


Responsible
Supreme Hero
Digitally signed by FoG
posted December 02, 2006 09:28 PM
Edited by dimis at 04:08, 09 Dec 2006.

Loops [aka Repetitions, Iterations]

Many times we want to do things in a repetitive manner. I believe that everyone has faced at least once in his/her lifetime the "problem" of writing down consecutive numbers. Let's have a closer look on this problem. What you need to know (assuming you know how to add two numbers!) is the starting integer and the finishing integer of the numbers you want to write. For simplicity, let's assume we want to write down numbers 1, 2, ..., 10 separated by a blank. How do we actually do that without ambiguity? Obviously, our criterion ( condition ) is number 10. In other words,
Quote:
while we haven't written down 10 , we will write down the integer we have in mind at the moment and we will get ready to write down the next integer.

which also assumes that we were ready to write down the first integer at the beginning; i.e. 1!

while ( condition[s] ) { ... }
Introduction
Let's see a working example of the problem of writing down 10 numbers in a row starting out from number 1:

There are three main points in the above example that are similar in most cases when you use a while loop. These are shown as comments on the following (pseudocode):

First of all, you have to get ready before you enter the while loop. In the example regarding numbers, this was done in line 7, where we initialized variable counter to 1.
On the second phase, commands between '{' and '}' in lines 9 and 12 respectively are executed as long as the condition holds; i.e. is TRUE. Hence we do what we really want to do (line 10 --> print current number on screen) and finally at line 11 we influence the condition that while checks by incrementing variable counter.



continue
Sometimes however, we want to skip some parts. For example, suppose we want to print on screen numbers 1, 2, ... 10 but this time we want to exclude all those numbers that are multiples of 3. For this reason, we can use the directive continue which forces the computer to go directly at the top of the while loop, i.e. checking the validity of condition[s]. Let's see the example:

Compile and run the above program.
I have a question on comment at line 11 above. Can you answer it?
(you can always remove the line I pose in question, recompile program and re-run )



break
On the other hand, some other times we want to check for a special exception that is not covered in the condition that is being checked on the while loop. Whenever we use the break; command we force the execution of the program to leave the while loop. For demonstration purposes, I've changed slightly the previous example with the following code:

As you can see at line 9 the condition that is being checked is 1 which is equivalent to TRUE. In other words, this condition will never turn into FALSE so that while loop stops executing. For this reason, another check is being made at line 11 which implies that at the first time variable counter has value 10, then break command (directive) will be executed. Whenever a break command is executed, it forces the computer to get out of the while (...) loop. Hence in this example break command forces the execution to transfer exactly after the '}' which is the end of the while (...) loop.
In other words, in case you have a nested while (...) loop, break will only direct the processor to leave the loop where it appears; and not the outer loop as well. If you want to leave the outer loop as well, you'll have to use again the command break on that loop as well. If this seems unclear for now, don't worry. It will become aparent as we'll start making some programs (and we are not that far from generating some interesting ones); so keep on reading and have in mind that there is a remark on break on a future problem you are going to face.
Finally, and this is a difficult question for beginners I guess, the program above (with break usage) does not behave exactly as the first one that solved the problem of printing numbers 1, 2, ... , 10. Can you pinpoint what's the difference? (yes, I am insane!)



Infinite Loops
Let's create on purpose our first buggy program. We are all humans after all and sometimes things slip out of our minds as we write code. Luckily, this sort of problem is rather easy to overcome. Write a copy of the following code:

Compile and execute. If you want to stop the execution of your program you must type Ctrl + c which is the signal on keyboard to kill your application (just like task manager has an option to terminate a program). As you can realize we tend to avoid situations like these.



do ... while ( condition[s] );
A similar control structure that allows us to do things repetitively is the do ... while ( condition[s] ); structure. Note on syntax, that in this case, a ; is needed at the end of the parenthesis after while ( condition[s] ). The difference with the previous case (while () loop) is, that this time the commands we place inside the do { ... } while (...); structure are executed at least once! Just keep that in mind because there are cases where you might not want these commands to be executed even once. But again, you 'll become more familiar with this as time goes by and you earn experience from your programs. Our initial problem of writing down numbers 1, 2, ... , 10 separated by a blank can be solved with the following code:




for ( initializer; condition[s]; influence) { ... }
We have finaly reached my favourite repetition structure. Recall the intuitionistic pseudocode that was given right after the first while program. There are three major points (apart from the commands that are executed each time in loop):
(1) the initializing phase just before we enter the while loop,
(2) the condition[s] that is (are) being checked on each loop,
(3) and finally a command that influences the condition and will eventually turn it into FALSE (0) so that we leave the loop.
These three notions are captured in the header of this paragraph. A sample program that would use a for (...;...;...) loop in order to print numbers 1, 2, 3, ... , 10 separated by a blank, is the following:

Note that these 3 basic ingredients of a repetition loop are all neatly put into a line separated by a ; Note also (syntax) that we do NOT place extra ; at the end of various commands, i.e. we don't write something like:

This is a syntax error and the compiler will indicate it.



continue, break
The usage and remarks about continue and break that were made on while section of this post, hold on do { ... } while (...); and for (...;...;...) {...} repetition structures as well.



I guess this is all about repetition structures and a very basic knowledge of C. We can now start facing some interesting problems.
____________
The empty set

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Lith-Maethor
Lith-Maethor


Honorable
Legendary Hero
paid in Coin and Cleavage
posted December 08, 2006 02:03 AM

filler

go ahead my friend
____________
You are suffering from delusions of adequacy.

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
dimis
dimis


Responsible
Supreme Hero
Digitally signed by FoG
posted December 09, 2006 04:41 AM
Edited by dimis at 16:42, 12 Dec 2006.

Let's get more interactive!

The more you experience the better programming skills you are going to have. So let's start facing some problems.

Problem 1
Write a program that initially asks from the user an integer. Say this number is N. Then, the program asks from the user to input N integers and at the end of the execution it prints the maximum number it read. If N is less than or equal to zero (0), the program should not ask for any number. Sample execution is shown below:


I will not go further until this problem is solved.
Ofcourse, any questions regarding things that have been described earlier are more than welcome.
Have fun and post solutions below.

Hint: Some times we have to initialize more than 1 variables before we enter a loop. (added Dec 12, 2006)
____________
The empty set

 Send Instant Message | Send E-Mail | View Profile | Quote Reply | Link
Jump To: « Prev Thread . . . Next Thread » This thread is 2 pages long: 1 2 · «PREV
Post New Poll    Post New Topic    Post New Reply

Page compiled in 0.1050 seconds