C:为什么你可以按值传递结构,而不是数组?
背后有什么历史或逻辑原因C:为什么你可以按值传递结构,而不是数组?,c,arrays,struct,pass-by-value,C,Arrays,Struct,Pass By Value,背后有什么历史或逻辑原因 说明: 在C中,当您将数组传递给函数时,实际上只传递指向数组的指针。 但是,当传递结构时,可以传递结构的副本或指针 //this: int function(int array[10]) // is equivalent to this: int function(int *array) //and they both pass a pointer //but this: int function(struct tag name) //passes a struct
说明: 在C中,当您将数组传递给函数时,实际上只传递指向数组的指针。 但是,当传递结构时,可以传递结构的副本或指针
//this:
int function(int array[10])
// is equivalent to this:
int function(int *array)
//and they both pass a pointer
//but this:
int function(struct tag name)
//passes a struct by value, where as this:
int function(struct tag *name)
//passes a pointer to it.
为什么不同?两种函数声明中的类型都不同-
struct tag /* and */ struct tag *
一个是结构变量,另一个是指向结构的指针
您可以对结构执行类似操作-
int function(struct tag name[]) /*--> int function(struct tag *name) */
上述内容是等效的。int函数(int数组[10])
和int函数(int*数组)
是相同的,因为6.7.5.3函数声明器(包括原型)(第118页)
7应调整“类型数组”的参数声明
到“类型的限定指针”,其中类型限定符(如果
any)是在数组类型的[and]中指定的
起源如果关键字static也出现在[和]中
]数组类型派生,然后针对每个调用
函数,则对应的实际参数的值
提供对数组的第一个元素的访问,该元素的数量至少为
由大小表达式指定的元素
.结构用于声明自己类型的数据类型,原始数据类型包括int、float、long(或structs of structs)等。它们应该包含一些数据类型,例如,学生结构将包含id、name、rollno、subject等。因此,大多数结构元素最多包含10-20个字段(在逻辑情况下),因此,当您将结构传递给函数时,它必须复制大约40-100个字节才能复制该结构变量。其中as阵列可以具有巨大的尺寸,并用于存储相同类型的信息。如果是整数,它们的大小可能是10^7,因此如果我们实现一种语言来复制整个数组以进行函数调用,它可能必须复制(10^7)*4字节,这是一个巨大的量,会严重影响性能。而数组的典型大小是10^4到10^6,这仍然是一个很大的数目。但如果创建int数组(或任何其他数组)的结构,则可以将其作为该数组的副本传递给函数。e、 g
#include<stdio.h>
typedef struct {
int arr[10];
}arrayStruct;
void change(arrayStruct a){
a.arr[2]=5;
}
int main(){
arrayStruct a;
for(int i=0;i<10;i++){
a.arr[i]=i;
}
printf("Before:\n");
for(int i=0;i<10;i++){
printf("%d ",a.arr[i]);
}
change(a);
printf("\nAfter:\n");
for(int i=0;i<10;i++){
printf("%d ",a.arr[i]);
}
return 0;
}
在原始K&R中,无法按值传递结构。这是一个语法错误。由于许多编译器供应商将其作为扩展提供,传递值最终进入了标准 为什么是限制,为什么是进化?C开发的机器很小。64 KB的段大小是常见的。记忆是珍贵的,既然你可以传递地址,为什么还要复制一些东西呢?在堆栈上复制64字节的结构是一个错误,甚至可能不是用户想要的 到了20世纪90年代中期,这已不再是事实。32位寻址和4MB或更大的RAM是常见的。这种限制是一种阻碍,并导致了一些复杂性,因为如果没有
const
,通过引用传递的结构可能会被修改,可能是无意中修改的
为什么不对数组执行相同的操作?没有需求。正如您所知,数组和指针在C中是密切相关的。C标准库很大程度上依赖于引用传递,考虑<代码> MyStase<代码>和<代码> StrucP。按值传递结构意味着在调用中删除&
,而按值传递数组则需要添加新语法。比如说,一家编译器供应商提供了C语法的按值,可能会在会议上被嘲笑 当然,可以按值传递数组;您只需将其包装在结构中
。但这仅在数组具有确定(且非可变)大小时才有效。可以在结构中包含无限大小的数组,但生成的类型不完整,只能用作指针的目标
这可能是我们将要得到的解释。绝大多数作为参数传递的数组的大小都不是固定的,按值传递数组是不可能的,即使是有意的,也是不可能的
函数存在类似(但不同)的衰减;函数不能作为参数传递,只能作为函数指针传递。由于每次需要引用函数时显式编写&
都会很繁琐,因此语言会为您处理好它
总的来说,“为什么这种语言是这样的,而不是那样的?”这种形式的问题只能回答“因为它是这样的” 嗯?“这是如何回答这个问题的?”我想大卫法利。我想OP没有意识到这一点,否则他不会对此感到困惑。在我看来,这个问题似乎是这样的,因为所有的贴花都是不可比较的。@ameyCU“我想”并没有回答“如何?”。Davidefaeli是OP.@ameyCU-我想你不明白这个问题。我在问为什么在C语言中,你可以将结构的副本传递给函数,但你不能传递数组的副本…@ameyCU是的,问题似乎是“为什么?”。你可以按值传递数组,但数组的值是指向它的第一个元素的指针(不是指向数组的指针)。指向结构的指针也是指向它的第一个值的指针,如果我没有弄错的话,不,这些是不同的(例如,类型不匹配)。我认为这个问题的可能重复更多地属于programmers.SE。值得注意的是,K&R C不允许值传递/返回struct
s。
arrayStruct returnChange(arrayStruct a){
a.arr[2]=332;
return a;
}