C++

Discussion in 'Scripting & Programming' started by Mof, Jul 10, 2008.

  1. nellyp123

    nellyp123 Byte Poster

    213
    13
    0
    Thats not good enough...go and learn it!!! LOL!

    Cheers anyway. :cry:
     
    Certifications: CIW Professional
  2. Mof

    Mof Megabyte Poster

    526
    2
    49
     
    WIP: C++ and A+
  3. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    Well for your example:

    'enum' stands for 'enumeration' which means that the members of the set {paul,jack,harry} will be substituted for the set {0, 1, 2} since paul = 0, jack = 1, harry = 2 - since an enumeration's default value assignment starts from 0. To 'enumerate' something means to give it a value representing its order in a particular group, which slightly diverges from the regular meaning which means to 'quantify'.

    'name' is the label assigned to the enumerated set {paul, jack, harry} which is actually {0, 1, 2}.

    'typedef' provides an alias for a given type, so for the code

    Code:
    typedef enum {paul, jack, harry} name;
    
    we are saying in English for the type 'enum {paul,jack,harry}' we will give it the name 'name'.
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  4. Mof

    Mof Megabyte Poster

    526
    2
    49
    and this is saying the following enum is named "name". and thats why they are the same. so why use type def.

    in the book it shows:
    typedef enum{NEGATIVE,POSITIVE} charge;

    can this code be written as:

    enum charge {NEGATIVE,POSITIVE};
     
    WIP: C++ and A+
  5. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    In C++ it's down to choice and both lines of code are equivalent. The reason why it is different for C is the way that code is interpreted when parsed is actually different. It's a very long story that you won't understand right now unless you want to start learning how compilers and linkers work exactly, but take it for granted now that C++ semantics (what your code actually is defined to do from compilation right up to the final executable) is more intelligent than that for C. :)

    To put it another way, it is taken for granted that every enum must have a type name therefor making 'typedef' redundant in this instance.
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  6. Mof

    Mof Megabyte Poster

    526
    2
    49
    beautifully explained as usual.:cheers:cheers:clap:thumbleft:onthePC
     
    WIP: C++ and A+
  7. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    Excellent! you should also give yourself a pat on the back for understanding! :biggrin
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  8. Mof

    Mof Megabyte Poster

    526
    2
    49
    Mathmatix seeing that you are on line Ive been playing about with a mixture of the codes we have been talking about. I have no compiler at work as was wondering if you would tell me if this runs ok.

    # include <iostream>
    using namespace std

    int main()

    int letter; letter='A';

    cout << "Letter:" << letter << endl;

    int letter(a=1,b=4);
    cout<< "A+B=:"<<a+b << endl;

    enum charge{NEGATIVE,POSITIVE};
    charge = neutral wire, live wire;
    cout<<"Neutral wire:"<< neuatral<<endl;
    cout<<"Live Wire:"<< live wire<<endl;


    return 0;

    Ive not looked in the book, trying to see if i have remembered,so there well could be mistakes.
     
    WIP: C++ and A+
  9. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    Code:
    #include <iostream>
    
    using namespace std;
    
    enum Charge{NEGATIVE,POSITIVE};
    
    int main(){
    
        int letter='A';
    
        cout << "Letter:" << letter << endl;
    
        int a=1, b=4;
        cout << "A+B=:" << a+b << endl;
    
        Charge neutral_wire = NEGATIVE;
        Charge live_wire = POSITIVE;
    
        cout << "Neutral wire:" << neutral_wire << endl;
        cout << "Live Wire:" << live_wire << endl;
    
        return 0;
    }
    There were some syntax errors, I think this is what you meant.

    In C++ its normal to put enums inside either a namespace or a class to avoid poluting the global namespace.

    Note typesafe enums are a goal of the C++0x standard http://en.wikipedia.org/wiki/C&#37;2B+0x#Strongly_typed_Enumerations
     
  10. Mof

    Mof Megabyte Poster

    526
    2
    49
    Hi Dmarsh26 good to talk again hope your keeping well.

    I notice you droped the "enum charge{NEGATIVE,POSITIVE};
    is this because of the code above sees itself as a enum.
     
    WIP: C++ and A+
  11. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    No I just moved it to be in file scope instead of local scope.

    The concept of scopes is very important in programming.

    It's not important for this exercise but in general enums are not declared in local scope, they will normally be class or file scope and possibly also reside in a namespace.

    Scope C/C++
    C++ Scope

    The concept of scope is quite complex in C++.

    Explanation of Scope, Storage Allocation and Linkage Units

    In essence you are currently learning C++ as a better C, you can probably just look at and understand C scoping rules for now.

    All your examples thus far have also resided in a single linkage unit which further simplifies matters.

    Later when you look at C++ contructs like classes and inheritance you can look into the C++ scoping rules
     
  12. Mof

    Mof Megabyte Poster

    526
    2
    49
    I can see where you have put it now, Cheers
    and fancy me forgeting {} at the start and end opps!
     
    WIP: C++ and A+
  13. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    Sorry, Mof. Been hopping on and off for a mind break as I'm quite busy. Will address your question later today. :)
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  14. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    Back for a rest. Yippee! :biggrin

    Seeing as dmarsh got rid of the syntax and semantic errors we'll look at that code.

    Code:
    #include <iostream>
    using namespace std;
    
    enum Charge{NEGATIVE,POSITIVE};
    
    int main()
    {
    
        int letter='A';
    
        cout << "Letter:" << letter << endl;
    
        int a=1, b=4;
        cout << "A+B=:" << a+b << endl;
    
        Charge neutral_wire = NEGATIVE;
        Charge live_wire = POSITIVE;
    
        cout << "Neutral wire:" << neutral_wire << endl;
        cout << "Live Wire:" << live_wire << endl;
    
        return 0;
    }
    
    You are right to only declare variables immediately before you use them, and likewise for the original position of your definition for the enum 'Charge'. Let me demonstrate why...

    Code:
    #include <iostream>
    using namespace std;
    
    enum Charge{one_quid, two_quid};		// 'Charge' INCORRECTLY redefined in local scope.
    
    int main()
    {
    
        int letter='A';
    
        cout << "Letter:" << letter << endl;
    
        int a=1, b=4;
        cout << "A+B=:" << a+b << endl;
    
        enum Charge{NEGATIVE,POSITIVE};		// 'Charge' CORRECTLY redefined in local scope. 
                                                                                 // Overrides 'enum Charge{one_quid, two_quid};'
    
        Charge neutral_wire = NEGATIVE;
        Charge live_wire = POSITIVE;
    
        cout << "Neutral wire:" << neutral_wire << endl;
        cout << "Live Wire:" << live_wire << endl;
    
        return 0;
    }
    
    In the code above, the global definition of 'Charge' is overridden by the correctly defined enum in the local scope to be correct for the code that follows. This makes for tighter code than only defining the enum in global scope. You should only make it global if you are certain that that would be the definition of Charge for everywhere in your code that you intend to use it.

    Comment out the local definition of Charge and see what happens.

    Apart from that point the rest has already been explained.
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  15. Mof

    Mof Megabyte Poster

    526
    2
    49
    Sorry mathmatix dont understand which part to remove.
     
    WIP: C++ and A+
  16. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    This bit.

    Code:
    enum Charge{NEGATIVE,POSITIVE};		// 'Charge' CORRECTLY redefined in local scope.
    
    :biggrin

    My bad, the outer one is global scope and should read:

    Code:
    enum Charge{one_quid, two_quid};		// 'Charge' INCORRECTLY redefined in GLOBAL scope.
    
    Sorry!
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  17. Mof

    Mof Megabyte Poster

    526
    2
    49
    errors not declared in scope

    opps

    C:\MyPrograms>c++ scope.cpp -o scope.exe
    scope.cpp: In function `int main()':
    scope.cpp:19: error: `NEGATIVE' was not declared in this scope
    scope.cpp:20: error: `POSITIVE' was not declared in this scope
     
    WIP: C++ and A+
  18. Mathematix

    Mathematix Megabyte Poster

    969
    35
    74
    Exactly. But you know why it happened?
     
    Certifications: BSc(Hons) Comp Sci, BCS Award of Merit
    WIP: Not doing certs. Computer geek.
  19. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    Good to see you looking into scope ! :D

    Please bear in mind that in real life main() is really just an entry point into your program, as such it should be just a few lines long, just long enough to hand control off to another object, it should not really declare any types.

    In general names should be limited to the smallest scope possible and you should avoid global state and polution of the global namespace.

    However it is often not realistic to keep constants and enums to local scope and class or namespace scope comes to the rescue in C++. Earlier I avoided putting the enum Charge in a class or namespace in order to avoid causing confusion with syntax which might be new to you. I'll give a fuller explanation here but it requires more knowledge of C++.

    Public constants and enums along with public methods and public members form the 'interface' to your class/library/module.

    Consider this example of a Card Data Type :-

    Code:
    class Card {
    public:
       enum Suit {
          Diamonds,
          Hearts,
          Clubs,
          Spades
       };
    
       // Declare two constructors: a default constructor,
       //  and a constructor that sets the cardinal and
       //  suit value of the new card.
       Card();
       Card(int CardInit, Suit SuitInit);
    
       // Accessors and Mutators
       int  GetCardinal() const;       // Get cardinal value of card.
       void SetCardinal(int cardinal); // Set cardinal value of card.
       Suit GetSuit() const;           // Get suit of card.
       void SetSuit(Suit new_suit);    // Set suit of card.
    
    private:
       Suit  m_suit;
       int   m_cardinalValue;
    };
    
    The enum is in public class scope, because it is used in the classes public interface. It cannot live in local scope, thats my original point, its very rare for an enum to be able to live in local scope, because it severely limits its usefulness in a C++ OO program.

    There are many legacy global constants and enums as part of the C headers. While this is not great practice (and led to things like namespaces being introduced in C++) it illustrates the point that constants generally need a larger scope.

    Local variables however should always have their scope minimised by declaration at point of first use, and thats demonstrated in some of the examples. You should also avoid redefinition and reuse of variables for a different purpose than was originally intended.

    Also with type names I would ensure they are at least unique across all of your code, in practice you would not declare two types with the same name in your code, at least not without a controlling scope like a class or namespace. Where this might happen is when you consume third party libraries and this is a major reason why scopes and namespaces exist. You can then use these to avoid name clashes that do arise.

    Its all about intent, as a programmer you must convey your intent clearly to the reader of your program and follow the law of least surprise.

    If you've yet to look at classes you may need to come back later to understand this, if so for now continue to just look at the C scope rules.
     
  20. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    Heres the example again with a namespace, note in real life this would probably be in a class and a namespace, and the code would be spread across multiple files ! :D

    Code:
    namespace electricity {
        enum ElectricPlugWireType{NEUTRAL,LIVE,EARTH};
    }
    
    int main(){
    
        electricity::ElectricPlugWireType black_wire = electricity::NEUTRAL;
        electricity::ElectricPlugWireType red_wire = electricity::LIVE;
        electricity::ElectricPlugWireType blue_wire = electricity::NEUTRAL;
        electricity::ElectricPlugWireType brown_wire = electricity::LIVE;
        electricity::ElectricPlugWireType green_and_yellow_wire = electricity::EARTH;
    
        return 0;
    }
    
    Now we've avoided poluting the global namespace, plus we've been explicit on where the Charge we want comes from. We've also allowed the charge type to be reused if we put it in a header file. The purpose of declaring types generally is to allow them to be reused as well as to make the code expressive and self documenting.

    We could also rename it ElectricPlugWireType to be more specific, an electric charge is not really a wire its an amount of energy or potential difference of electrons between two points. However this is just an example and this enum is probably not the best example of a real life enum anyway. Electric charge is only negative or positive in relation to another point, its a relativistic term, but we also use it to label terminals on equipment. You could define it as an enum if you wanted :-

    Code:
    namespace electricity {
    enum TerminalType {POSITIVE, NEGATIVE};
    }
    You are modelling the real world when creating a computer program. Its unlikely you would represent monetary charges or electric charges as plain enums in real life. Since you would probably need to represent sign and magnitude convential number representations would generally be better.
     

Share This Page

Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.