Tom Gunn 1,164 Practically a Master Poster

I have problems understanding the code quickly whenever I need to go back to it after some time.

That is normal, and it is why code should be written as simply as possible without sacrificing functionality, and why comments that describe why you wrote something the way you did are critically important.

I started about a month ago , without planning much , and now I am struggling to understand the logic.

You should plan enough to understand how the application is supposed to work. The details can be ironed out during development, but the overall vision should not change much. Planning is even important for conversions because the target language might have better ways of designing the code. The result will probably be completely different from the original even though they both do the same thing. A straight line by line conversion of VB6 to C# is not a good idea, if you get my drift. ;)

Today I had a talk with a user and things cleared up much more .

I always make sure that clients are involved in the development process from start to finish, both to keep myself informed about their needs and to keep them informed about what I am doing. That way things do not get too far off track and everybody understands the vision of the final product.

I don't feel confident in my programming abilities because I can't predict when I'll finish a project .

Nobody can predict …

majestic0110 commented: Good answer! +6
Tom Gunn 1,164 Practically a Master Poster

The seed for each thread is independent. You need to call srand() in the Draw() function to reseed for each thread.

hmortensen commented: Simple and accurate, information. :) +1
Tom Gunn 1,164 Practically a Master Poster

so shouldn't the assignment read S[i-1]='\0'?

At the end of the loop, i is indexing the right array element for placing '\0'. If you subtract 1, you will overwrite the last character. This problem is easier to see if you change the loop to stop on a new line:

for (i = 0; (c = getchar()) != '\n'; ++i)

Otherwise by putting the assignment you gave me in the body of my for loop every element of array S will be initialized to NULL?

That is why I did not put the assignment in the body of the loop. I put it after the loop, just before the call to reverse().

Tom Gunn 1,164 Practically a Master Poster

In the reverse() function, there is a test for if(*str) . That means the function is expecting str to be a string. Strings in C are sequences of characters where the last character is a sentinel with the value of 0. This value is not added automatically, you have to insert it because you are manually building a string:

S[i] = '\0';
reverse(p1);
Tom Gunn 1,164 Practically a Master Poster

Your code has three immediate problems:

  1. The i variable is not initialized to 0.
  2. getchar() is only called once, not every time the loop iterates.
  3. The array is not terminated with a '\0' character.

If you fix those things, it should work.

Tom Gunn 1,164 Practically a Master Poster

Containers are implemented using data structures, and the implementation of a container is not usually specified, so containers are a more abstract concept than data structures.

Tom Gunn 1,164 Practically a Master Poster

scanf() does not treat new line characters as different from other white space. To get line oriented input you should use something like fgets(). sscanf() is an easy way to parse the line fgets() reads:

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

int main()
{
    char line[BUFSIZ];
    float dollars;

    while (fgets(line, sizeof line, stdin) &&
           sscanf(line, "%f", &dollars) != 1 ||
           dollars <= 0)
    {
        printf("invalid amount. please enter a positive amount: ");
        fflush(stdout);
    }

    printf("Received %f\n", dollars);

    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

Then terminate it there. :) If you do not do something to break the line of execution, you will step over each statement in order. Try this to kill the program from the else clause:

else
{
    system("pause");
    return 0;
}

This matches your end of main code, but I do not recommend the habit of using system() for something mundane like pausing execution. It is too risky because system() is easily turned to the dark side by replacing the pause program with something malicious. A better way to do the same thing uses the equivalent of getch():

else
{
    cout << "press any key to continue . . .";
    getch(); // not portable
    return 0;
}

And the portable way is only a bit less convenient by forcing you to type [Enter] instead of any key right away:

