Call Array Member in function Help
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 24

Thread: Call Array Member in function Help

  1. #1
    Join Date
    Sep 2010
    Posts
    11

    Call Array Member in function Help

    Hello everyone,

    I have defined a struct, and I have made an array of this struct:

    Code:
    struct Nodes
    {
        int number;
    }
    
    Nodes Block[10];
    I have declared the following function:

    Code:
    void function_one(Nodes Block);
    Then I call it in my main() program:

    Code:
    for (int i = 0; i < 10; i++)
       function_one(Block[i]);
    The following is the definition of function_one();

    Code:
    void function_one(Nodes Block[]) {
      Block[].number = 1;
    The problem is that I don't know how to make the above function definition take the array element that I am sending it when I call it. For example, if in the main() part, the for loop is evaluating i = 0, I thought the definition would take i = 0 as a parameter and evaluate Block[0].number = 1.

    It doesn't. Any help would be appreciated.

    Thanks guys!

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: Call Array Member in function Help

    Your function declaration and function definition do not match. Nodes Block is a single Nodes object while Nodes Block[] is an array of Nodes objects (of indefinite size). The way you call the function in main(), the declaration is right: You're passing Blocks[i] which is a single object, and you would have to access its sole member as Block.number inside the function.

    BTW: Giving the array and the function parameter the same name is not really dextrous: It is likely to lead to confusion.

    BTW II: Naming the struct type "Nodes" is misleading too, as the name is plural while it only contains a single item.

    Ah, and... Welcome to CodeGuru!

  3. #3
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    Thank you for the reply and the warm welcome Eri523!

    Your BTW's are spot on. The reason I named them like this are for clarity in my post. The names are not like this in my program. I guess my attempt for clarity was not clear. Ha!

    Anyway, I have changed my definition to match the declaration like you suggested. Mainly:

    Code:
    void function_one(Nodes Block) {
      Block[].number = 1;
    However, now it gives me an error telling me that Block[].number = 1 is expecting an argument (inside [] I suppose).

    Thanks again for any further insights!

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: Call Array Member in function Help

    Quote Originally Posted by M2W View Post
    Anyway, I have changed my definition to match the declaration like you suggested. Mainly:

    Code:
    void function_one(Nodes Block) {
      Block[].number = 1;
    However, now it gives me an error telling me that Block[].number = 1 is expecting an argument (inside [] I suppose).
    Yes, of course. As I wrote in my previous post:

    Quote Originally Posted by Eri523
    [...] you would have to access its sole member as Block.number inside the function.
    An empty [] only makes sense in a declaration. (Well, there actually are other contexts where this construct is used as well, but I think I'll ignore them here for simplicity.)

    And I hope the missing curly brace at the end of the function definition in both your posts is merely a copy-past failure.
    Last edited by Eri523; September 25th, 2010 at 09:25 PM.

  5. #5
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    Thank you again. That fixed the issue. But created another one, albeit, just 1.

    Let me define a function_two() (and please ignore function_one() from before) so you can help me see what I am doing wrong:

    Code:
    void function_two(Nodes Block)
    {
       // some stuff here
    
       if (Block.number == 9) // the .number is the same as the index
        {
    	function_two(Block[0]); //Here is the problem -> Block[0] (The error points to the first bracket)
         }
    
            function_two(stop.number ++); //Here is the same problem -> The error points to the stop word
    
    }
    Now, I have fixed my functions like you told me to in your first post (I misread the first time, won't happen again). But this function_two is supposed to check if the "int number" of the array member is 9, if it is, I want to call function_two on the first element in the array, which is Block[0]. I figured this is the right way of calling it, since that is how I called function_two in the fist place in my main() part. But it doesn't work here. "Error: No operator [] matches these operands"

    I tried a different way too, as you can see in the last line. This time, I'm trying to call function_two on the next member in the array (from the array member that called function_two in the first place). I tried accessing without the [] as above and using stop.number ++. It says
    "No suitable constructor exists to convert from int to Nodes"


    Thank you!
    Last edited by M2W; September 25th, 2010 at 11:18 PM. Reason: added comments

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: Call Array Member in function Help

    Quote Originally Posted by M2W View Post
    Code:
    	function_two(Block[0]); //Here is the problem -> Block[0] (The error points to the first bracket)
    This error is thrown because Block inside the function is a single Nodes object, but you try to access it as an array (which would be correct &#237;n main()). I told you it would be misleading to use the same name for two different things...

    To fix this, you can pass the entire array (for access to the first element) as well as the index to the function:

    Code:
    void function_two(Nodes Block[], int i)
    {
       // some stuff here
    
       if (Block[i].number == 9) // the .number is the same as the index
        {
    	function_two(Block[0]); // Now this is correct
         }
    
            function_two(stop.number ++); // Still wrong, well take care of that later
    }
    Now this would be called like function_two(Block, i); in main(). (I must admit I reused a variable name here myself, but in this case at least it's for the same type of object, and the name i for an array index is too tempting... )

    Code:
            function_two(stop.number ++); //Here is the same problem -> The error points to the stop word
    Well, this is definitely not the same problem, hence you get a different error message. I don't see any definition of stop anywhere, but the error message suggest there must be one anywhere, and maybe it's a Nodes object. I can't tell you how to fix this though, because I don't know what you intend to do here.

    EDIT: Oops! Of course this is not correct:

    Code:
    	function_two(Block[0]); // Now this is correct
    It's incorrect because I changed the function signature to take two arguments now. Calling it like function_two(Block[0], 0); would at least be syntactically correct, but I'm not sure whether this would do what you want it to. Be careful when using recursion: This can be tricky, sometimes not only for a beginner.
    Last edited by Eri523; September 26th, 2010 at 07:29 AM.

  7. #7
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Call Array Member in function Help

    A thing to remember when you work with the built-in array is that the array decays to a pointer when passed to a function. Here's a little demo
    Code:
    #include <iostream>
    
    // This is a POD
    struct Nodes
    {
        int number;
    };
    
    void function_with_array_syntax(Nodes indicator_to_nodes[])
    {
        // Q: how is this assignment possible?
        Nodes* pointer_to_nodes = indicator_to_nodes;
    
        // here, the asterisk '*' is the dereference operator,
        if((*pointer_to_nodes).number == 9)
        {
            // do something
        }
        std::cout << "Finished inside function_with_array_syntax\n";
    }
    
    void function_with_pointer_syntax(Nodes* pointer_to_nodes)
    {
        // arrow operator is a shorthand which means,
        // dereference, then access a member thru a dot operator
        // as shown in the function above
        if(pointer_to_nodes->number == 9)
        {
            // do something
        }
        std::cout << "Finished inside function_with_pointer_syntax\n";
    }
    
    void function_with_plain_nodes(Nodes node_object)
    {
        std::cout << "The value inside the plain Nodes object is: "
                  << node_object.number << "\n";
    }
    
    void how_we_usually_pass_array_to_function(Nodes* pointer_to_nodes, const unsigned int array_size)
    {
        for(unsigned int element_counter = 0; element_counter < array_size; ++element_counter)
        {
             // do something
        }
    
        // let's access 3rd element without iteration, but by a pointer arithmetic
        const unsigned int THIRD_ELEMENT_INDEX = 2;
        std::cout << "3rd element is "
                  << (pointer_to_nodes + THIRD_ELEMENT_INDEX)->number << "\n";
    }
    
    // a little better way to work with the each element in the array once
    // you are familiar with a function pointer
    void array_walk(Nodes* begin, Nodes* end, bool (*pointer_to_a_function)(const int))
    {
        while(begin != end)
        {
            std::cout << begin->number << " is "
                      << (pointer_to_a_function(begin->number)  ? "Even" : "Odd") << " number\n";
            ++begin;
        }
    }
    
    bool is_even(const int number)
    {
        return (number % 2) == 0;
    }
    
    int main()
    {
        const unsigned int ARRAY_SIZE = 5;
        Nodes blocks[ARRAY_SIZE] = { 1, 2, 3, 4, 5 };
    
        // Q: We plainly passed the blocks object to a function with differenct signature,
        //    how are these three function calls possible?
        function_with_array_syntax(blocks);
        function_with_pointer_syntax(blocks);
    
        // Q: What funny business is this '*(&blocks[4])' all about?
        function_with_plain_nodes(*(&blocks[4]));
    
        how_we_usually_pass_array_to_function(blocks, ARRAY_SIZE);
    
        // work with each elements
        array_walk(blocks, blocks + ARRAY_SIZE, is_even);
    }
    And as for the pointer itself, it's just there to remind us that no matter how good you get with the language, there's always something to learn.

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,888

    Re: Call Array Member in function Help

    Code:
    void function_one(Nodes Block) {
      Block.number = 1;
    }
    Something which hasn't been mentioned yet (that I've seen) is that this will not do what you expect it to do.

    If you pass the entire array to the function, and an index, then you can modify elements of the array at will. However, here you pass only a copy of one element----so any changes you make to it, will not be propagated to the passed object in main!

    You could if you wish pass by reference instead of by value.

  9. #9
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    OK guys. Thanks for the replies. That was a handful. I'm trying to implement the suggestions and it went bad, so let me summarize what I want to do, and where I am. Please bear with me.

    So I have an array of 10 elements Nodes:
    Code:
    Nodes Block[10]
    In main, I use the following to call function_two on every member in the array:
    Code:
    for (int i = 0; i < 10; i++)
        function_two(Block[i])
    Now, each element of the array together with function_two is intended to do 2 things:
    1) Check if the array member that called it is the last one in the array. If it is, then call function_two on the first array element, mainly Block[0]. I thought I could access this member two ways: via its index (i.e., Block[0]) or via its "member number" (i.e., Block[0].number or Block.number, not sure)

    If it is not the last element in the array, I just want it to call function_two on the next element. I thought I could do this in two ways. Either put Block[index ++] (but how?) or with Block.number ++

    2) Once it knows that it is not the last element in the array, or if it is and it went to the first element in the array, it just needs to change a bool member in the array element. So my struct is in fact:
    Code:
    struct Nodes {
    int number;
    bool label;
    };
    So I guess where I stand is, if I define the function like this:
    Code:
    void function_two(Nodes &Block) {
       //What I wrote in this post
    }
    You guys say it will automatically take the array member calling the function automatically as a reference. And that's cool, but inside this function definition, I don't see a way to call this function again for specific array members, mainly the next array element from the one that called the function.

    Thanks again!

  10. #10
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Call Array Member in function Help

    I think you're being taught things backwards xD

    If I got you right, you want a recursive function to work with the array, and the class Node is capable of knowing whether it is sitting in the last position in the array, and if so, the class can then call the said recursive function??

    First, arrays are fixed size, so you already know the ELEMENT in the last position.

    Second, in order for the Node class to be self-aware of its position, it needs more than just simple data types and I have a feeling that such a thing is far from your reach at this point.

    Third, if none of these don't make sense to you, and somehow you're stuck with what you've been said and still want to do what you want to do, then maybe something like this could suit your needs?
    But once again, this is not the proper way to work with the array
    Code:
    #include <iostream>
    #include <cstddef>
    
    #define SENTINEL_VALUE 999
    #define ARRAY_SIZE 10
    
    using namespace std;
    
    struct Node
    {
        int number;
        bool label;
    };
    
    // Demo only, please avoid this kinda recursion
    void function_two(Node* pointer_to_node)
    {
        static size_t counter(0);
        cout << "Element at position (" << counter + 1 << ")";
    
        if(pointer_to_node->number == SENTINEL_VALUE)
        {
            cout << " is the last element, terminating loop\n";
    
            // rewind the pointer back to the first element
            pointer_to_node -= counter;
    
            // then,change the value of the label like you described
            pointer_to_node->label = true;
        }
        else
        {
            cout << " is not the last, checking next element... \n";
            ++counter;
            return function_two(++pointer_to_node);
        }
    }
    
    int main()
    {
        Node blocks[ARRAY_SIZE] = { 0 };
    
        blocks[9].number = SENTINEL_VALUE;
    
        function_two(blocks);
    
        cout << "Label value of the the 1st element is " << blocks[0].label;
    }

  11. #11
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    OK. I mostly understand what you said. I can work my way through pointers if it does what I need it to do. Would my stuff work better if I made the struct Nodes a linked list? Actually, a circular linked-list?

    If I did this, would function_two() (yes, it is recursive), know that it has to point to the first element in the array if the one that called it is the last one? Or how would I do it? I guess I could try to pass the pointers a the parameter in the function?

    I'm gonna go ahead and try that, and post what I write. Maybe then you guys can tell me if that is a better approach.

    Be back in a few mins.

  12. #12
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: Call Array Member in function Help

    First, potatoCode, thank you for your concise sample code in post #7. And it's even taylor-made for the OP's question, not just some anonymous copy-paste stuff!

    But I really had to twist my mind a bit to follow what is going on in your demo code in post #10. As you correctly mentioned, this is definitely not the right way to do that, and I hope that's illustrated appropriately by that sampe. BTW: The counter will de facto not be incremented during the path of processing, as it is not passed along when recurring...

    M2W, I don't think that using a linked list, whether circular or not, would be a real gain. I agree to potatoCode and think a plain iteration would best fit the scenario. Something like that:

    Code:
      do {
        for (int i=0; i<10; ++i) {
          function_two(Block, i);  // Implemented non-recursive!
        }
      } while (/* some condition */);
    You may add specific processing for the last element either in main() (preferably in the outer loop) or, based on the value of i, in function_two(), as you like.

  13. #13
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    Again, thanks for the replies. Some, I admit, are a little over my head. I mean, what I want to do sounds simple in my head, but it's totally confusing when writing it. Forgive me, I am just a mathematician trying to pick up on the programming part. I used to get along fine with a piece of paper and a pencil before. C++ is another story...

    Anyway, I kind of wrote a linked-list before reading your post Eri523. I liked potatoCode's stuff too but couldn't get my head around it. Well, like I said, I tried writing a linked-list. And since I already wrote it, can you guys check it out anyway?

    The idea is that I will call function_two with some pointer as a parameter, then it will do something to that node, and then call function_two on the next node via a pointer. Sounds simpler no?

    In other words:
    1. function_two (on first node)
    2. do stuff to it
    3. function_two (next node)

    Two issues:
    1. How do I make the last node point back to the first node? I know I have it as NULL, so I should change it to what? top?

    2. How do I even pass the "next" pointer as a parameter? I don't know the syntax.

    Please check what I have.

    Code:
    #include <iostream>
    using namespace std;
    
    struct Nodes
    {
    	int number;
    	Nodes *link;
    };
    
    typedef Nodes* Block_Ptr;
    
    void function_two(/*pointer to a node*/);
    void insert_node(Block_Ptr &top, int num); //insert a new node, and modify its number member in Nodes
    
    int main(){
    	do{
    
    		Block_Ptr top;
    		top = new Nodes;
    
    		top->number = 2;
    		top->link = NULL;
    
    		insert_node(top, 1);
    		insert_node(top, 0);
    
    		function_two(/*pointer to some specified node, maybe use number member?*/);
    
    	}while(/* something */);
    
    	return 0;
    }
    
    void insert_node(Block_Ptr &top, int num)
    {
    	Block_Ptr tmp_ptr;
    	tmp_ptr = new Nodes;
    	tmp_ptr->number = num;
    	tmp_ptr->link = top;
    	top = tmp_ptr;
    }
    
    void function_two(/*Ponter to some specified node*/)
    {
    	// do stuff and then move on to next node
    	
    	function_two(/*Pointer to the next node*/)
    }
    This seems easier to follow except for my 2 questions.

    Thanks for any help fellas.

  14. #14
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,583

    Re: Call Array Member in function Help

    Let's answer your post backwards...

    Quote Originally Posted by M2W View Post
    2. How do I even pass the "next" pointer as a parameter? I don't know the syntax.
    The "next" pointer can be treated just like the "top" pointer, which already is obvious from the fact that they're both of the same type: Block_Ptr.

    Yet again, I strongly suggest to forget recursion here. While recursion is the method of choice for, for instance, binary trees, a linear list is better approached by plain iteration. Considering this, function_two() might look something like this:

    Code:
    void function_two(Block_Ptr pNode)
    {
      while (pNode!=NULL) {
        // Do something with the Nodes object
        pNode=pNode->link;
      }
    }
    1. How do I make the last node point back to the first node? I know I have it as NULL, so I should change it to what? top?
    Yes, exactly that. By having the last node point back to the first one, you close the circle. But be aware that, in that case, you can't use the way of terminating the iteration I demonstrated above any more. Passing the pointer to any node of a circular list to the function_two() above would send your program into an endless loop.

    So you need some other means of determining that you have scanned the entire list. This has to be done using some property of the node objects, and one particular property is the link pointer. But in this case you wouldn't compare it to NULL but rather to top. (I'm not 100% sure though whether comparing pointers for equality to anything else but NULL would pass the "clean design" check.) Another way of doing this would be using a sentinel node like potatoCode described above for the array, or to implement another struct field solely for that purpose, probably a boolean flag.

    But here applies the same I already said about recursion: As far as I know the scenario by now, I don't see any reason why you should prefer the more complicated circular list over the plain linear list.

    And finally: You are allocating the list nodes using new, which is the way to do it for a linked list. But you never release them again using delete, which is the most basic sample of a memory leak.

  15. #15
    Join Date
    Sep 2010
    Posts
    11

    Re: Call Array Member in function Help

    Thanks Eri523. I'll work on your suggestions now, but will leave this post with little extra info.

    The array of struct in my first post, and the linked-list in my previous post are intended to be a circular structure. That was my issue with the arrays. I needed to find a way to let the function know that it was working on the last element in the array, and then send the function call to the [0] element, and not to the next element (which would be out of bounds).

    Then I tried using a linked-list. And I figured I would make it circular by connecting the last pointer to the head pointer. The problem is, I don't know how to do this connection precisely. I know the next pointer should point to the top, but I don't know how to code that. It seems like I should just add a line or two to my code on the previous post and it will work.

    Finally, I want the thing to go into an endless loop, calling function_two on the next node, and then on the next one, etc. I kind of have to use recursion because that is the point of the problem assigned. The loop will end since I will put a counter that will go up with each function_two that is called and once it hits a limit it will exit the do-while.

    I guess I'll worry about the memory leak once I get this thing running.

    I'll go and see if I can implement what you tell me. Thanks a lot. Any more insights please post in the meantime.

Page 1 of 2 12 LastLast

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center