Results 1 to 9 of 9

Thread: Problem...

  1. #1

    Thread Starter
    yay gay PT Exorcist's Avatar
    Join Date
    Apr 2002
    Location
    . . . my reason of shame
    Posts
    2,729

    Problem...

    i am using MS visual c++ 6.0 and in most tuturials i see around you use the cout>>"hello world";...but i seem to not can use that ...is it because im using VC++6??? i can use the printf() function...but why damn all ppl use cout>>""; and i cant use it? lol

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    cout <<
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3

    Thread Starter
    yay gay PT Exorcist's Avatar
    Join Date
    Apr 2002
    Location
    . . . my reason of shame
    Posts
    2,729
    Code:
    // mdos2.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    int main(int argc, char* argv[])
    {
    	cout <<"lopl";
    	return 0;
    }
    error:
    --------------------Configuration: mdos2 - Win32 Debug--------------------
    Compiling...
    mdos2.cpp
    C:\Program Files\Microsoft Visual Studio\MyProjects\mdos2\mdos2.cpp(8) : error C2065: 'cout' : undeclared identifier
    C:\Program Files\Microsoft Visual Studio\MyProjects\mdos2\mdos2.cpp(8) : error C2297: '<<' : illegal, right operand has type 'char [5]'
    Error executing cl.exe.

    mdos2.exe - 2 error(s), 0 warning(s)

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    // mdos2.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <iostream> // this is called a header file
    // it contains class and function names so the compiler
    // knows that they exist
    using namespace std; // for now just accept that
    // this line must be here, don't worry what it means

    int main(int argc, char* argv[])
    {
    cout <<"lopl" << endl; // you probably
    // want to end the line with a newline
    return 0;
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5

    Thread Starter
    yay gay PT Exorcist's Avatar
    Join Date
    Apr 2002
    Location
    . . . my reason of shame
    Posts
    2,729
    worked like a charm..hehe although u said "Just accept it" i'd like to know the why of "using namespace std;"..i know we use using <namespace> in C#.NET for somewhat the same that it seems that C++ uses the #define <iostream.h>...am i right?

  6. #6

    Thread Starter
    yay gay PT Exorcist's Avatar
    Join Date
    Apr 2002
    Location
    . . . my reason of shame
    Posts
    2,729
    ah..i saw that printf("",args) works about the same way than cout >> ""...what does work the same way cin << "" works?

  7. #7
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by PT Exorcist
    ah..i saw that printf("",args) works about the same way than cout >> ""...what does work the same way cin << "" works?
    You mean cout << "" and cin >> var;

    Yes, printf works similarly to inserting to cout, they both convert their arguments and print to stdout.

    However, with cout, the compiler knows all the involved types at *compile* time, so it can get it all inlined, checked, etc. before you run it. Using printf, it only checks at runtime, so you can cause some major headaches getting things wrong.

    For now, only use the streams (cout, cin).
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Actually printf doesn't even check at runtime. You can pass anything to it and you'll just get weird results or access violations, but no meaningful error messags.

    printf has another drawback: it cannot be extended for your own classes.

    Oh yeah, you don't
    #define <iostream.h>
    you use
    #include <iostream>
    Note: no .h for C++ header files, they are deprecated and BAD!

    Nice long explanation of namespaces coming up.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    About namespaces.

    In C there sometimes (especially in large projects) occurred a problem named name conflicts. This means that you have more than one function or global variable with the same name, in different modules (probably written by different programmers). Like here:
    Code:
    /* module1.c */
    void PrintDebugData(void)
    {
     /* blablabla printf blablabla */
    }
    
    /* module2.c */
    void PrintDebugData(void)
    {
     /* blablablu puts bluble printf bla */
    }
    Those functions perform similar but different tasks: both output runtime information of the data in this module.

    The code will compile fine, but the linker will discover the two functions with same names and will not know which one to use when there's a reference to PrintDebugData somewhere.

    In practice the only solution was often renaming the function and searching for every call to this function and changing it to the new name.

    C++ has introduced the concept of namespaces to battle this problem. A namespace is a named area of variable visibility. You can for example do:
    Code:
    namespace A
    {
      int i;
    };
    
    namespace B
    {
      int i;
    };
    and the two names will not conflict. Now the programmers with conflicting names could just wrap their whole files in two differently named namespaces and be fine.

    The most important operator that is to be remembered is the :: (scope resolution) operator. It is used to make clear which namespace you mean. e.g. A::i means the i defined in namespace A, B::i means the i defined in namespace B. ::i would mean the i defined outside any namespace (the "global scope"), if there was one.

    This requires a few things to remember:
    Code:
    int i;
    
    namespace A
    {
      int i;
    
      void func()
      {
        i = 4; // means A::i, because we are inside A
        B::i = 3; // means B::i
        ::i = 2; // means the global i
      }
    };
    
    namespace B
    {
      int i;
    
      void func()
      {
        i = 4; // means B::i, because we are inside B
        A::i = 3; // means A::i
        ::i = 1; // means the global i
      }
    };
    
    void main()
    {
      i = 5; // means the global i
      A::i = 2; // means A::i
      B::i = 1; // means B::i
    
      A::func(); // calls A::func, afterwards ::i = 2, A::i = 4, B::i = 3
      B::func(); // calls B::func, afterwards ::i = 1, A::i = 3, B::i = 4
      func(); // ERROR: no function named func in global scope
    }
    The code above won't compile, firstly because of the call to undefined ::func, but also because B::i is referenced before it gets defined. Which leads us to the next section:
    Continuing namespaces.
    When you define a struct or class, once you close the braces it's done. You can't later reopen them and add something:
    Code:
    struct S
    {
      int a, b;
    };
    
    // we now want to extend the struct:
    struct S
    {
      int c, d;
    };
    This code will result in an error: struct S is already defined.

    Namespaces allow this. You can do
    Code:
    namespace NS
    {
      int a, b, c;
      void func();
    };
    
    // do something
    
    namespace NS
    {
      double d, e, f;
      double func2(int i);
    };
    // NS now contains a, b, c, d, e, f, func and func2
    So, in order to make the above code compile you'd do this:

    Code:
    int i;
    
    namespace B
    {
      int i;
    };
    
    namespace A
    {
      int i;
    
      void func()
      {
        i = 4; // means A::i, because we are inside A
        B::i = 3; // means B::i, now works because B::i is declared above
        ::i = 2; // means the global i
      }
    };
    
    namespace B	// extending B
    {
      void func()
      {
        i = 4; // means B::i, because we are inside B
        A::i = 3; // means A::i
        ::i = 1; // means the global i
      }
    };
    
    void main()
    {
      i = 5; // means the global i
      A::i = 2; // means A::i
      B::i = 1; // means B::i
    
      A::func(); // calls A::func, afterwards ::i = 2, A::i = 4, B::i = 3
      B::func(); // calls B::func, afterwards ::i = 1, A::i = 3, B::i = 4
    }
    You may also nest namespaces:
    Code:
    namespace A
    {
      int i;
      namespace B
      {
        int i;
      };
    };
    
    A::i = 4;
    A::B::i = 456;
    Now A, B or NS aren't very good names for namespaces: they might easily get into conflict again, thus removing all the benefit they ever had. You'd better choose namespace names like PROGRAMMERNAME_MODULENAME_GLOBALS. Which has other problems:
    Code:
    namespace SebastianRedl_AiPathFinding_Globals
    {
      void FindPath(POSITION from, POSITION to);
    
      int g_iIterations;
    };
    
    // set number of iterations:
    SebastianRedl_AiPathFinding_Globals::g_iIterations = 100;
    // call:
    SebastianRedl_AiPathFinding_Globals::FindPath(mouseClickPos, unit.location);
    // My fingers are falling off!
    This is why there is the using keyword. There are two ways to use it: per-element or whoel namespaces.
    Code:
    namespace SebastianRedl_AiPathFinding_Globals
    {
      void FindPath(POSITION from, POSITION to);
    
      int g_iIterations;
    };
    
    namespace SebastianRedl_AiPatrollingEnemy_Globals
    {
      POSITION NextPatrolMark(UNIT unit);
    
      double g_dAggresivity;
    };
    
    // because we have many calls to NextPatrolMark
    // we don't want to type the namespace identifier every time.
    // This is where using comes into play:
    using SebastianRedl_AiPatrollingEnemy_Globals::NextPatrolMark;
    
    // Now we can call the function like this:
    POSITION posTo = NextPatrolMark(units[4]);
    
    // both g_iIterations and FindPath from the other
    // namespace are often called, import the whole namespace at once:
    using namespace SebastianRedl_AiPathFinding_Globals;
    
    g_iIterations = 80;
    FindPath(units[4].location, posTo);
    You can also create alias names for namespaces:
    Code:
    namespace SomeNameSpace
    {
      int i;
    };
    
    namespace XYZ = SomeNameSpace;
    
    XYZ::i = 4;  // sets SomeNameSpace::i
    All new C++ headers (those without the .h) define all their elements within the namespace std. Because you often don't know in advance which elements you use (or because you use so many) you don't import the elements selectively with the using std:: syntax but rather grab the whole namespace with a simple
    using namespace std;
    Last edited by CornedBee; Mar 7th, 2003 at 01:53 PM.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width