else
{
    cout << "press [Enter] to continue . . .";
    cin.get();
    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

Try combining the tests like this:

int code;

while ((code = scanf("%f", &fDollars)) != 1 || fDollars <= 0)
{
    printf("invalid amount. please enter a positive amount: ");
    fflush(stdout);

    if (code != 1) FLUSH_STDIN();
}

Further reading for extra credit can be found here.

Tom Gunn 1,164 Practically a Master Poster

Your isbal() function only tests the root, it should recursively test every node because there are trees that can be unbalanced but still have a height difference of less than 2 from the root. The definition of height balanced is that when every node is tested as an individual tree, it will be balanced according to the height rule.

Tom Gunn 1,164 Practically a Master Poster

Maybe something like this?

String^ RClammer = "]";
String^ BigLine = "aaaaaaaa]aaaa";
int pos = 0;

while ((pos = BigLine->IndexOf(RClammer, pos)) != -1)
{
    BigLine = BigLine->Insert(++pos, " ");
}

Do not forget that managed strings are immutable. The Insert method does not modify the string, it returns a new one.

Tom Gunn 1,164 Practically a Master Poster

IndexOf() returns -1 if it cannot find the value.

Tom Gunn 1,164 Practically a Master Poster

You set the capacity of vector1 in the constructor, but not the size. vector1 is still an empty list, so the first order of business is adding all of the new lists to vector1 before trying to use them. The equivalent native code for that managed declaration would be:

vector<vector<string> > vector1;

vector1.reserve(1000);
Tom Gunn 1,164 Practically a Master Poster

The generic List class is in the System::Collections::Generic namespace, not the System::Collections namespace. Either use the full name or add a using directive to the namespace:

using namespace System::Collections::Generic;
Tom Gunn 1,164 Practically a Master Poster

compileerror:
syntax error : '>'

I do not have any problem with that declaration. Can you post a complete program that throws a syntax error so that I can test it on my end?

Tom Gunn 1,164 Practically a Master Poster

A 2D managed list of strings with an initial capacity of 1000 would be declared like this:

List<List<String^>^>^ vector1 = gcnew List<List<String^>^>(1000);

You can use typedef to make that simpler too. ;)

Tom Gunn 1,164 Practically a Master Poster

1) Using the getchar() function, you need to flush the input buffer to get rid of the newline character

As a corollary, fflush(stdin) is not the way to flush the input buffer because fflush() is only defined to work on output buffers. A portable way to flush is getchar() in a loop:

while (getchar() != '\n')
{
    /* no work to do */
}

If EOF is possible, add that to the condition:

{
    int c;

    while ((c = getchar()) != '\n' && c != EOF)
    {
        /* no work to do */
    }
}

The only problem with this loop strategy is when the buffer is empty, the loop will block until some characters are buffered. The end user will have to type an extra [Enter] before getting past the loop, and that can be surprising. I like to fix it by dipping into the stream internals, but that is not a portable fix. Use it with caution:

#if defined(_MSC_VER)
/* Visual C and derivatives */
#define FLUSH_STDIN() stdin->_cnt = 0;
#else
#define FLUSH_STDIN() while (getchar() != '\n')
#endif

2) In your original code posting, you used void main() - this is bad, very bad.

I have only seen one OS mentioned that fails when void main() is used, and both compilers in that article warn about it. Not recommended, definitely. void main() is not portable and technically undefined when the compiler does not support it, so it should be avoided on all hosted …

kvprajapati commented: Thanks Tom to share your knowledge. Good suggestion but I still recomend int main() +17
tux4life commented: I still prefer to use the standard about the return type of main, but you're right about the void main() :) +23
Tom Gunn 1,164 Practically a Master Poster

i have wriitten the following code and checked for five levels its working fine. but i am not comparing the values of the nodes.

is it the correct way ?

That should work. So your definition of a strict tree is where each node has either 0 or 2 children?

Tom Gunn 1,164 Practically a Master Poster

but i dont understand how can we ensure a binary tree is strict just by checking only root and its children .

That was my mistake. I posted an incomplete example. That function is supposed to be recursive. I will try again:

int IsStrictRoot(struct node* root)
{
    return !((root->left && root->left->dat >= root->dat) ||
             (root->right && root->right->dat <= root->dat));
}

int IsStrictBst(struct node* root)
{
    if (root)
    {
        return IsStrictBst(root->left) && 
               IsStrictBst(root->right) && 
               IsStrictRoot(root);
    }
    else return 1;
}

The rule for a strict binary search tree is that the left node has a smaller value than the root and the right node has a larger value than the root. That is assuming no duplicate values are allowed in the tree. The comparison can be changed to support that duplicates easily. :)

for the tree to be strict does it must be a BST?

For a tree to be strict you need to define what strict is. A BST has a node order requirement, but if you have a binary tree that is not a BST, there has to be some ordering that makes it strict, or the design of the tree allows more than one child node and you want to allow only up to two at run time.

but you checked it reverse.

It is a reverse test for failure. Here is the truth table for that comparison:

I = Invalid
V = Valid
* = NULL

   | * | V | I |
tux4life commented: Is there maybe something you don't know? :P +22
Tom Gunn 1,164 Practically a Master Poster

When you say 'strict binary tree', you mean that each node has only two links? You can do it, but if your node struct only has left and right pointers, it is kind of pointless to do a test that is guaranteed at design time. ;)

