Tom Gunn 1,164 Practically a Master Poster

You need to #define TEST to run the code as is. main() is conditionally compiled because this is a library function.

Tom Gunn 1,164 Practically a Master Poster

CSV is more than just comma delimited fields. There are quoting and white space rules too. This is a short function as an example of a complete way to read CSV records line by line.

Tom Gunn 1,164 Practically a Master Poster

Lessons timings are: 8pm to 10pm GMT!

What days? If you only have lessons on weekdays then I cannot attend. Those times fit right in the middle of work in my time zone. However, I can attend on weekends.

Tom Gunn 1,164 Practically a Master Poster

I think I will give it a try. What are the time zone constraints for these lessons? I doubt you are running them 24/7. ;)

Tom Gunn 1,164 Practically a Master Poster

I am interested, but I have never used skype before.

Tom Gunn 1,164 Practically a Master Poster
if (i != n){
                cout << i << '\n' << n << '\n';
                files += line;
                files += '\n';
            }

What is files ? You use that identifier as if it were a string, but it is never declared or defined anywhere.

Tom Gunn 1,164 Practically a Master Poster

I think you need to create a project and attach those files to the project before you can build and then run.

Tom Gunn 1,164 Practically a Master Poster

What does your copy constructor look like for the XboxFriends class?

Tom Gunn 1,164 Practically a Master Poster

Is there a way for me to compile them into some shared library object so that I can link them with my visual c++/clr source files using cl.exe.

You need to rebuild them on a Windows system or use a cross compiler targeting Windows. Otherwise the library file format from Unix will not work. If the code does not use anything unique to C99 or Unix, you might be able to compile with Visual C++, but I guess since you are asking this question, that did not work. ;)

Tom Gunn 1,164 Practically a Master Poster
printf("\nThe value is: %d", i**pow);

** is not an operator in C, it will be parsed as i * (*pow) , which should either not compile or throw a runtime exception because pow is not a pointer. The pow() function in math.h is the library way to calculate a power. It is also easy to write a loop that multiplies a number x times to get the power.

Tom Gunn 1,164 Practically a Master Poster

Can you do it all in main? If all you need to do is refactor, that is relatively easy. Take a simple adder for example:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a, b;

    printf("2 numbers to add: ");

    if (scanf("%d%d", &a, &b) != 2)
    {
        fputs("Error reading expected numbers\n", stderr);
        return EXIT_FAILURE;
    }

    printf("%d + %d = %d\n", a, b, a + b);

    return 0;
}

a+b is a simple expression, but you might want to refactor it into a function. The first step is to decide how you want to use the function. In this case having it take a and b as arguments and return the result makes sense. Your maximum value function would probably work the same way. Next, cut out the expression and replace it with the function call you want:

