Announcement

Collapse
No announcement yet.

LECTURE: Introduction into C++

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • LECTURE: Introduction into C++

    For those that are not so familiar with C++ and want to do something on the source code themselves I start a online lecture in thread-format on this subject. Note weather I can hold it on a regularly base depends on my time. It is based on a script to lecture by Andreas Döring, hold at the start of the summer semester 2004 at the Freie Universität Berlin. Note that this script is in German and therefore I have to translate it, so that I will post it stepwise. Actual this is a good thing so that it is posted in small portions. It is entitled "Einführung in C++" in English "Introduction into C++". So let's start:

    Of course first the obligatory motivation:

    Why C++?

    Here are some answers:

    1. C++ is fast.
    2. C++ is widespread.
    3. C++ has a lot of language constructs.
    4. C++ allows machine-oriented programming.

    And of course the most important reason:

    5. CTP2 is written in C++.

    1. Well in spite of opposite messages C++ is still faster then e.g. comparable programs written in Java, but note bad written C++ might be slower then well written Java.

    3. As the complexity of C++ is high we won't probably cover everything, fortunately this isn't necessary.

    4. Machine-oriented programming is an advantage but also a disadvantage. The advantage is that the machine-orientation makes C++ efficient, the disadvantage is that it is more difficult to handle.

    -------------------------------------------------------------------------

    Some useful things to know about C++:

    -It is an imperative programming language.
    -Contains more then 60 reserved keyword, some of them with multiple meaning, that is context depending.
    -The source code is translated (compiled) by a compile into an executable program.

    Imperative programming language: Instructions are executed consecutively. The control flow is handled by instructions.

    Compiling C++ programs takes often a lot of rime. JIT (just in time) compiling like Java is not possible. One reason for this is that C++ compiler use very good optimizer to make the resulting program to run as fast as possible. But note don't rely always on the optimizer, if you chose the wrong algorithm, or you make the code to complicated the compile doesn't has any chance.

    --------------------------------------------------------------------------

    Now enough with all the drivel let's write our first program in C++, of course it is the obligatory "Hello Apolyton!" example.

    Type out the following code, don't use copy and paste:

    Code:
    #include <iostream>
    int main()
    {
    	std::cout << "Hello Apolyton!";
    	return 0;
    }
    Save the file under test.cpp or whatever name you want.

    If you are on a LINUX system, open a shell and compile the program on the command line like this:

    g++ test.cpp -o test

    To execute the program enter ./test

    g++ is the GNU compiler, very common on UNIX/LINUX systems. And should also be available for windows, use Google to find one if you don't have any other compiler, for the start this should be enough, even if we don't have a public available version that compiles on a GNU compiler. Of course under windows you just have to enter the name of the program without extension from the command line to start the program.

    If you have VC++ 6 you just can write your program in its integrated development environment and press Ctrl+F5 and a project file is created automatically and the program is compiled and after compiling it is executed. For .NET you have to create a project file manually.

    #include is a preprocessor directive, that binds the standard library iostream into the program. Alternatively you can replace the angle brackets by quotation marks, but angel brackets are the usual way to include standard libraries.

    main is the name of the function that serves as the entry point of the program, it is the first function of the program that is explicitly called. But don't think that contains the first piece of code that is executed, but that is a story for the advanced ones.

    int is the return type of the main function, the function has to return anything of type int. In that case its value is always 0.

    std::cout is defined in iostream and is an output stream it writes to the console/shell the string "Hello Apolyton!" if the program is executed from the command line.
    The operator << writes the string "Hello Apolyton" to std::cout so that std::cout can write it onto the console/shell.
    sdt is the name of a name space, I don't explain what a name space is at this place.

    And note a semicolon completes each instruction.

    ----------------------------------------------------------------------

    Let's talk about the workflow of compiling:

    - Input: *.cpp and *.h files.
    - For each *.cpp file:
    -- Preprocessor: Include header files (*.h)
    -- Compiler: Create *.obj files
    - Linker:
    -- Creates *.exe files from all *.obj files
    -- Takes all the pieces from the used libraries
    -Output *.exe file

    Instead of *.cpp the extensions *.c and *.C are also common, note that LINUX has a case sensitive files system, therefore *.c and *.C are two different extensions there.

    Alternatively for *.h *.hpp or in the case of the new standard libraries no extensions are in use.

    Some compilers use *.o instead of *.obj, that is for instance the case for the GNU compiler.

    *.h files are called header files. They are used to tell the *.cpp file to be compiled what other functionalities can be found in other *.obj files and libraries. Header files contain declarations.

    OK next time I continue with preprocessor and declarations and definitions, just to mention some of the stuff to come.

    -Martin
    Last edited by Martin Gühmann; January 16, 2005, 14:49.
    Civ2 military advisor: "No complaints, Sir!"

  • #2
    Good tutorial. One problem - there is no after the #include.
    Last edited by tombom; March 21, 2005, 05:07.
    Caution! Under no circumstances confuse the mesh with the interleave operator, except under confusing circumstances!
    -Intercal reference manual

    People often remark of me, "You say sorry far to much!". To which my common-sense reply is "I apologise".

    Comment


    • #3
      Originally posted by tombom
      Good tutorial. One problem - there is no after the #include.
      That is a problem of the following:

      Forum Rules:
      You may post new threads
      You may post replies
      You may post attachments
      You may edit your posts

      HTML code is ON
      vB code is ON
      Smilies are ON
      [IMG] code is ON
      HTML code is ON. And I cannot disable it, so it interpretes anything within angle brackets as HTML code and removes it from the thread. Well I fixed it by using HTML code for the angle brackets.

      By the way I wanted to give you all a little task. Each console program has a main function, well for Windows it is called WinMain, but for the LINUX version there is added in the meantime a main function. So your task is to find this main function in all these files. Note that it is in a *.cpp file. And to find it use the automatic search function of your operating system. Later when you work with the source code you need to know how to find stuff easily. The main two questions are in which kind of files you are looking for and for what string you are looking for.

      -Martin
      Civ2 military advisor: "No complaints, Sir!"

      Comment


      • #4
        OK, let's continue with the lecture.

        The Preprocessor

        - Instructions for the preprocessor start with #
        - #include adds a file into the source code for instance a header file:

        Code:
        #include <iostream>
        #define defines a macro: The keyword is replaced in the whole program by the given text.

        Code:
        #define PI 3.141596
        In this example every time you write PI in the source code the precompiler replaces it by 3.141596.

        You can also pass some arguments to a #define for instance:

        Code:
        #define AUSGABE(a,b) cout << a << “ is ” << b
        This

        Code:
        AUSGABE(“my favourite color”, 42);
        becomes

        Code:
        cout << “my favourite color” << “is” << 42;
        Note: This is a simple text replacement. Macros may generate text that contains other macros, but recursive macros aren't possible.

        Note: Use #define sparely, in the mean time there much better constructs that can replace #define in most cases.

        -----------------------------------------------------------------------

        A C/C++ program is a text

        - The source code is case sensitive
        - Preprocessor: Instructions end with a line break
        - Compiler: Line break is white space
        - Exception: Comments they start with // and end with the next line break

        For instance:
        return 0; // returns always 0

        - Instructions end with a semicolon ';'
        - No semicolon follows preprocessor instructions and closing brace '}' except enums and classes.

        -------------------------------------------------------------------------

        Declarations and Definitions

        Declaration of X = Description, what is X

        Diffinition of X = Declaration of X and generation of X

        Note: It is allowed to declare an X as often as you want, but it is only allowed defining it once.

        Header files allow to notify other *.cpp files about symbols that are defined in one *.cpp file. The other *.cpp files just need the declarations of these symbols. But other header files should just contain declarations and no definitions, because otherwise each *.cpp file would define a new X.

        At the latest the linker would complain if one and the same X is defined multiple times, even if the definitions are all the same. The reason is that at each definition another new X is generated and the linker has no idea, which X it should take.

        But note that the same identifier can be defined in different {}-blocks at the same time as local symbol. The same identifier can be used in different name spaces for something different.

        --------------------------------------------------------------------------

        Variables

        Variables definition:

        Code:
        int j; // One variable j of type int
        float x, y; // Two variables x and y both of type float
        Optionally the variables can be initialized:

        Code:
        int i = 32;
        float z = 2.781;
        char c = 'x';
        Declaration of variables with the keyword extern
        Code:
        extern int i;
        The assignment of initial values is only possible at variable definitions not at bare declarations.

        Here is an example from the source code, you can find this line in scheduler.cpp, but where is the definition of g_theGoalDB. Use the same technique you used to find the main function, so far we got to know header files (*.h) and source files (*.cpp), and of course you have your operation system's search enigne to look for strings in a lot of files. Therefore it should be such a problem for you to find it.

        Code:
        extern CTPDatabase *g_theGoalDB;
        --------------------------------------------------------------------------

        Availability of declarations

        Rule 1:
        A symbol is in a program text only known under its declaration.

        Rule 2:
        A declaration within a {}-block is only available in the same {}-block and its sub blocks, but not outside.

        Code:
        int main(){
        	{
        		int x;
        		x = 0; // No problem x is known here
        	}
        	return x; // Error x is not known here
        }
        ------------------------------------------------------------------------------

        Built-in Types

        Each variable can contain values of a certain type:

        char: Numbers from 0 to 255
        signed char: Numbers from -128 to 127
        short int: Numbers from -32768 to 32767
        unsigned short int: Numbers from 0 to 65535
        int: Numbers from -2^31 to (2^31)-1
        unsigned int: Numbers from 0 to (2^32)-1
        bool: true or false

        On 64-bit-machines int can also be numbers between -2^63 and (2^63)-1 and unsigned int also between 0 and 2^64. Note this is compiler dependent. So don't be sure that an int is always and everywhere exactly 4 bytes big.

        Instead of int and unsigned int long int and unsigned long int can be used respectively. Formally these are different types. But at least on 32 bit machines the same fits into them. Of course in the case of doubt this is compiler dependent.

        Instead of "char" "unsigned char" and instead of "short int" "signed short int" and instead of "int" "signed int" can be used.

        Additional "short" can be used instead of "short int", "unsigned short" instead of "unsigned short int", "long" instead of "long int" and "unsigned long" instead of "unsigned long int". So everything clear now?

        ------------------------------------------------------------------------

        Additional Built-in Types

        Types for saving floating point numbers:

        float: Floating point number with simple precision
        double: Floating point number with double precision

        If float and double are different at all is dependent on the used machine and the used compiler. The only rule is that double is not allowed to be less precise than float. Typical are 4 bytes for float and 8 bytes for double.

        --------------------------------------------------------------------------

        ... and what is with characters?

        Characters are whole numbers:

        'A' == 65 <- Simple quotation marks for single characters. Which character is assigned to which number, is determined by the ASCII table.

        Also logical (Boolean) values are numbers:
        true == 1 (and all other numbers unequal 0)
        false == 0

        (Sequences of characters (strings) are more complex ...)

        As single characters are numbers they can also be used like numbers:

        Code:
        'A' + 2 == 'C'
        'F' < 'T'
        Well this should be all for now, next time we will continue with arrays, strings and pointers.

        -Martin
        Last edited by Martin Gühmann; January 16, 2005, 14:35.
        Civ2 military advisor: "No complaints, Sir!"

        Comment


        • #5
          JIT (just in time) compiling like Java is not possible. One reason for this is that C++ compiler use very good optimizer to make the resulting program to run as fast as possible.
          I think this is wrong. JIT would be possible because you might know at runtime that in this loop, the concrete class is always XXX so you could bypass the virtual function table sometimes.
          In particular, inner classes have a virtual finction table that is useless. For isntance:
          class A {virtual ~A(); virtual method();}
          class B {private A a;}
          a is an object that bears a virtual function table which could be optimised away. But then we already know it at compile time and the compiler doesn't get rid of it. If you go a little further you can get optimisations that are always possible but can be found out only at runtime (e.g. using statics so the inner class type is not seen from the outside at link time but is known at run time).
          Clash of Civilization team member
          (a civ-like game whose goal is low micromanagement and good AI)
          web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

          Comment


          • #6
            Originally posted by Martin Gühmann
            Declarations and Diffinitions
            If you'll forgive me niggling (which I wouldn't do normally, except that I think spelling, etc. is more important in a tutorial-style context), that's "Definitions".

            Comment


            • #7
              Originally posted by J Bytheway


              If you'll forgive me niggling (which I wouldn't do normally, except that I think spelling, etc. is more important in a tutorial-style context), that's "Definitions".
              Well next time I use a spell checker, however I have fixed the first two parts.

              -Martin
              Civ2 military advisor: "No complaints, Sir!"

              Comment


              • #8
                well I think it is good for a translation.
                "Every time I learn something new it pushes some old stuff out of my brain" Homer Jay Simpson
                The BIG MC making ctp2 a much unsafer place.
                Visit the big mc’s website

                Comment


                • #9
                  Originally posted by The Big Mc
                  well I think it is good for a translation.
                  Of course I can dig up a script in English, but then I don't need to post it piecewise, then I can just give the link and tell everyone to work through alone. And of course such a script would be without the valuable references to the source code.

                  -Martin
                  Civ2 military advisor: "No complaints, Sir!"

                  Comment


                  • #10
                    I don't see a Preprocessor "exercise" here, and nothing mentioning the use of #! is there somewhere I go, or did I miss something here.
                    Formerly known as "E" on Apolyton

                    See me at Civfanatics.com

                    Comment


                    • #11
                      Originally posted by E
                      I don't see a Preprocessor "exercise" here, and nothing mentioning the use of #! is there somewhere I go, or did I miss something here.
                      The preprocessor is explained at the start of the second part. Well not in detail.

                      It is explained again in this post and the execise is there as well:

                      Now do the following: Form two versions of the following code fragment one that the preprocessor generates if the statement defined(ACTIVISION_ORIGINAL) is true and one if this statement is false. And finally post these two code fragments. You have to get this!
                      And the code in question is there as well. And for #! it is in the other thread.

                      But here again:

                      All preprocessor instructions start with a #. Like:

                      #if
                      #else
                      #endif

                      The boolean statment can be true or false, 1 or 0 respectively.

                      defined(ACTIVISION_ORIGINAL) is such an boolean expressions. And it is true if ACTIVISION_ORIGINAL is defined and false otherwise. And as every boolean expression in code it can be modified by operators. Well the operators are missing here. So let's come to the exclaimation mark operator:

                      Each boolean expression can be true or false, the exclaimation reverses the value of a boolean expression, so false becomes true and true becomes false: Here an example for the operator:

                      !true == false: In words not true equals false
                      !false == true: Not false equals true

                      If we compile the source code ACTIVISION_ORIGINAL is not defined. So the expression defined(ACTIVISION_ORIGINAL) is false and in the following example Code 1 is cut out and Code 2 is compiled.

                      #if defined(ACTIVISION_ORIGINAL)
                      // Code 1
                      #else
                      // Code 2
                      #endif

                      Of course if ACTIVISION_ORIGINAL is defined it is the way around.

                      And of course if you now do the negation of the defined statement and ACTIVSION_ORIGINAL is not defined in the following code Code 1 is compiled and Code 2 is cut out.

                      #if !defined(ACTIVISION_ORIGINAL)
                      // Code 1
                      #else
                      // Code 2
                      #endif

                      Of course no one forces you to put an else block:

                      #if !defined(ACTIVISION_ORIGINAL)
                      // Code 1
                      #endif

                      or

                      #if defined(ACTIVISION_ORIGINAL)
                      // Code 2
                      #endif

                      In our setup with ACTIVISION_ORIGINAL not defined Code 1 is compiled and Code 2 is cut out and therefore is ignored.

                      -Martin
                      Civ2 military advisor: "No complaints, Sir!"

                      Comment


                      • #12
                        Hi again.

                        Little question regarding the reserved word RETURN.

                        Every reference that I've checked states that this is a variable which is used to pass a value back to a calling routine.
                        All the references include sample code where RETURN is the final statement.

                        Reading the CtP2 source files suggests that this is not the whole story as routines, quite often, contain multiple RETURNs.

                        If the references are correct then, in this psuedo-code,

                        if 1
                        return 1;
                        if 2
                        return 2;
                        return 0;

                        the returned value would always be 0.

                        Does setting a return value result in an implicit exit-routine being performed (which would also mean that RETURN could not be initialised at the start of a routine)?

                        Or is there another explanation?

                        TIA

                        Comment


                        • #13
                          Originally posted by Mirimunchkin
                          Little question regarding the reserved word RETURN.

                          Every reference that I've checked states that this is a variable which is used to pass a value back to a calling routine.
                          All the references include sample code where RETURN is the final statement.
                          'return' is not a variable - if it were then you would have to use syntax like "return=0", rather than "return 0".

                          Reading the CtP2 source files suggests that this is not the whole story as routines, quite often, contain multiple RETURNs.

                          If the references are correct then, in this psuedo-code,

                          Code:
                          if 1
                             return 1;
                          if 2
                            return 2;
                          return 0;
                          the returned value would always be 0.

                          Does setting a return value result in an implicit exit-routine being performed (which would also mean that RETURN could not be initialised at the start of a routine)?
                          'return' is a keyword which is used to indicate that control should leave this function immediately, and there is the option of also specifying a return value to be passed to the calling function.

                          So, in short, your pseudo-code can return either 1, 2 or 0, depending on which of the conditions are true.

                          Comment


                          • #14
                            Txs JB.

                            Pity that the text books don't mention exiting the function!!!

                            Sorry about the sloppy use of the term 'variable' .

                            Comment


                            • #15


                              may help as well.
                              Formerly known as "E" on Apolyton

                              See me at Civfanatics.com

                              Comment

                              Working...
                              X