简体   繁体   English

当结构来自“结构数组”时在函数中传递结构

[英]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:在“ C 编程:一种现代方法”一书中,向读者提供了以下准代码:

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.因此,简言之,作者创建称为数据类型struct part ,创建了一个函数调用print_part即作为其参数的变量p的数据类型的struct part ,创建称为阵列inventory该类型的存储100个不同的结构struct part ,和然后对上述函数进行以下调用: print_part(inventory[i]) ,其中i可以采用 0 到 99 之间的任意值。


In the above function call, is inventory[i] functioning as a pointer?在上面的函数调用中, inventory[i]用作指针? 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).起初我认为肯定不是(因为print_part的原型语句指定函数的参数是一个结构变量......而不是指向结构的指针)。

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.然而,随后使用inventory[i].number=883inventory[i].name[0]='\\0'让我重新考虑,也许它确实起到了指针的作用。

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 .inventory[i].name[0]的情况下,似乎inventory[i]正在建立一个基地址,并且从该基地址开始, struct part数据类型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?在上面的函数调用中,inventory[i] 是否用作指针?

No. The type of inventory[i] is struct part .不可以inventory[i]的类型是struct part It is passed to the function by value , just like any other function argument.通过 value传递给函数,就像任何其他函数参数一样。 * *

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).起初我认为肯定不是(因为print_part 的prototype 语句指定函数的参数是一个struct 变量...不是指向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.但是,随后使用inventory[i].number=883inventory[i].name[0]='\\0'让我重新考虑,也许它确实起到了指针的作用。

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 .如果inventory[i]是一个指针,那么访问它指向的结构成员的惯用方法是使用->运算符,形式为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.inventory[i].name[0]的情况下,似乎inventory[i]正在建立一个基地址,并且从该基地址开始,结构部分数据类型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.当然,您可以称其为“pointeresque”,但这不会使指定对象的表达式成为 C 意义上的指针。 Pointers introduce an extra level of indirection that is not present in your inventory[i] .指针引入了一个额外的间接级别,这在您的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 由指向第一个数组元素的指针。 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. C 函数中的数组类似于指针。 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) .此外,数组取消引用语法array[i]*(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.例如,这可以从sizeof如何对待它们中看出。 If you have unsigned char array[100];如果你unsigned char array[100]; , then sizeof(array) is 100. However, if you then assign unsigned char *ptr=array; ,则sizeof(array)为 100。但是,如果您随后分配unsigned char *ptr=array; , then sizeof(ptr) is the size of the pointer and not the array. ,那么sizeof(ptr)是指针的大小,而不是数组的大小。

In your case, inventory[i] is not a pointer but a struct part .在您的情况下, inventory[i]不是指针,而是struct part As mentioned above, it is a convenient expression meaning *(inventory+i) .如上所述,它是一个方便的表达方式,意思是*(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.也就是说, inventory+i是数组的第i个元素的地址,而inventory[i]通过取消引用该地址来为您提供该元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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