If you mean to test for a strict binary search tree, you need to do a key value relation test:

int IsStrictBst(struct node* root)
{
    if (root)
    {
        if ((root->left && root->left->dat >= root->dat) ||
            (root->right && root->right->dat <= root->dat))
        {
            return 0;
        }
    }
    else return 1;
}
Tom Gunn 1,164 Practically a Master Poster

Is this possible that instead of typing - program.week[0].workout[0].exercise[0].exerciseName
everytime I want to access an element.
That I can access the elements of the most nested struct via a pointer.

Yes. If you have an object, you can have a pointer to it:

#include <stdio.h>

struct A
{
    struct B
    {
        struct C
        {
            int dat;
        } c;
    } b;
};

int main()
{
    struct A a;
    struct C* pc = &a.b.c;

    pc->dat = 123;
    printf("through struct pointer: %d\n", pc->dat);
    printf("direct access:          %d\n", a.b.c.dat);

    return 0;
}

Is that what you were trying to do?

Tom Gunn 1,164 Practically a Master Poster

Good start! C is different in a few ways though. Declarations need to be the first thing in a block unless you are compiling under C99, so your C code will not compile with most compilers.

printf("N %2.2f, factorial %2.2f \n" ,i,factorial(i));

You need to be very careful with printf() and scanf() format strings because mixing up types can give weird results. In this one, the first modifier should be %d, not %2.2f, because i is an int.

char wait;
printf("Enter to exit");
scanf(&wait);

scanf() is just like printf() in that it requires a format string. Your code will compile because &wait is the right type, but anything could happen because &wait does not point to a string. The whole thing should look like this:

/* unnamed block so wait can be declared */
{
    char wait;

    printf("Enter to exit");

    /* flush the stream if you do not print '\n' */
    fflush(stdout);
    scanf("%c", &wait);
}

But in both your C and C++ code, that whole wait thing is more verbose than it needs to be. In C++ you can do cin.get(); and in C you can do getchar(); for the same effect as a char variable and operator>> or scanf().

Using the same style, I would write the code like this:

#include <stdio.h>

double factorial(int n);

int main()
{
    int i;

    printf("N          Factorial\n");
    printf("--------------------\n");

    for(i = 15; i > 0; --i)
    {
        printf("%-11d%.2f\n", i, factorial(i));
    }

    printf("Enter to exit");
    fflush(stdout);
    getchar();

    return 0;
}

double
Grn Xtrm commented: Thanks for the help +1
Tom Gunn 1,164 Practically a Master Poster

CArray<> is an MFC class, right? The problem is almost surely going to be in your code, not the code of CArray<>. Can you post a small program that has the same error so that everyone can see how you are using the class?

Tom Gunn 1,164 Practically a Master Poster

Move left up 1, move end down 1. If left == mid || right == mid then stop.

You can also do away with the middle variable because that case is identical to when left == right .

Tom Gunn 1,164 Practically a Master Poster

Technically all you need is a stack to store the nodes needed to get back to the nearest root and traverse the other subtree. So the memory cost is O(logN), not O(N), because the size of the stack has at most as many nodes as height(tree) .

The only way I can think of to traverse without using extra storage is destructive and less efficient. Let us say you want to do an in order traversal. Start with the root and whenever the left node is not a null pointer, rotate right. When the left node is a null pointer, visit the node and move to the right, then keep doing the same thing until the node is a null pointer:

while (node)
{
    if (node->left) node = RotateRight(node);
    else
    {
        visit(node);
        node = node->right;
    }
}

This algorithm is less efficient because of the rotations, and it is destructive because the structure of the tree changes after the traversal into the worst case of a BST. However, the good news is that this is also the first step of a perfect balancing algorithm called DSW. If you want, after the traversal you can add the second step and get a better tree than you probably started with. :)

Another good use for this traversal is destroying the tree and freeing nodes. Because the nodes are all being destroyed anyway, the structure does not matter anymore.

Tom Gunn 1,164 Practically a Master Poster

can you show me the codes? ^^

No. This is a simple homework problem, and Daniweb's homework policy is not to give code examples without proof of effort.

Tom Gunn 1,164 Practically a Master Poster

Start by making a subset of the pattern:

*0000000*
0*00000*0
00*000*00
000*0*000

This is easier to visualize with two counters to mark the stars. After you get this one, you can add the central star that does not ever move.

Tom Gunn 1,164 Practically a Master Poster

