Red - 19 Jan. 2004 - 07:54:

C plus plus

Hey grigri and any other c++ coders out there. I'm brushing up on mine, and I figured the dos thread might be a way that would work for me too. I need to start with the basics, I think. I never quite under stood what I should include when I was coding basic apps. Last class I took was all dos based, and that's the complier I have now, but I have access to a visual c++ one at school and through friends. I've got a copy or the GNU C++ on hand. Maybe we could start with a word on compliers?

To give you an idea of what I (but not nesseccerally what others who jump in will) know, he's a lil list.
- Basic logic: if, loops, nesting
- varibale types
- cin & cout (rusty on the fine points)
- commenting
- most of the syntaxt on those
- familiar with arrays and sorting
- only know concepts of pointers, objects, and functions
- basics of debuging
- only ever coded apps that ran in the dos box

That should be most of it. I'm probably fuzzy on my syntax, and often had a lot of syntax errors, so tips on that are welcome. I should be able to pick up syntaxt from examples. After we've chosen a compiler (or two maybe?), then naturally a few toy apps are good to start off with, but I'm hear to learn, so conduct as you see fit. Things don't have to be super structured like in a class room either. Eventually I'll make a list of apps I'ld like to code to give myself some goals and dirrection. We'll see how it goes. 8)
 
19 Jan. 2004 - 09:34 craeonics
I've done various C++ tutorials, but I've never really coded anything. Trouble with most tutorials is that they extensivley iterate over all the basics I already know (loops, variables) and then it stops.

I'm far more interested in making actual Win32 apps than console things, but I always find myself lost in a maze of functions. Plus, sixty lines to create a window, of which half consists of deprecated calls no-one knows what they were for but have to be included for compatibility reasons, never sounds too appealing to me.

Compiler I always used was Bloodshed Dev C++, which is a frondend for gcc (and is free). It worked for me, but then again, I only used it for tutorials.
 
19 Jan. 2004 - 09:52 grigri
okie-dokie, good job :)

Compilers. I personally use Visual C++ 6.0, I've never used any other compiler for windows-based apps. Back at school we used the gnu compiler (I think), but only for DOS apps, and even then I did my homework on Visual C++. So that's more or less the only one I'm capable of talking about - not that it really matters I suppose.

I'm warning you and anyone else that the transition from DOS programming to windows programming is not easy at all. There are a lot of new things to get to grips with, such as messaging and window structure, which are essential to any windows program, which have to be learned from scratch. That doesn't mean it can't be done, of course it can! It's just a big jump.

So I'll start by covering "standard" c++, that is DOS-based. These techniques will of course be used in windows apps too.

The first, most important part of c++ to understand is the scope and the stack. A scope is delimited by curly braces { like this }. Any variable declared and allocated in a scope will be freed when that scope is exited. It doesn't matter whether the scope is a class, a function, a for loop, an if... or even an unnamed scope. Therefore this:

void SomeFunction()
{
int a = 1;
if (a==1)
{
int b=2;
}
else
{
b=4;
}
cout << b;
}

Will not work, because b is not defined when we try to access it.

Bear in mind that whenever you create a variable inside a scope, that variable will override any other of the same name from a different scope, until the scope is exited. Example:

int a = 4;
{ // Unnamed scope
int a = 6;
}
cout << a;

This will print 4... a is only 6 within the unnamed scope. Actually that sounds misleading - it's better to say that the letter "a" does not mean the same thing inside and outside that inner scope. In this case they are both ints, but this would be exactly the same:

int a = 4;
{ // Unnamed scope
float a = 3.1415927;
}
cout << a;


Ok, that handles scopes. A quick word on comments. There are 2 types of comment in c++ - single-line comments and free comments. Single-line comments are like the example above: you put a double-slash ("//") and everything on the rest of the line is a comment. Free comments are much more flexible. They start with "/*" (slash-star) and end with "*/" (star-slash). Everything in between these markers is a comment, even if it's on several lines. Here's a nasty example I remember from school:

int a = 0;
a += 1; /* Increment by one
a += 2; * Increment by two
a += 3; * Increment by three
a += 4; * Increment by four */

What's a worth at the end of this code? If you're still counting, then you're wrong - a is worth 1, because only the first increment is used, the rest are all comments.
Of course, with syntax colouring in most IDEs now this isn't a problem, but you should still be aware of it :)

A quick word on control structures. Control structures change the flow of program execution. In c++, there's if, switch, for, do...while and while (exceptions also obey this definition, but that's for another time).
"if" is simple. The syntax is : if (test-expression)
The CODE part can be an instruction or a scope. Remember than the test-expression must always be enclosed in parentheses.
You can also use "else" with if. else must logically be the next expression in the same scope as if, and it is used the same way. example:

