简体   繁体   中英

Passing structures in functions when the structure comes from an “array of structures”

In the book " C Programming: A Modern Approach " the following quasi-code is supplied to the reader:

struct part {
  int number;
  char name[NAME_LEN+1];
  int on_hand;
} part1;

void print_part (struct part p)
{
  ...
}

struct part inventory[100];

print_part(inventory[i]);

inventory[i].number=883;

inventory[i].name[0] = `\0`

So, in summary, the author creates a data type called struct part , creates a function called print_part that takes as its argument a variable p of data type struct part , creates an array called inventory that stores 100 different structures of type struct part , and then makes the following call to the aforementioned function: print_part(inventory[i]) , where i could take on any arbitrary values between 0 and 99.


In the above function call, is inventory[i] functioning as a pointer? At first I thought certainly not (because print_part 's prototype statement specifies that the function's parameter is a struct variable...not a pointer to struct).

However, the subsequent usage of inventory[i].number=883 and inventory[i].name[0]='\\0' made me reconsider that, perhaps, it does function as a pointer.

In the case of inventory[i].name[0] , it seems like inventory[i] is establishing a base address and from that base address, there is an offset to the 2nd field of the struct part data type, name . This strikes me as very "pointer-esque". Any clarification would be greatly appreciated!

In the above function call, is inventory[i] functioning as a pointer?

No. The type of inventory[i] is struct part . It is passed to the function by value , just like any other function argument. *

At first I thought certainly not (because print_part's prototype statement specifies that the function's parameter is a struct variable...not a pointer to struct).

And you were right to think that.

However, the subsequent usage of inventory[i].number=883 and inventory[i].name[0]='\\0' made me reconsider that, perhaps, it does function as a pointer.

I'm not seeing the connection there. The . in those expressions is the operator for accessing a structure member. Its left-hand operand must be a structure, not a pointer to one. If inventory[i] were a pointer then the idiomatic way to access the members of the structure to which it points would be with the -> operator, of the form array_of_pointers[i]->member = value .

In the case of inventory[i].name[0] , it seems like inventory[i] is establishing a base address and from that base address, there is an offset to the 2nd field of the struct part data type, name. This strikes me as very "pointer-esque".

Most objects have associated storage, which has a characteristic address of appropriate pointer type. When you access an object, you can think of it as accessing the memory at that object's address. Sure, you can call that "pointeresque", but that does not make the expression designating the object a pointer in the C sense. Pointers introduce an extra level of indirection that is not present in your inventory[i] .


* Perhaps someone is saying "not arrays!" right now. That's right, arrays are not passed to functions by value, because they are not passed to functions at all . In almost all contexts where a sub-expression of array type appears in an expression, it is automatically replaced by a by a pointer to the first array element. A function call's argument list is not among the exceptions. Thus, it is impossible even to express passing an array to a function.

Arrays in C function similarly to pointers. That is, when you pass them as arguments to functions, the address of the first element is what is passed. In addition, the array dereference syntax, array[i] , is syntactic sugar for *(array+i) . So, in many situations, you can treat arrays like pointers.

However, it must be kept in mind that, despite these similarities, arrays are not pointers. This can be seen, for example, in how sizeof treats them. If you have unsigned char array[100]; , then sizeof(array) is 100. However, if you then assign unsigned char *ptr=array; , then sizeof(ptr) is the size of the pointer and not the array.

In your case, inventory[i] is not a pointer but a struct part . As mentioned above, it is a convenient expression meaning *(inventory+i) . That is, inventory+i is the address of the i th element of the array and inventory[i] provides you that element by dereferencing that address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM