我试过谷歌这个并阅读:
但他们都说得很明显:你不能分配给数组,因为标准是这样说的。 这很好,但我想知道为什么标准不包括对分配数组的支持。 标准委员会详细讨论了一些事情,如果他们从未讨论过让arrays可分配,我会感到惊讶。 假设他们已经讨论过,他们必须有一些理由不让数组被分配。
我的意思是,我们可以将一个数组放在一个结构中并分配给结构就好了:
struct wrapper { int array[2]; }; struct wrapper a = {{1, 2}}; struct wrapper b = {{3, 4}}; a = b; // legal
但是禁止直接使用数组,即使它有效地完成了同样的事情:
int a[2] = {1, 2}; int b[2] = {3, 4}; a = b; // Not legal
标准委员会禁止分配数组的理由是什么?
理解意图不是使数组表达式无法分配; 那不是目标1 。 相反,这种行为不属于Ritchie在编译器中进行简化数组处理的设计决策,但在交换中使得数组表达式成为“第二类”对象; 他们在大多数情况下失去了“arrays性”。
阅读本文 (特别是标题为“胚胎C”的部分)的某些背景; 我在这里也有更详细的答案。
1.除了Perl或PHP 2之外 ,大多数公然的语言WTF通常是设计意外或妥协的结果; 大多数语言并非刻意设计为愚蠢的。
我只是拖了一下; Perl和PHP是直接的混乱。
在C中,赋值将固定大小对象的内容复制到另一个固定大小的对象。 对于标量类型(整数,浮点,指针,自C99以来的复杂类型)实现这一定义非常明确且相当简单。 结构的分配几乎一样简单; 较大的可能需要调用memcpy()
或等效的,但它仍然很简单,因为在编译时已知大小和对齐。
数组是另一回事。 大多数数组对象的大小在运行时才确定。 一个很好的例子是argv
。 运行时环境为每个命令行参数构造一个char
数组,以及一个包含指向参数的指针的char*
数组。 这些通过argv
, char**
和argv
的元素指向的动态分配的char[]
数组可用于argv
。
C数组本身就是对象,但它们通常不作为对象访问。 相反,它们的元素通过指针访问,代码使用指针算法从一个元素遍历到下一个元素。
语言可以设计为将数组视为具有赋值的第一类对象 – 但它很复杂。 作为语言设计者,您必须确定10个整数的数组和20个整数的数组是否是同一类型。 如果是,您必须决定当您尝试将一个分配给另一个时会发生什么。 是否复制较小的尺寸? 它是否会导致运行时exception? 您是否必须添加切片操作以便可以对数组的子集进行操作?
如果int[10]
和int[20]
是没有隐式转换的不同类型,那么数组操作是不灵活的(例如,参见Pascal)。
所有这些都可以定义(参见Ada),但只能通过定义比C中典型的更高级别的结构。相反,C的设计者(主要是Dennis Ritchie)选择提供具有低级操作的数组。 这无疑有时不方便,但它是一个框架,可用于实现任何其他语言的所有更高级别的数组操作。
答案很简单:在委员会介入之前从未允许过(甚至struct
分配被认为太重),并考虑到arrays衰减,允许它会产生各种有趣的后果。
让我们看看会发生什么变化:
int a[3], b[3], *c = b, *d = b; a = b; // Currently error, would assign elements a = c; // Currently error, might assign array of 3? c = a; // Currently pointer assignment with array decay c = d; // Currently pointer assignemnt
因此,允许数组赋值将使(最多)两个当前不允许的赋值有效。
这不是麻烦,但是几乎相同的表达会产生截然不同的结果。
如果你认为函数参数中的数组符号当前只是指针的另一种表示法,那就特别激动了。
如果引入了数组赋值,那将更加令人困惑。
没有足够的人不像现在这样被事物完全混淆了……
int g(int* x); // Function receiving pointer to int and returning int int f(int x[3]);// Currently the same. What afterwards? Change to value-copy?
原因基本上是历史性的。 甚至在ISO C89之前有一个C,在Kernighan和Ritchie之后被称为“K&R” C。 该语言设计得足够小,因此编译器适合严格限制(按今天的标准)64kb的内存。
该语言不允许分配数组。 如果你想复制相同大小的数组, memcpy
可以满足你的需求。 写memcpy(a, b, sizeof a)
而不是a = b
肯定不是一个很大的复杂因素。 它的另一个优点是可以推广到不同大小的数组和数组切片。
有趣的是,您提到的struct
分配变通方法在K&R C中也不起作用 。您必须逐个分配成员,或者再次使用memcpy
。 第一版 K&R的The C Programming语言提到了struct
赋值作为未来语言实现的一个特性。 这最终发生在C89上。
以这样的方式编写C,即在计算数组表达式时计算第一个元素的地址。
引用这个答案的摘录:
这就是为什么你不能做的事情
int a[N], b[N]; a = b;
因为
a
和b
都在该上下文中评估指针值 ; 它相当于写3 = 4
。 内存中没有任何内容实际存储数组中第一个元素的地址; 编译器只是在翻译阶段计算它。
也许有必要转过来解决问题,并问为什么你想要分配数组(或结构),而不是使用指针? 这更清晰,更容易理解(至少如果你已经同化了C的Zen),并且它的好处是没有隐瞒许多工作被隐藏在多兆字节数组的“简单”分配之下的事实。
以上就是c/c++开发分享防止分配数组的理由是什么?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545973.html