if (a==3)
{
cout << "Something";
}
else
cout << "Something else";

same as

if (a==3)
cout << "Something";
else
{
cout << "Something else";
}


switch is if's big brother. It allows multiple values to be queried and branches differently for each. switch is a very efficient structure (it usually compiles to a jump table), and is far faster than a series of if/else structures.
example of switch:

switch (x)
{
case 1:
case 3:
case 5:
cout << "x is odd";
break;
case 2:
case 4:
case 6:
cout << "x is even";
break;
default:
cout << "Invalid value for x";
break;
}

A few things to remember : never forget the break statement. In a switch statement, wherever you jump to, flow continues until it is told to stop. You can exit with a break, a return, or other methods but if you don't tell it to stop, it won't.
The "default" branch, isn as you've probably guessed, where execution goes if no specific label for the value is there.
I should also say that the decision variable in switch should always be an integer (int, short, long... any integer). Pointers, variables, floats won't work (although simple chars will, because they really are integers anyway).
Another thing is variable declaration. Lexically, all the "case" fields (branches) are in the same scope, which means that they share the variable namespace. Therefore, this generates an error:

switch (x)
{
case 1:
int y = x * 4;
cout << y;
break;
case 2:
int y = 1+ x * 3;
cout << y;
break;
}

because y is being defined twice within the same scope (remember, I said scoping was important!). The solution is to make a new scope for each branch, like so:
switch (x)
{
case 1:
{
int y = x * 4;
cout << y;
break;
}
case 2:
{
int y = 1+ x * 3;
cout << y;
break;
}
}

Scoping rules will become even more important when you use objects and classes.

Phew, that's long enough for now... even though I haven't covered much. Next time, for/while, arrays and pointers.

Questions, class? (grin). I'm deliberately not presenting this as a lesson, rather as a summary of little bits I've had to learn the hard way. If I've skipped anything, if something is unclear, just say...
 
19 Jan. 2004 - 15:55 fallout
one other control structure that isn't used often but works well in certain cases is ? : it basically goes like this

conditionell ? true-statement : false-statement ;

examples:

int x,y;
cout<<"enter 2 numbers:";
cin>>x>>y;
cout<<"the bigger number entered is "<<( x>y ? x : y);

you can also do things like this with it

//numapples is already initialized
cout<<"You have "<<numapples<<" apple"<<(numapples==1?char(0):'s')<<'.';
 
19 Jan. 2004 - 16:09 grigri
indeed :)

<note pedantic="yes" useful="no">
sorry for being pedantic, but it's not actually a "control structure", it's an operator. In fact it's the only ternary operator in c++, and is known as the "ternary conditional operator".
</note>

Still, it's really useful - I use it all the time. It can make code look a bit more complicated though - they make good use of it at the IOCC :)
 
19 Jan. 2004 - 16:57 craeonics
It makes code damn unreadable, but it's great if you want to do things in tight spots.
 
19 Jan. 2004 - 18:26 fallout
I know it isn't technically a control structure and it should have been able to go without saying that statements using it should usually be commented. However, the conditional operator does tend to produce well optimized code and can work small wonders.

I once used it in a for loop dealing with a pattern matching program I was writing for a class and it ended up saving me from writing 1.5 pages if code. It required quite a bit of comments to reveal what I was doing, but it ran faster than anyone elses in the class.
 
19 Jan. 2004 - 19:32 fallout
On another note one thing that should be being done by everyone is the use of standard template libraries

you shouldn't be including things like iostream.h, string.h, or any other standard header with a .h on the end.

instead you should include iostream, string, etc...
and you should use namespaces.

this means putting the line

using namespace std;

right after your #includes in your main.cpp file

it also means that in every file that doesn't contain your main program you should prefix every statement that uses something from the standard namespace with std:: and you ahouldn't have a using namespace std; at their top. This includes every header file you write.

here are examples using a hello world theme of the 2 ways your main.cpp file should be written
ex 1.

#include <iostream>

using namespace std;

int main(void) {
    cout<<"Hello World\n";
    return -1;
}

ex 2.

#include <iostream>

int main(void) {
    std::cout<<"Hello World\n";
    return -1;
}


One more thing that is a major part of C++ that should be discussed even though it makes no difference on how code works is style/formmatting.

There are 3 common ways that C is formatted(ignoring the whole speal about where to put comments). These come from how the compilers were originally developed.

all the following examples use grigri's somefunction code seen above.
Method 1 "show me the delimeters":
Code is organized with every open brace and close brace on their own line and every one is in the same column that every other one of the same level is. This is the earliest style developed and it looks something like what grigri has above.

