Problem with structs and functions

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

Problem with structs and functions

Post by Taliesen »

This is a pretty basic question I think, but since I am new to programming I feel little shame in asking it. Basically I am trying to use a structure with functions and no matter what I try I can't get them to declare properly. This code is pretty ugly and all, but if someone has an idea as to what I am doing wrong.

Code: Select all

#include <cstdlib>
#include <iostream>

using namespace std;

//structures
typedef struct Tribe
{
    int Number;
    int Members;
    int Men;
    int Age;
}; 

int totalTribes;
//user-defined function declaration
int menuFunction(int a, int b, int c);
int tribalAssignment(Tribe Tribes[], int c);



int main(int argc, char *argv[])
{
    int menuChoice;
    Tribe Tribes[totalTribes];
           
    menuFunction(menuChoice, Tribes[totalTribes].Members, totalTribes);
    
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

int tribalAssignment(int b, int c)
{
    int y = 1;
    Tribe Tribes[totalTribes] = b[];
    int currentTribe = y;
    
    
        for(int iCount = 0; iCount <= c; iCount++)
        {
            Tribes[iCount].Members = 0;
            Tribes[iCount].Number = 0;
            Tribes[iCount].Men = 0;
            Tribes[iCount].Age = 1;  
            cout << "Tribe number    " << Tribes[iCount].Number << "    Tribe Members   " << Tribes[iCount].Members << endl;
              
        }  
}
    
int menuFunction(int a, int b, int c)
{
    
    cout << "Main Menu..." << endl;
    cout << "-------------------" << endl;
    cout << "       1. Change Number of People   " << b << endl;
    cout << "       2. Change Number of Tribes   " << c << endl;
    cout << "       3. Generate Tribal Assignment" << endl;
    cout << "       4. Quit..." << endl;  
    
    cin >> a;
    
    switch ( a )
    {
            case 1 :
                    cout << "How many people would you like to calculate?" << endl;
                    cin >> b;
                    menuFunction(a, b, c);
                    break;
            case 2 :
                    cout << "How many tribes would you like to calculate for?" << endl;
                    cin >> c;
                    menuFunction(a, b, c);
                    break;
            case 3 :
                    tribalAssignment(b, c);
                    break;
            case 4 :
                    return EXIT_SUCCESS;
                    break;
          
    }
    

   
    
}
This is in Dev-C++, the problem is in the line:
Tribe Tribes[totalTribes] = b[];

Someone try compiling it and you will see the error. The error it is giving me is: expected primary expression before ] token. I am new to c++ so I am having difficulty with understanding structs and functions and such.
bearSoft
Posts: 165
Joined: Fri Apr 01, 2005 9:55 pm
Location: Denmark

Post by bearSoft »

yes b[] is not valid
ur array b[] is not defined in the abowe snippet so i believe u wont get a better result with
Tribe Tribes[totalTribes] = b[0];
since b[0] is undifined
if u however hacked in and wrote
int b[0]=111;
Tribe Tribes[totalTribes] = b[0];
then i believe u would be able to compile

btw use better names for ur vars 'b' is not descriptive
Regards.
Tech: win98se| 320mb ram| abitbe6| 433mhzceleron| atiRadeon7000.64mb| soundblaster125| dx9.0b | devCPP | IRR 0.12.0 |
hybrid

Re: Problem with structs and functions

Post by hybrid »

Taliesen wrote:

Code: Select all

int tribalAssignment(Tribe Tribes[], int c);

int tribalAssignment(int b, int c)

int menuFunction(int a, int b, int c) 
Someone try compiling it and you will see the error. The error it is giving me is: expected primary expression before ] token. I am new to c++ so I am having difficulty with understanding structs and functions and such.
Now these are the problematic parts. First of all your forward declaration for tribalAssignment is better then the method head as it uses the correct type Tribe[]. But you don't want to pass the array! Pass a pointer to an array or a reference. That way changes will be done on your original array, not on a local copy. Thus, you won't need a local variable at all for assignment, use the parameter.
Also change menuFunction to pass the array not an int, otherwise you don't get access to the array from main.
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

Post by Taliesen »

Like I said I am kind of new, could you give me an example of passing a pointer?
hybrid

Arrays in C++

Post by hybrid »

Taliesen wrote:

Code: Select all


int menuFunction(int a, Tribes[], int c);
int tribalAssignment(Tribe Tribes[], int c);


    menuFunction(menuChoice, Tribes, totalTribes);