/*
Not working code
*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a, b;

    printf("2 numbers to add: ");

    if (scanf("%d%d", &a, &b) != 2)
    {
        fputs("Error reading expected numbers\n", stderr);
        return EXIT_FAILURE;
    }

    printf("%d + %d = %d\n", a, b, add(a, b));

    return 0;
}

Now it is just a matter of defining a function with the same interface and making the body of the function do what needs to be done. If you name the parameters the same as the arguments being passed in, you can paste the expression that you cut out earlier:

#include <stdio.h>
#include <stdlib.h>

int add(int a, int b)
{
    /* same expression …
Tom Gunn 1,164 Practically a Master Poster

If you defer initialization of the struct object, you can do it all in one go:

#include <stdio.h>

typedef struct a
{
	int a;
} A;

typedef struct b
{
	char ba[2][12];
	int bb[12];
} B;

int main()
{
    B test = 
    {
        {"a", "b"},
        {1, 2, 3, 4, 5}
    };
    int x;

    for (x = 0; x < 2; ++x) printf("%-2.12s", test.ba[x]);
    putchar('\n');
    for (x = 0; x < 12; ++x) printf("%-2d", test.bb[x]);
    putchar('\n');

	return 0;
}

One can say char a[] is simply a string since a string in C is only an array of chars.

That is only half the story. A string in C requires two parts: an array of character type and a terminating '\0' character. If you have an array of char but not '\0' at the end, it is not a string. A string also does not have to be the char type. C supports two character types for strings where there are string constants and string functions defined. char is the single byte character type and wchar_t is the multibyte character type.

So when one says char a[][] is that not a 1d array of strings?

It is a 2D array of char. If the inner arrays are all strings then it is also a 1D array of strings. You can use it either way as long as the requirements for a string are met.

Tom Gunn 1,164 Practically a Master Poster

1)What is a NULL Macro? What is the difference between a NULL Pointer and a NULL Macro?

The NULL macro is a symbolic name for a null pointer constant. It is defined something like this:

#define NULL ((void*)0)

or this:

#define NULL 0

2)What is the difference between the functions rand(), random(), srand() and randomize()?

rand() returns a pseudo random number between 0 and RAND_MAX. srand() seeds the random number generator that rand() uses so that the same sequence is not generated each time. Under the hood rand() and srand() work something like this:

static int __seed;

void srand(int seed)
{
    __seed = seed;
}

int rand()
{
    int r = {cool math using __seed};

    ++__seed;

    return r;
}

random() and randomize() are not part of the C library, but if a compiler supports them they probably work similarly to rand() and srand().

Tom Gunn 1,164 Practically a Master Poster
for(int i = 1; i <= a; i++)

Vectors are indexed the same way as arrays, using 0 based indexes. You start at 0 and go to N-1:

# include <iostream>
# include <iomanip>
# include <math.h>
# include <vector>

using namespace std;

void getCurves(int& );

int main()
{
    int a = 0, y = 1;

    getCurves(a);

    vector<float> RA(a);

    cout << "Please key in RA : ";

    for(int i = 0; i < a; i++)
        cin >> RA[i];

    cout << "RA : " << endl;
    for(int j = 0; j < a; j++)
        cout << RA[j] << endl;

    system("pause");
}

void getCurves(int& a)
{
    int pass = 0;

    cout << "Plese key in 'a' : ";
    cin >> pass;

    a = pass;
}

The error you were getting was right. There were only 5 slots in the vector, but you were trying to access the 6th. It did not exist and threw and exception.

Tom Gunn 1,164 Practically a Master Poster

I think before you get into Windows and games, you should be very comfortable with just C++. That way you only struggle with one complex thing at a time. ;) This is a good second book on C++.

Tom Gunn 1,164 Practically a Master Poster

Can you post something that I can compile? I cannot reproduce your problem with the code given.

Tom Gunn 1,164 Practically a Master Poster

Can you take a look at my program and tell me if it will work for all numbers? Or can you see an exception when this algorithm wont work?

If you want to be confident in your algorithm, you need to give it good tests before turning it in. The function reverses digits, so the testing is pretty easy. I would start with these test cases for 32 bit ints:

0
1
2
3
12
123
1234
12345
123456
1234567
12345678
123456789
1234567890
-1
-2
-3
-12
-123
-1234
-12345
-123456
-1234567
-12345678
-123456789
-1234567890 INT_MIN or numeric_limits<int>::min() INT_MAX or numeric_limits<int>::max() This covers all possible digit counts on both positive and negative numbers, it tests the edge cases of the largest and smallest possible value, and it tests values around your recursive base condition.

At the bare minimum, you should test average cases to make sure the algorithm works in general, and boundary cases to make sure that the algorithm is complete. If you can, write a function that exhaustively covers all cases, because that is a stronger test.

Tom Gunn 1,164 Practically a Master Poster

vector sizes are always in unsigned integers, so change the for-iterator i into an unsigned int.

The type might not be unsigned int . It is safer to use the actual type that is typedef'd in the vector class:

void RandomArrayFill(vector<int>& vec)
{
    cout << "Creating and filling the array with integers..." << endl;

    for (vector<int>::size_type i = 0; i < vec.size(); ++i)
    {
        vec[i] = rand() % 101;
    }

    cout << "Array = {";

    for (vector<int>::size_type i = 0; i < vec.size(); ++i)
    {
        cout << vec[i] << " ";  
    }

    cout << "}" << endl;	
}

also in the first program there is no memory leak.

Are you sure.

I am. The allocation in the function is commented and will not run. If you uncomment it, there will be a compiler error because array is redefined.

Tom Gunn 1,164 Practically a Master Poster

Complete Binary Tree, Full Binary Tree, Perfect Binary Tree.

According to those definitions, I would draw the difference like this:

// Trees rotated 90 degrees counter clockwise

Perfect:       Full:         Complete:

      g              e
   c              c             c
      f              d

a              a             a

      e                            e
   b              b             b
      d                            d

The perfect tree is completely filled, the full tree is a perfect tree where the bottom level is partially filled, and the complete tree is a full tree where the bottom level has to be left oriented.

Tom Gunn 1,164 Practically a Master Poster

can you explain why is that required?

I always figured that it is because type names can consist of more than one token, like sizeof(long double) , but variable names are always one token. The parentheses make parsing multiple tokens easier. I cannot think of a good place where the behavior would change between sizeof(long double) and sizeof long double if the parentheses were optional, but C's syntax is wacky enough that I am sure there is one. ;)

Tom Gunn 1,164 Practically a Master Poster

And by the way, when can one be sure about
anything, except math. Isn't everything based on assumption?

I prefer to err on the side of caution. If I have to make an assumption, it is an assumption that things will be worse than expected, not better. Experience has proven that to be a good assumption. :)

Tom Gunn 1,164 Practically a Master Poster

Maybe but it is probably good enough for this experiment.

If you have to say 'probably', it is not a safe assumption to make. ;)

Tom Gunn 1,164 Practically a Master Poster

just pass 2d vector and use only its column?

The function being called is from wxMathPlot, and wxMathPlot is a third party library. It is a good assumption that he either does not have the code to change, or rightfully thinks that changing the code is a really bad idea.

Tom Gunn 1,164 Practically a Master Poster

outputs number from 10000000000 to 99999999999

If you are happy with that result, then OK. But do not expect the same quality of random numbers that a 64 bit generator would have. All you are doing is taking the small period of rand and throwing it into a larger type. The period is not changing, and the distribution is probably going to be much worse.

Tom Gunn 1,164 Practically a Master Poster

A little searching will always help. There is already a thread for this.

Just use the code it shows there for generating a random number between a range, and use a range of 10000000000 to 99999999999.

1) Seed random number
2) use rand()/RAND_MAX * (max-min) + min;

On 32 bit systems int is usually capped somewhere around 2,147,483,647. Visual Studio is at least one popular compiler that caps RAND_MAX at the minimum value of 32,767 even on 32 bit systems. For either of those suggestions to work, you would have to be on a 64 bit system with RAND_MAX being large enough to handle the upper limit of the range.

himgar, you probably need to look for a 64 bit random number generator. I do not know if gcc has one, but that is the default compiler that comes with Code::Blocks, so it should help you get started. You can use the long long data type for gcc to hold the value once it is generated.

Tom Gunn 1,164 Practically a Master Poster

Normally you just pass the object and the compiler does the rest. No special syntax is needed:

#include <iostream>
#include <vector>

void PrintAll(std::vector<int> const& v)
{
    std::vector<int>::const_iterator x = v.begin();

    while (x != v.end()) std::cout << *x++ << '\t';

    std::cout << '\n';
}

int main()
{
    std::vector<std::vector<int> > v;

    for (int x = 0; x < 3; ++x)
    {
        v.push_back(std::vector<int>());

        for (int y = 0; y < 5; ++y)  v.back().push_back(y);
    }

    for (int x = 0; x < 3; ++x) PrintAll(v[x]);
}

The problem you have is incompatible types. vector<double> is not compatible with vector<float>, and vector<double> is not compatible with vector<time_t>. There is no way around copying the values into a new vector with whatever explicit or implicit conversions are needed. Your working code is the answer if you cannot change the types of the vectors to match.

Tom Gunn 1,164 Practically a Master Poster

You can use std::sort with a STL container, like a vector or a list.

sort() uses random access iterators, so it will not work on a list. STL lists use bidirectional iterators, but they also support their own sort method.

Tom Gunn 1,164 Practically a Master Poster
int c_hrs1 , c_hrs2 , c_hrs3 , c_hrs4;
    float gpa_1 , gpa_2 , gpa_3 , gpa_4;

    int total_c_hrs= c_hrs1+c_hrs2+c_hrs3+c_hrs4;
    float cgpa= ((c_hrs1*gpa_1)+(c_hrs2*gpa_2)+(c_hrs3*gpa_3)+(c_hrs4*gpa_4))/total_c_hrs;

This will not work because all of those variables used in initializing total_c_hrs and cgpa have not been initialized. You should move the second two lines to after all of the input.

cout<<"Please enter you GPA in course 4: ";
    cin>>gpa_4;
    cout<<"Please enter the credit hours for course 4:";
    cin>>c_hrs1;

Copy/paste coding can be dangerous. ;) You forgot to change c_hrs1 to c_hrs4, which leaves c_hrs4 uninitialized in the calculation of total_c_hrs and cgpa.

It doesnt even display the last cout>>

If you are using cin.get() to keep the console window open then the last cout would happen too fast for you to see. But a terminating line break is a good idea anyway.

operator<< trims leading white space and stops reading on white space by default, so there will be a '\n' character still sitting in the stream for cin.get() to read, like firstPerson said. But another cin.get() is just a hack to fix this specific problem. If there is more than one character at the end of the stream, the same thing will happen. You can fix the problem generically like this:

cin.ignore(1024, '\n');

This reads and discards up to 1024 characters or until '\n' is found. It should clear the stream out so that the next cin.get() will block. 1024 is an arbitrary number though, numeric_limits<streamsize>::max() is a better …

Salem commented: Many fine points +36
Tom Gunn 1,164 Practically a Master Poster

oh so when loop see \n getchar() reads it and discards then quit the loop ?

The loop does not see '\n' until getchar() reads it, and by the time getchar() reads '\n', it has been extracted from the stream. So when the loop ends by comparing with '\n', the '\n' will not be read by the next input call.

Tom Gunn 1,164 Practically a Master Poster

'Discard' in this case means that the character is extracted from the input stream so that the next read will return the character after it or EOF. getchar() always extracts a character if it can, so if '\n' is next in line, getchar() will remove it from the stream and return it to the program.

The ignore pattern while(getchar() != '\n') continue; discards all characters up to and including the first '\n' because before the loop can test the result against '\n', getchar() first has to extract it from the stream. If you do not want to ignore the '\n', it has to be pushed back onto the stream:

int c;

while ((c = getchar()) != '\n' && c != EOF)
{
    continue;
}

if (c == '\n')
{
    // push the line break back onto the stream
    if (ungetc(c) == EOF)
    {
        // could not push the character back
    }
}
Tom Gunn 1,164 Practically a Master Poster

Characters are really small integers. '0' is a convenient symbol for the value 48. If you add 1 to 48, you get 49. And 49 is the actual value of the character '1'. Because '0' is a symbol for 48, you can say '0'+1 and still get 49. You can take 49 and print it as an int to get 49, or print it as a char to get '1'. Cool, huh? The decimal digits are required to be contiguous, so you end up with this sequence:

???+1 = '0'
'0'+1 = '1'
'1'+1 = '2'
'2'+1 = '3'
'3'+1 = '4'
'4'+1 = '5'
'5'+1 = '6'
'6'+1 = '7'
'7'+1 = '8'
'8'+1 = '9'
'9'+1 = ???

Be warned! The only characters that have any kind of order specified by C++ are the characters '0'-'9'. If you try to do something like 'a'+1, it is not guaranteed that the result will be 'b'.

Be warned again! ;) For simplicity I used 48 and 49 as examples of the underlying value for '0' and '1', but that is not guaranteed either. The actual value of a character depends on the character set being used. '0' and '1' are 48 and 49 for the ASCII and Unicode character sets, but there are others out there that do not use the same values, like EBCDIC.

Summary: Characters are small integers, you can do arithmetic on them just like on ints and get a different character in the …

Tom Gunn 1,164 Practically a Master Poster

You have the right idea, but there are a few problems in the details:

vector <string > string;
vector <int> int;

Naming your variables the same as types is not a good idea. Most of the time it will not work the way you want.

tranform(string.begin(), string.end(), int.begin(), atoi);

First, atoi() does not work on C++ string objects. You need to define another function that does. Second, transform() does not insert new items onto the destination. This call will fail because the int vector does not have room.

Compare your code with this:

#include <algorithm>
#include <stdexcept>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>

int StrToInt(std::string const& s)
{
    std::istringstream iss(s);
    int value;

    if (!(iss >> value)) throw std::runtime_error("invalid int");

    return value;
}

int main()
{
    std::vector<std::string> vs;
    std::vector<int> vi;

    vs.push_back("1");
    vs.push_back("2");
    vs.push_back("3");
    vs.push_back("4");
    vs.push_back("5");

    std::transform(vs.begin(), vs.end(), std::back_inserter(vi), StrToInt);

    std::vector<int>::const_iterator x = vi.begin();
    int sum = 0;

    while (x != vi.end()) sum += *x++;

    std::cout << "Sum: " << sum << '\n';
}

String streams are a good way to convert between strings and other types because most of the work is already done for you. And when you want transform() to add new items, the back_inserter uses a call to push_back() instead of just assigning to an index.

Dave Sinkula commented: This will be a good post to refer to in the future (but I've come to expect that). +26
mrnutty commented: Good job +2
Tom Gunn 1,164 Practically a Master Poster

Recursive functions should be used as sparingly as possible as they are extremely slow...

Potentially slow. Compilers do not have to do a function call mechanism with the usual stack frame setup that has the lion's share of overhead. For some tail recursive functions, compilers can easily optimize them into iteration and there is no speed difference at all. The overhead of recursion is not usually enough to be a deciding factor, but the risk of stack overflow should always be considered.

Recursion should be used when it makes sense to do so. But when it makes sense depends on things like how much complexity is reduced by switching from iteration to recursion, how much risk of stack overflow there is, whether you need to break out of the recursive loop, and speed/memory usage.

For say, fibonacci sequence, you can immediately model the function by applying the direct (recursive) definition while the iterative version will surely catch your brain for at least 2-3 minutes (if you are a beginner)

Then those 2-3 minutes are time well spent. :D Unless previous results are cached, the recursive algorithm for calculating the fibonacci sequence is very inefficient. If you are a beginner, you probably will not think about this, and the 2-3 minutes of catching your brain will save you from using a really bad algorithm. ;)

Tom Gunn 1,164 Practically a Master Poster

Most of the time when a programmer prints a char*, he wants a string to be printed, not the address. cout assumes that is what you want and to get around it, you need to cast to a different pointer type. void* is a good choice because an object pointer can be cast to void* safely:

#include <iostream>

int main()
{
    char const* p = "string";

    std::cout << p << '\n'
              << (void*)p << '\n';
}

On a side note, this is the same as how printf works with the %p modifier. To be 100% safe, the pointer should be cast to void* because that is the type %p expects:

#include <cstdio>

int main()
{
    char const* p = "string";

    std::printf("%s\n%p\n", p, (void*)p);
}
Salem commented: Nice, so few people get the %p thing right. Though the C++ would have been better with a reinterpret_cast +36
Tom Gunn 1,164 Practically a Master Poster

Member access through pointers is different. If you try to do something like T1.reveal() , you would get that error because the dot operator does not work with pointers. You need to dereference the pointer first, then do the access:

(*T1).reveal();

Because it is such a common operation, there is a special operator to make the whole thing simpler:

T1->reveal();
Tom Gunn 1,164 Practically a Master Poster

Not pretty, so if anyone out there have a more clean way of doing it, please reply

With a recursive algorithm that is about the best way to do it. A cleaner and more powerful way is by writing an iterator for your BST. Traversal with iterators can be stopped and started without forcefully breaking out of a recursive call chain, so the algorithm is more elegant:

Node* Pheno::GetNode(long const i)
{
    if (i < 0 || i > size()) return NULL;

    Iterator current(begin());

    while (current != end() && --i >= 0) ++current;

    return current->Node;
}

But that means you have to write a lot of framework to support iterators, and it is more complex than recursive traversal. If you are interested in learning more, a good place that describes one way is here.

Tom Gunn 1,164 Practically a Master Poster

Now I am aware that C++ has the try/catch option like Java, but what do I have available in C?

C can simulate exception handling with the setjmp.h library, but that is kind of an advanced C thing. ;) Usually error handling in C is done by receiving error codes as the return value from functions, as output parameters to functions, or with a global error code object:

#include <stdio.h>

#if defined(_MSC_VER)
#define FLUSH(strm) ((strm)->_cnt = 0)
#else
#define FLUSH(strm) FlushInputStream(strm)
#endif

void FlushInputStream(FILE *strm)
{
    int ch;
    do ch = getc(strm); while (ch != '\n' && ch != EOF);
}

void PrintError(char const* msg, FILE *istrm)
{
    fputs(msg, stderr);
    FLUSH(istrm);
}

/* error handling with a return code */
int GetInt1(int* value)
{
    return scanf("%d", value) == 1 &&
           0 < *value && *value < 6;
}

