[英]Passing structures in functions when the structure comes from an “array of structures”
在“ 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`
因此,简言之,作者创建称为数据类型struct part
,创建了一个函数调用print_part
即作为其参数的变量p
的数据类型的struct part
,创建称为阵列inventory
该类型的存储100个不同的结构struct part
,和然后对上述函数进行以下调用: print_part(inventory[i])
,其中i
可以采用 0 到 99 之间的任意值。
在上面的函数调用中, inventory[i]
用作指针? 起初我认为肯定不是(因为print_part
的原型语句指定函数的参数是一个结构变量......而不是指向结构的指针)。
然而,随后使用inventory[i].number=883
和inventory[i].name[0]='\\0'
让我重新考虑,也许它确实起到了指针的作用。
在inventory[i].name[0]
的情况下,似乎inventory[i]
正在建立一个基地址,并且从该基地址开始, struct part
数据类型name
的第二个字段有一个偏移量。 这让我觉得非常“指针式”。 任何澄清将不胜感激!
在上面的函数调用中,inventory[i] 是否用作指针?
不可以inventory[i]
的类型是struct part
。 它通过 value传递给函数,就像任何其他函数参数一样。 *
起初我认为肯定不是(因为print_part 的prototype 语句指定函数的参数是一个struct 变量...不是指向struct 的指针)。
你这么想是对的。
但是,随后使用
inventory[i].number=883
和inventory[i].name[0]='\\0'
让我重新考虑,也许它确实起到了指针的作用。
我没有看到那里的联系。 .
在这些表达式中是访问结构成员的运算符。 它的左侧操作数必须是一个结构体,而不是指向一个的指针。 如果inventory[i]
是一个指针,那么访问它指向的结构成员的惯用方法是使用->
运算符,形式为array_of_pointers[i]->member = value
。
在
inventory[i].name[0]
的情况下,似乎inventory[i]
正在建立一个基地址,并且从该基地址开始,结构部分数据类型name 的第二个字段有一个偏移量。 这让我觉得非常“指针式”。
大多数对象都有关联的存储,它具有适当指针类型的特征地址。 当您访问一个对象时,您可以将其视为访问该对象地址处的内存。 当然,您可以称其为“pointeresque”,但这不会使指定对象的表达式成为 C 意义上的指针。 指针引入了一个额外的间接级别,这在您的inventory[i]
不存在。
*也许有人在说“不是数组!” 马上。 这是正确的,数组不按值传递给函数,因为它们不是在所有传递给函数。 在几乎所有数组类型的子表达式出现在表达式中的上下文中,它会自动替换为 a 由指向第一个数组元素的指针。 函数调用的参数列表不属于例外情况。 因此,甚至不可能表达将数组传递给函数。
C 函数中的数组类似于指针。 也就是说,当您将它们作为参数传递给函数时,第一个元素的地址就是传递的内容。 此外,数组取消引用语法array[i]
是*(array+i)
语法糖。 因此,在许多情况下,您可以将数组视为指针。
然而,必须记住,尽管有这些相似之处,数组并不是指针。 例如,这可以从sizeof
如何对待它们中看出。 如果你unsigned char array[100];
,则sizeof(array)
为 100。但是,如果您随后分配unsigned char *ptr=array;
,那么sizeof(ptr)
是指针的大小,而不是数组的大小。
在您的情况下, inventory[i]
不是指针,而是struct part
。 如上所述,它是一个方便的表达方式,意思是*(inventory+i)
。 也就是说, inventory+i
是数组的第i
个元素的地址,而inventory[i]
通过取消引用该地址来为您提供该元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.