int tribalAssignment(Tribe Tribes[], int c) {
int menuFunction(int a, Tribe Tribes[], int c)

                    menuFunction(a, Tribes, c);
                    tribalAssignment(Tribes, c);
Ok, these are the lines to change. I realized that you used a static array, thus no need to pass a pointerto array, just use address of array. Therefore you need to distinguish declaration of array and element access to array. It looks the same in syntax but is used in different ways. When declaring an array you write Type name[20]; and you want to have an array of 20 elements. But when writing func(name[20]) you would access the 21st element of that array instead of an array of size 20.
Additionally the syntax and semantics of arrays in C++ is inherited from C, thus &Tribes[0]==Tribes is the beginning of the array, and is of type pointer to array element (not pointer to array). A pointer to an array is of type element** and you could use &Tribes to access it. That way you could change the memory address of your array, e.g. if you use dynamic allocation.
The equivalence of pointer to array and pointer to pointer to element can be tested on the parameters of main(). argv is either char *argv[] or char **argv.
Hope this helps, otherwise try a good tutorial on C++.
jf03cg
Posts: 14
Joined: Sun Apr 24, 2005 12:12 am
Location: Ontario, Canada
Contact:

Post by jf03cg »

Taliesen wrote:Like I said I am kind of new, could you give me an example of passing a pointer?
Sure, here you go:

Code: Select all


typedef struct {
  int num1;
} myStruct;

void doSomething(myStruct*);

int main(int argc; char *argv[]){
   myStruct struct1;
   doSomething(&struct1);
}

void doSomething(myStruct *input){
   input->num1=12;
}

When you call
myStruct struct1;

There is a memory address associated to struct1 of type myStruct. When the compiler sees that you are calling

doSomething(&struct1);

It knows that you are sending the function doSomething the ADDRESS of struct1 not the structure itself. When you declare your function, you will need to include an asterisk infront of the variable name. This tells the compiler that you want a pointer passed to the function and not a variable.

The tricky thing about pointers is you have to de-reference them or else you are writing to the address and that is bad madness....

There are a lot more to pointers than just this, this is a very basic example.

Just remember that whatever you pass a pointer, you are passing by reference, so any changes made to the data in the structure is changed inside the calling function as well..


Hope this helps you out ;) If not, just google "Pointers in C"
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

Thank you

Post by Taliesen »

This was a truly helpful post, and I got all of those pointer issues figured out and my program compiles gallantly. However after a couple more hours of programming I hit a snag with random numbers. I am using the random function and have the correct header files. I think my problem is in the passing of my struct member variables again, but I don't know. so here is the code:

Code: Select all


#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <time.h>



using namespace std;

//structures
typedef struct
{
    int Number;
    int Members;
    int Men;
    int Age;
    float Prob;
}Tribe; 

//user-defined function declaration

int tribalAssignment(Tribe*, int c);
int menuFunction(int totalMembers, int totalTribes);
int probability(Tribe*, int a);

const int totalTribes = 100;
Tribe Tribes[totalTribes];