void SomeFunction()
{
    int a = 1;
    if (a==1)
    {
        int b=2;
    }
    else
    {
        b=4;
    }
    cout << b;
}

Method 2 "where does it end"
End braces line up with the beginning of the statement that justifies their creation. This method stems from the idea that you don't need an opening brace to say that a new scope should be formed at a point: it should be understood by the code on the preceding line.
ex:

void SomeFunction() {
    int a = 1;
    if (a==1) {
        int b=2;
    } else {
        b=4;
    }
    cout << b;
}

(note: people argue her about where else should be, some say it is an extension of the if and should be placed on same line as the } of the if, others say that it is a statement in it's own right and should be treated as such)

Method 3 "spaces are not free"
Code in this style makes extreme use of indentation, braces are never on their own line. This style was brought to c++ by languages that don't appear to even have delimiters, such as prolog.
ex:

void SomeFunction() {
    int a = 1;
    if (a==1) {
        int b=2; }
    else {
        b=4; }
    cout << b; }


Keep in mind that I didn't say anything about switch statemnts(they are a world of their own, and when I write mine they look similar to method 3, even though the rest of my code looks like method 2)
 
19 Jan. 2004 - 19:47 craeonics
I always found method 2 to be the most aesthetically pleasing, when writing JavaScript or PHP, so I'll probably take that route with C++ as well. To me its not necessarily about writing code that works, but it should also look good. I ain't no designer for nothing.
 
19 Jan. 2004 - 19:55 beaker
I just wanted to raise a point that I trip on the most frequently (since I switch from language to language so often).

if (x=1)
{
// do something here
}
else
{
// do something else here
}

Two problems with this piece of code:
1) x=1 is _assigning_ x the value of one, not evaluating it. x==1 is evaluating it.
2) The if statement will always evaluate to true because in C++ 6.0 anything greater than 0 evaluates to true (it may even be any non-zero number, help me out grigri).

Probably common sense to most of you, but to me (and maybe any of us that learned on VB), I find myself falling into this trap and scratching my head before I remember.
 
19 Jan. 2004 - 20:40 kmr
Yeah true is any non-zero number.
Using using namespace std; is actually a bad habit because it "pollutes" the global namespace. If you're only gonna use cout, cin, and endl, go:
using std::cout;
using std::cin;
using std::endl;

For compilers, Visual C++ 6.0 is nice indeed.
 
19 Jan. 2004 - 21:35 methodik
good thread - eager to follow this. i've been wanting to translate my xBar app into C++ from VB - seeing as it is a console only type app, it shouldn't be too bad, and perhaps this will give me the incentive. :)

i'm going to load Visual C++ back up on my box here, and it would be real sweet to have some sort of tutorial(s) that i can follow and implement for myself. ( like a 'hello world' type tutorial, complete with window creation. )

even so, learning lots just by reading. :)
 
19 Jan. 2004 - 22:03 beaker
FWIW, I use method 1 of the spacing.formatting, fallout. It helps me to visualize the logic, since I'm fairly new to the C world. I also code css that way :)
 
19 Jan. 2004 - 22:50 grigri
I always use method 1 - I find it much easier to spot missing braces, and generally "feel" the code flow. I imagine it's very much a matter of taste though.

I (gulp) don't tend to use the standard library, in fact I usually compile without it, as it tends to bloat the executable size, especially noticeable for small projects. The "standard" functions such as atoi and so all have native windows equivalents, and they can be easily replaced.
I'm not saying everyone should do this, again it's a matter of preference. I do know the standard crt very well though, since I had to use it at uni :)
 
20 Jan. 2004 - 07:05 fallout
The only file that I put using namespace std in is the file that contains main and that's only when I am writing small things that will not re-use any code from. Code is faster to modify then. When I have sufficiently completed something I will usually prefix everything and get rid of the using statement(doing this will make exe's smaller).

I think that readers of this thread will have already seen a couple tutorials on the very basic's of c++ so I think we can probably skip over much about native types, common operators, and loops.

Here is a list of what I feel should be discussed:
  • file i'o
  • classes
  • overloading operators
  • templates
  • pointers
  • the power behind using c++ as a low level language (the asm command)
  • the stl containers
  • recursion
  • inheretance
  • win32 exe*
  • threading*
  • win32 dll*
  • xml DOM
  • optimising your code

* if there was anywhere that I didn't know what was going on it's here!

anything else?
 
20 Jan. 2004 - 15:45 Red
Oh wow... didn't know the thread would go this fast. Man, I've got some catching up to do. :o Feel free to keep going, but be prepaired to reiterate a few things. ^.^
 