/* error handling with an output parameter */
int GetInt2(int* error)
{
    int value = 0;

    if (!(scanf("%d", &value) == 1 &&
          0 < value && value < 6))
    {
        *error = 1;
    }

    return value;
}

static int errorCode;

/* error handling with a global error object */
int GetInt3()
{
    int value = 0;

    errorCode = !(scanf("%d", &value) == 1 &&
                  0 < value && value < 6);

    return value;
}

int main()
{
    int value;
    int error;

    /* error handling with a return code */
    if (GetInt1(&value)) printf("read %d\n", value);
    else PrintError("GetInt1 failed\n", stdin);

    /* error handling with an output parameter */
    error = 0;
    value = GetInt2(&error); …
Tom Gunn 1,164 Practically a Master Poster

I get a warning just because I made a double topic, and had no idea about how to move the other one.

You can probably go to the post you want to move and click the Flag Bad Post link to report it. That will get the moderators' attention, and because it was an accident and you reported it yourself, they should not give you a warning.

Tom Gunn 1,164 Practically a Master Poster

Is it possible to seek a map while saved in a file.How do you suggest i make windows for the file?

You can seek in a file, and load from a file into a map. Unless you want to use a third party external B-tree library, that is probably as good as it gets. As for the window idea, it is nothing more than looking at a smaller part of the file at once, and loading another small part when searching leaves that view.

The main question now is,how do i ensure great perfomance when loading an STL map of a billion pages into memory.

There is no such thing as great performance working with huge files or huge amounts of files that I know of. How do you know the performance is not acceptable when your code has not worked with that amount yet? Are you sure you are not optimizing prematurely?

Tom Gunn 1,164 Practically a Master Poster

Am looking at up to a billion,i haven't such data yet,but i would like to know if someone has an idea on how it will perform

The STL map class has performance guarantees that match a balanced search tree. The height will be small for a billion items, like 2*log(n) for a red black tree, so lookup is quick. When lookup is quick, insertion and deletion will be quick too.

Really all you need to worry about with performance is paging and locality of reference. If there are a lot of items in memory that are in different pages, the computer will be swapping pages in and out and that slows memory accesses. If there are so many items that RAM cannot hold it all, the whole machine can slow down as memory gets swapping and out of virtual memory.

especially when trying to load from a file.

Files are slow. There is no getting around that. :) If loading the whole file is too slow, you can use windows into the file and only process part of it at any time. Just make sure that the file format makes seeking possible.