int main(int argc, char *argv[])
{
    int totalMembers;
    
    menuFunction(totalMembers, totalTribes);
    
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

int tribalAssignment(Tribe *input, int c)
{
    int i = 0;
    int a;
    
        while (i<=100)
        {
            probability(&Tribes[i], a);
            input->Members = 0;
            input->Number = i;
            input->Men = 0;
            input->Age = a;
            cout << "Tribe number    " << input->Number << "    Tribe Members   " << input->Members << "    Age   " << input->Age << endl;         
            i++;  
        }  
}
    
int menuFunction(int totalMembers, int totalTribes)
{
    int menuChoice;
    //int totalTribes, totalMembers;
    
    
    cout << "Main Menu..." << endl;
    cout << "-------------------" << endl;
    cout << "       1. Change Number of People   " << totalMembers << endl;
    cout << "       2. Change Number of Tribes   " << totalTribes << endl;
    cout << "       3. Generate Tribal Assignment" << endl;
    cout << "       4. Quit..." << endl;  
    
    cin >> menuChoice;
    
    switch ( menuChoice )
    {
            case 1 :
                    cout << "How many people would you like to calculate?" << endl;
                    cin >> totalMembers;
                    menuFunction(totalMembers, totalTribes);
                    break;
            case 2 :
                    cout << "How many tribes would you like to calculate for?" << endl;
                    cin >> totalTribes;
                    menuFunction(totalMembers, totalTribes);
                    break;
            case 3 :
                    tribalAssignment(&Tribes[0], totalTribes);
                    break;
            case 4 :
                    return 0;
                    break;
          
    }
}

int probability(Tribe *input, int a)
{
    srand((unsigned)time(NULL));
    input->Age = a;
    a = rand() % 26 + 1;
    return a;  
}
As you can see I am trying to make age come back as a random number for each member of the structure array Tribes. Am I passing it incorrectly? Or is there something wrong with my random code? Thanks again in advance.
hybrid

Post by hybrid »

:lol:
You should really repeat one or two chapters of some programming tutorial. Three things with your new method:
  • - You use an uninitialized variable (your compiler should warn you, try gcc -Wall if you have this compiler)
    - You assign a to the member variable and change a afterwards (remember that a is a variable whose value is copied to Age, you're not assigning a new object to Age, thus change Age directly)
    - The return value is not needed (and probably not wanted) so do not return anything and make it void.
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

still a little confused

Post by Taliesen »

Code: Select all

#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <time.h>



using namespace std;

//structures
typedef struct
{
    int Number;
    int Members;
    int Men;
    int Age;
    float Prob;
}Tribe; 

//user-defined function declaration

int tribalAssignment(Tribe*, int c);
int menuFunction(int totalMembers, int totalTribes);
int probability(Tribe*);

const int totalTribes = 100;
Tribe Tribes[totalTribes];

int main(int argc, char *argv[])
{
    int totalMembers;
    
    menuFunction(totalMembers, totalTribes);
    
 
    system("PAUSE");
    return EXIT_SUCCESS;
}

int tribalAssignment(Tribe *input, int c)
{
    int i = 0;
    int a;
    
        while (i<=100)
        {
            probability(&Tribes[i]);
            input->Members = 0;
            input->Number = i;
            input->Men = 0;
            input->Age = a;
            cout << "Tribe number    " << input->Number << "    Tribe Members   " << input->Members << "    Age   " << input->Age << endl;         
            i++;  
        }  
}
    
int menuFunction(int totalMembers, int totalTribes)
{
    int menuChoice;
    //int totalTribes, totalMembers;
    
    
    cout << "Main Menu..." << endl;
    cout << "-------------------" << endl;
    cout << "       1. Change Number of People   " << totalMembers << endl;
    cout << "       2. Change Number of Tribes   " << totalTribes << endl;
    cout << "       3. Generate Tribal Assignment" << endl;
    cout << "       4. Quit..." << endl;  
    
    cin >> menuChoice;
    
    switch ( menuChoice )
    {
            case 1 :
                    cout << "How many people would you like to calculate?" << endl;
                    cin >> totalMembers;
                    menuFunction(totalMembers, totalTribes);
                    break;
            case 2 :
                    cout << "How many tribes would you like to calculate for?" << endl;
                    cin >> totalTribes;
                    menuFunction(totalMembers, totalTribes);
                    break;
            case 3 :
                    tribalAssignment(&Tribes[0], totalTribes);
                    break;
            case 4 :
                    return 0;
                    break;
          
    }
}

int probability(Tribe *input)
{
    srand((unsigned)time(NULL));
    input->Age = rand() % 26 + 1;
      
}
those are the changes I made, trying to do what you said, or at least what I think you said. You were kind of general so I am not sure if I understood right. If I did not understand right, maybe you could explain it one more time. But with these changes, it compiles and runs with no warnings but age is always printed as 0. Which shouldn't be...thanks again in advance.
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

Post by Taliesen »

woot I made some progress. By passing input instead of a refrence to the tribes[] array it now generates and outputs the random number. The problem is that now it is the same number for every instance of the array. And it does change with every time I run the program, I just need it to come up with a different random number every time it goes through that loop. Any ideas why it is doing this?
Guest

Post by Guest »

Code: Select all

input->Age = rand() % 26 + 1;
Don't be surprised if this always returns 1.
The % operator returns the remainder of the division of rand() by 26.
My guess is that rand() returns a number between 0 and 1.
Which means the remainder is always 0 (except when rand() is precisely 1) because ypou're using integer math (% works on integers, 26 is an integer, 1 is an integer, Age is an integer).

But my guess is you want a random number between 0 and 26?
Try changing % into a * ...
Guest

Post by Guest »

And another thing:

when you write a function with a return type, you're supposed to "return" something. Otherwise you'll get garbage, or worse, a crash when calling the function.
Your probability function should return something - or be declared as void.
Taliesen
Posts: 17
Joined: Fri Apr 22, 2005 7:39 am

Post by Taliesen »

my rand() call works perfectly. Every time I run the program I get a different number within the range. The problem is that I want a different Age for every instance of the Tribe struct array. And right now it is just giving me the same random number, it dosn't change it. Am I not changing the instance? Or is there another problem that I have?

Also I will change it to void now. And see what happens.
Guest

Post by Guest »

If rand() works fine, that must be because it returns values between 0 and something big.

But:

Code: Select all

int tribalAssignment(Tribe *input, int c) 
{ 
    int i = 0; 
    int a; 
    
        while (i<=100) 
        { 
            probability(&Tribes[i]); 
            input->Members = 0; 
            input->Number = i; 
            input->Men = 0; 
            input->Age = a; 
            cout << "Tribe number    " << input->Number << "    Tribe Members   " << input->Members << "    Age   " << input->Age << endl;          
            i++;  
        }  
} 
Are you checking this output or are you checking it somewhere else?

Because what happens here, is that a is uninitialised and then assigned to Tribes[0].Age. (Since Input is &Tribes[0])
The "probability" function is applied to all 100 items, but you only display the first - Tribes[0].

Can I ask you something?
Are you trying to assign an "age" to a tribe or to the individual members of a tribe? Because currently you have an array of tribes, no of tribes with members. For that, you'll have to add some other structures.
Guest

Post by Guest »

PS: not initialising a is also one of the things Hybrid warned you about.
Post Reply