20 Jan. 2004 - 16:08 methodik
i gotta say. this thread has the possibility to become really huge. there are just so many topics which could be covered in depth once you start talking about c++, that one single thread may become difficult to handle.

so further on that, i wonder what plastic would think of the idea of having a dedicated area for programming threads. could cover all areas of coding, c++, vb, scripting, html, php, etc. might be handy.

i reinstalled vc++ last night, and actually managed to play around a bit, but of course, a few questions:

you guys were talking about the proper way to do includes. kinda lost me there. is '#include <windows.h>' wrong? is there a 'using namespace something' that i should be doing? i guess the whole namespace thing has me a little confused.

i'm sure i'll have more questions to come, lol.
 
20 Jan. 2004 - 16:30 grigri
I agree, one thread isn't really feasible for a subject this huge. I mean it's only just been started and it's already pretty big!

Don't worry meth, they're talking about the CRT headers, nothing to do with windows.h. At some point someone decided to move all the crt classes into namespaces (like the std namespace), so they renamed the new headers without the ".h".

Namespaces are a C++ invention to try to avoid variable name collisions. The entire windows API is based on C, not C++, so it simply does not apply :)
 
22 Jan. 2004 - 03:10 methodik
thanks for clearing that up for me grigri.

i played last night with a lot of what you gusy have talked about here, and am patiently waiting for more lessons. :)
 
29 Jan. 2004 - 09:03 Tobbe
Please don't let this thread die. If we could cover fallout's list of things a few posts up this tread will be a great recource :)
 
30 Jan. 2004 - 01:30 fallout
I've been working on it, but schoolwork caught me up for a little bit... more soon(tonight I hope)
 
30 Jan. 2004 - 04:01 fallout
Here is an example of file input/output
it hasn't been extensively tested yet

/*
This Program uses these files:
name - content
list.txt - a list of filenames
any file listed in list.txt - numbers
output.txt - output of the most current run of the program
log.txt - a log of exactly what is happenning in the program
*/
#include <iostream>
#include <fstream>
#include <string>

using std::ifstream;
using std:: ofstream;//you may need to get rid of the space
using std::ios;   //it is there so you don't get the emote

void main() {
    //open file this.txt for input using the handle fin
    ifstream fin("list.txt");

    //create a handle for later use as input to a file
    ifstream fin2;

    //create/overwrite a file named output.txt and give it the handle fout
    ofstream fout("output.txt");

    //create/append to an existing file named log.txt and give it a handle log
    ofstream log("log.txt",ios::app);

    //initialize the rest of the variables used in the program
    char temp[81];
    int filecount=0,numbercount=0,filesum=0,numbersum=0,tempnum;

    log<<"New run of program, files opened, variables set to 0\n";
    
    fin.getline(temp,'\n'); //read new line from file,make sure that the end-of-file
    //marker hasn't been reached and store that line in temp
    while(fin) { //will quit when the end-of-file has been read
        fin2.open(temp);
        log<<temp<<" opened.\n";
        filecount++;
        
        //read all the numbers from the file specified in temp
        fin2>>tempnum;
        while(fin2) {
            filesum+=tempnum;
            numbercount++;
            fin2>>tempnum;
        }
        numbersum+=filesum;
        log<<numbercount<<" total numbers read so far.\n"
         <<"Current sum: "<<numbersum<<'\n';
        fout<<"File "<<temp<<" contains sum of "<<filesum<<'\n';
        filesum=0;


        fin2.close();
        log<<temp<<" closed.\n";
        fin.getline(temp,'\n');
    }
    fout<<"Total sum: "<<numbersum<<"\nAfter "<<numbercount<<" numbers from "
        <<filecount<<" Files\n";
    log<<"Total sum: "<<numbersum<<"\nAfter "<<numbercount<<" numbers from "
        <<filecount<<" Files\n";
    fin.close();
    fout.close();
    log.close();
}
 
30 Jan. 2004 - 13:56 Tobbe
Thanks, will try it later!
 
31 Jan. 2004 - 09:41 Tobbe
I'm not really sure why, but I had to add "fin2.clear();" just before "fin2.close();" to make it work... I know that .clear() clears all error-flags in the input stream, and that the input stream won't work if there is an error. That's how I figured out what was wrong. But as I said, I don't know why I needed that .clear(). I don't know what caused the error that needed to be cleared.
 
Please log-in to post.
You need to be logged in to post. To log-in, or to register an account go -there.
 
Options
Login | Help | Profile | User list | Display last  
 days 



xhtml 1.1