Tom Gunn 1,164 Practically a Master Poster

I think a more important question than how to make a function recursive is why should it be recursive? Recursion is great, but it has pitfalls. If the recursion goes too deep, you risk a stack overflow with no way to intercept the exception. Hard crashes like that are very very bad.

The best use of recursion when it makes a complex iterative algorithm shorter and easier to understand. If the difference between iterative and recursive is minimal, there is no reason to add the risks and potential inefficiencies of recursion. Compare and contrast:

int FindSumIterative(vector<int> const& v)
{
    int sum = 0;

    for (int x = 0; x < v.size(); ++x) sum += v.at(x);

    return sum;
}

int FindSumRecursive(vector<int> const& v, int x=0)
{
    if (x == v.size()) return 0;

    return v.at(x) + FindSumRecursive(v, x+1);
}

Both functions do the same thing, are called the same way, and have the same result with the same amount of code complexity. But the iterative version is safer for large vectors because the recursive version can cause a stack overflow. It might also be inefficient because of overhead from calling functions and storing all of the stack frames in memory.

There is no benefit to using recursion because the iterative algorithm is just as simple and much safer for a linear algorithm. A better use of recursion is for something like quicksort where the iterative algorithm is much more complex than the recursive one, and for a good pivot …

Tom Gunn 1,164 Practically a Master Poster