I understand both of those facts but I thought that here, I'm only accessing the private members via the friend class, which I thought would be okay.

Making a friend to a class does not make the private members public. FriendClass can access UnrelatedClass' private members, but those private members are still private. Users of FriendClass cannot access them any more than non-friends of UnrelatedClass can.

Is there any ugly hack I can use to get around this?

There are a few, and none of them are recommended. But since you asked for an ugly hack, I will show you one. Use it at your own risk:

void DerivedClass::Foo()
{
    *reinterpret_cast<float*>(m_hUnrelatedClass) = 2.0;
}

This hack assumes that CHandle<> is a smart pointer. Do whatever you need to do to get the address of the UnrelatedClass object pointed to by the field.

It works like this: UnrelatedClass has no virtual members, which means the object structure is easier to predict with some accuracy. There is only one field and it is the field you want, so you can assume that for an object of UnrelatedClass, &obj.fNumber is the same address as &obj. If that is true and you cast that address to float*, you can access fNumber even though it is private.

Tom Gunn 1,164 Practically a Master Poster

be warned its over 1600 lines of code

The problem is as we said at first. You are using things before they are declared. The cls() function is one example. You use it in the definition of the Pet class, but it is declared after the Pet class definition. Think of the declare before use rule as being top-down. If you flatten out your code into one file, the declaration has to be above the first use.

Tom Gunn 1,164 Practically a Master Poster

You guys make it sound so easy...........

It only sounds easy because we have learned by making the same mistakes before. I still mistype counters all the time, so I know how to find it and prevent it. ;)

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

Your bug is the reason why I do not use i and j for counters. ;) They look so much alike it is easy to mistype and not be able to see it. In the code above you increment i instead of j. x and y are easier to tell apart. Compare this with your code and put the bug back in to see if it is easier to find with different counter names:

void drawShape(int nrR, char a, char b)
{
    for (int x = 1; x <= nrR; x++)
    {
        for (int y = 1; y <= (nrR - x + 1) ; y++) cout << b;
        for (int y = 1; y <= (2 * x - 1); y++) cout << a;
        for (int y = 1; y <= (nrR - x + 1) ; y++) cout << b;
        cout << endl;
    }

    // Bottom row
    for (int x = 1; x <= (2 * nrR + 1); x++) cout << b;
    cout << endl;
}
Tom Gunn 1,164 Practically a Master Poster

You can call a function provided it has already been declared:

void afunction();

class example {
    public:
    example();
    ~example();
    
    void doSomthing() {
        afunction();
    }
};

void afunction() {
    //do more things
}

A definition is also a declaration, so you can move the definition above your class definition for the same effect:

void afunction() {
    //do more things
}

class example {
    public:
    example();
    ~example();
    
    void doSomthing() {
        afunction();
    }
};

Note the semicolon at the end of the class definition that I added. That is important, and forgetting it usually causes incomprehensible errors. ;)

Tom Gunn 1,164 Practically a Master Poster

Unless the lines are formatted to have exactly the same length, getline() is really the best way to do what you want, even if you throw away most of the lines:

for (int x = 0; getline(fs, line) && x < selectedLine; ++x)
{
    // all work in condition
}

if (!fs)
{
    cerr << "could not load requested line\n";
}
Tom Gunn 1,164 Practically a Master Poster

but what if I want the hexadecimal 199 to be displayed in binary?

printf() does not have a conversion to binary. The C++ library has a bitset<> class that will indirectly do it for you, but you need to use cout to print directly, or manually convert to a string for printf():

#include <iostream>
#include <limits>
#include <bitset>

int main()
{
    std::cout << std::bitset<std::numeric_limits<int>::digits>(0x199) << '\n';
}

The other alternative is manually converting the number to a binary string. If you search this forum you can find tons of threads about how to do it that way.

kvprajapati commented: I appreciate your knowledge. +13
tux4life commented: Great post, keep up the good work Tommy ! :) +21
Tom Gunn 1,164 Practically a Master Poster
printf("name=%s",b1.name);
printf("\nname=%s",&b1.name);

Technically the second statement is undefined behavior because the %s modifier expects a char pointer, but you pass a pointer to a char pointer. The types do not match. In reality it will probably work because b1.name and &b1.name should both evaluate to the same address even if the types are different. printf() will get the address and cast it to the expected type, so both printf() calls print a char pointer using the same address.

But it is not guaranteed to work, so you should not use the second printf() statement.

Tom Gunn 1,164 Practically a Master Poster

