The solution is simple: You just have to return a reference to data member:
int32& list_element_at(llist list, int32 n)
{
...
return temp->data;
Just a single ampersand and you are done :-). Now, what that causes behind the scenes is that the compiler will pass a pointer to the data cell instead of a value as the return value of your function. But as you have marked it as a reference, the compiler remembers that it has to dereference this pointer before using it. In other words, this is like writing:
int32* list_element_at(llist list, int32 n)
{
...
return &temp->data;
}
...
*(list_element_at (listo , 2)) = 50;
and the compiler does away with the two asterisks automatically.
While we are at it, I suggest that you give your variables more meaningful names. "temp" is for example no good choice. How about writing your little function like this:
int32 list_element_at (llist list, int32 index)
{
struct node *pNode;
pNode = list.head;
while (pNode )
{
if (pNode->index == index)
return pNode->value;
}
return INT_MIN; }
In your current version you return an undefined value if you can't find an element with the given index. But what should your function return instead? You have to find a value that is different from all the values in your nodes. I have chosen INT_MIN, which is the lowest integer value that can be represented in an int. But still this is no good solution. In the version that returns a reference, the problem is even bigger, as you have to return something.
My suggested solution is not to return a value but a node pointer. And in case you can't find the node you would return a null pointer:
struct node* list_element_at (llist list, int32 index)
{
struct node *pNode;
pNode = list.head;
while (pNode )
{
if (pNode->index == index)
return pNode;
}
return 0; }
That also solves your problem with assigning to the element. You can now write:
struct node* pNode = list_element_at (listo , 2);
if (pNode)
pNode->data = 50;
That looks a lot better.
<END OF LESSEN MODE>