Pass by reference is a pointer under the hood.

There is no hood to look under. C does not have pass by reference, only pass by value. Pass by reference is faked in C by passing pointers by value and using indirection to get to the object.

A side note : one of the main reason call by reference was created is
because passing a class object by value is expensive.

You can think of Pass by reference like a pointer in disguise.

I think you are talking about C++, but even in C++, the main reason references are part of the language is to support operator overloading. They are also a convenient way to make output parameters, but that is a side effect of the original goal.

Tom Gunn 1,164 Practically a Master Poster

I do not use Code::Blocks, so I will leave that answer to someone else. But there should be a setting somewhere where you can add .lib files for linking. Worst case you probably have a place where you can type gcc command line switches. Adding -lGdi32.lib should link with the right library.

Here is a link to the gcc manual for linking options:
http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Link-Options.html#Link-Options

Tom Gunn 1,164 Practically a Master Poster
int a,b,c;
cout <<"average is:"<<average(a,b,c);
cin >>a>>b>>c;

I always wonder how it makes sense to do the work before getting the values when the work depends on the values. Try this:

int a,b,c;
cin >>a>>b>>c;
cout <<"average is:"<<average(a,b,c);

Also, the function is not defined to take 3 arguments. This will fit your call better:

double average(int x, int y, int z)
{
    return (x+y+z)/3;
}
Tom Gunn 1,164 Practically a Master Poster