I think it is better to learn more about C++ than the basics first. You can learn about writing game logic without adding the complexity of graphics to your program. If you start learning how to make graphics with incomplete knowledge of C++, you will end up struggling with the language and the graphics API at the same time. That makes learning harder.

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

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

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

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

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

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

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.

Tom Gunn 1,164 Practically a Master Poster

Why does the calling function does not reflect the change done in the called function? despite the fact that I pass the variable via pointer.

Passing by pointer only means that the pointed to object can be changed. If you want to repoint the pointer to another address, it has to be passed by pointer too because pointers are also passed by value:

#include <iostream>
using namespace std;

void foonochange(int *x) {
	int *y = new int(999);
	x = y;
}

void foochange(int **x) {
	int *y = new int(999);
	*x = y;
}

int main(void) {	
	int *x = new int(1);

	foonochange(x);
	cout << *x << endl;

	foochange(&x);
	cout << *x << endl;

	cin.get();
	return 0;
}

But this is C++, and C++ has pass by reference. You can pass a reference to the pointer and not worry about adding another explicit level of indirection:

#include <iostream>
using namespace std;

void foonochange(int *x) {
	int *y = new int(999);
	x = y;
}

void foochange(int*& x) {
	int *y = new int(999);
	x = y;
}

int main(void) {	
	int *x = new int(1);

	foonochange(x);
	cout << *x << endl;

	foochange(x);
	cout << *x << endl;

	cin.get();
	return 0;
}
Tom Gunn 1,164 Practically a Master Poster
main(int ac, char *argv[])

Even when you do not specify a return type, main returns int, but your main does not have a return value. If you do not return a value from main, a junk value is returned to the OS. Also, C99 does not support implicit int anymore, so you should be typing it explicitly to futureproof your code.

if(ac>1)
    {
          printf("Invalid number of arguments /n");
          exit(1);
    }

The test is backwards. :) If ac is greater than 1, it means there is an argument available.

else
    {
        int newpid;
        newpid=atoi(argv);
    }

newpid is declared in the else block, so it does not exist outside of that block. Whatever you do with newpid, it will go away when execution gets to the end curly brace for the else block. Also, argv is an array, so you need to specify which item in the array you want to convert to an int.

This code should help you get started. It is always a good idea to start with something small and test that it works before adding more complexity. Like a program to print the arguments and make sure you got that right before trying to spawn processes which is harder to debug:

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

int isInt(char const* p);

int main(int argc, char *argv[])
{
    int nProcesses = 0;
    int x;

    if (argc < 2)
    {
        fputs("usage: $prog {number of processes}\n", stderr);
        exit(EXIT_FAILURE);
    }

    if (!isInt(argv[1]))
    {
        fputs("integer argument expected\n",
MentallyIll5150 commented: Thanks! +1
iamthwee commented: Good explanation and carefully thought out. +22
Tom Gunn 1,164 Practically a Master Poster

Why ... T1 &var=T1(), T2 &var=T2()?

and not simply

.. T1 &var, T2 &var

does the appendix =T1() has an additional meaning?

If you have a function that takes 4 parameters, you have to provide all parameters when calling it:

#include <iostream>

void function(int a, int b, int c, int d)
{
    std::cout << a << '\t'
              << b << '\t'
              << c << '\t'
              << d << '\n';
}

int main()
{
    function();           // error
    function(1);          // error
    function(1, 2);       // error
    function(1, 2, 3);    // error
    function(1, 2, 3, 4); // ok
}

The additional code I added was default values for the parameters. With default values, if you do not provide enough arguments, the default values are used and the function looks like it is overloaded:

#include <iostream>

void function(int a=0, int b=0, int c=0, int d=0)
{
    std::cout << a << '\t'
              << b << '\t'
              << c << '\t'
              << d << '\n';
}

int main()
{
    function();           // ok
    function(1);          // ok
    function(1, 2);       // ok
    function(1, 2, 3);    // ok
    function(1, 2, 3, 4); // ok
}

For a template argument called T, T() is the default value for that type. So for T==int, T() is 0. For T==string, T() is "". The template I wrote says that all of the parameters with a template argument type have a default value of the template argument type. :)

Tom Gunn 1,164 Practically a Master Poster

I mentioned printf() and how the iostream library fixes the type safety problem. That is a good place to start, but it means that you will not be able to use format strings in the same way, and there will be lots of overloading for different types.

To be honest, I am not sure how I would solve this problem. Maybe after a day or two letting it simmer, I can give you a better answer. :)