qsort() what your looking for.

But be careful with the example from that page. Subtracting ints like that without any kind of underflow test has some risk. The safe way is easier to understand too:

#include <stdio.h>
#include <stdlib.h>

int Compare(void const* a, void const* b)
{
    int const* first = a;
    int const* second = b;

    if (*first == *second) return 0;
    else if (*first < *second) return -1;
    else return 1;
}

int main()
{
    int a[] = {0,4,6,2,8,7,1,6,8,4,3,2,8,5,9};
    size_t const sz = sizeof a / sizeof *a;
    size_t x;

    for (x = 0; x < sz; ++x) printf("%2d%s", a[x], x < sz - 1 ? "" : "\n");
    qsort(a, sz, sizeof *a, Compare);
    for (x = 0; x < sz; ++x) printf("%2d%s", a[x], x < sz - 1 ? "" : "\n");

    return 0;
}
Salem commented: Nice +36
Tom Gunn 1,164 Practically a Master Poster

Now you can get the username by using scanf like this:

scanf("%s", username);

More info about character arrays and the scanf-function can be found at the links which are at the bottom* of this post.

I have not seen any references that talk about reading strings the right way with scanf(). It's always the same "%s" format string, even though making it overflow safe is super easy:

scanf("%49s", username);

I think a big reason why fgets() is recommended is because everyone teaching scanf() uses it unsafely. I'm sure fgets() would be evil too if everyone learned and used it like this:

char username[50];

/* Unsafe code */
fgets(username, INT_MAX, stdin);

it's like using a chainsaw with no safety guards.

Welcome to C. :D There are no safety guards here, and scanf() is kind of low on the list of great ways to screw yourself over.

use "fgets()" instead.

That is not much better than saying void main is evil without explanation. Using fgets() to replace scanf() is good advice to avoid scanf() pitfalls, but then the same people who give the advice go on to recommend sscanf() for parsing the string... Imagine how confusing that would be to a beginner since scanf() and sscanf() are so similar. ;)

tux4life commented: Some other interesting stuff about C :P +20
jephthah commented: bork bork bork :) +15
Nick Evan commented: - that's another bookmark +27
Tom Gunn 1,164 Practically a Master Poster

In general, passing by value means that a copy of variable is made with the same value and passing by reference means the variable object itself is passed. You can change the value all you want with pass by value, but the original object is not changed. With pass by reference any changes to the passed variable also change the original. C does not support passing by reference, but you can fake it with pointers:

#include <stdio.h>

void CallByValue(int x)
{
    x = 123;
}

void CallByFakeReference(int* x)
{
    *x = 123;
}

int main()
{
    int x = 0;

    printf("Before CallByValue: %d\n", x);
    CallByValue(x);
    printf("After CallByValue: %d\n\n", x);

    printf("Before CallByFakeReference: %d\n", x);
    CallByFakeReference(&x);
    printf("After CallByFakeReference: %d\n", x);

    return 0;
}

Faking call by reference is done by passing the address of an object and then accessing the value through indirection. That way you can get to the original object and make changes, but the address is still passed by value.

tux4life commented: I appreciate you for taking the time to answer this question in a more correct way than I did :P +20
Tom Gunn 1,164 Practically a Master Poster

That's actually not entirely true. It only works with integral-data types, which means that in addition to static const int also unsigned and char types are permitted to be declared and defined in the class as static const

It is true when you read 'int' as integer type. I had a brain fart and forgot that you guys do not interpret normal prose and need everything spelled out in standardese. ;)

Tom Gunn 1,164 Practically a Master Poster

Static fields in a class are really external declarations. You need to define the field outside of the class for it to exist:

#include <iostream>

class A
{
public:
    // external declaration
    static double ratio;
};

// actual definition
double A::ratio;

int main()
{
    A a;

    a.ratio = 1.76;
    std::cout << a.ratio << '\n';
}

If you remove the actual definition, building the code will give you an unresolved external object error. For static ints that are const, you can initialize them inline and that counts as a definition. But until the next C++ standard comes out, that only works with const int static fields:

#include <iostream>

class A
{
public:
    static const int Max = 50;
};

int main()
{
    A a;

    std::cout << a.Max << '\n';
}
Tom Gunn 1,164 Practically a Master Poster

Did you link with Gdi32.lib, or just include windows.h? All headers do is declare names so that the code will compile. Compilation and linking are two different steps in the build process. If you declare a name and do not define it, the code will compile but fail to link because there is no actual thing attached to the name. That is what an undefined reference means. You are referencing something in your code that does not exist.