为什么C语言中没有数组长度函数?

3

虽然在C语言中有各种方法可以找到数组的长度,但该语言并没有提供一个内置函数。

为什么C语言或其任何修订版都没有包含这样一个常见操作的原因是什么?


2
有一个操作符(应用两次)比函数更好。为什么您会更喜欢函数而不是操作符?您也不会使用函数来相加两个数字,对吧? - pmg
1
数组在C语言中的可见性不高,因此这样的函数的使用范围会受到一定限制。 - Kerrek SB
2
@Adam:不,数组不是指针。数组就是数组。 - Kerrek SB
@Kerrek SB:在C语言中,没有数组,只有指针。你所认为的数组实际上只是指针的语法糖。C编译器会将类似于x[y]的东西转换为*(x + y) - Swiss
4
@Swiss:你可能会想阅读《comp.lang.c FAQ》的第6节。既然你在那里,请也读一下其他章节。 - pmg
显示剩余2条评论
5个回答

8
C语言设计的指导原则之一是所有数据类型直接映射到内存,试图为数组类型(例如长度)存储元数据与该哲学相反。以下是Dennis Ritchie描述C语言开发过程的文章中的一段引用:
Embryonic C
...
These semantics represented an easy transition from B, and I experimented with them for some months. Problems became evident when I tried to extend the type notation, especially to add structured (record) types. Structures, it seemed, should map in an intuitive way onto memory in the machine, but in a structure containing an array, there was no good place to stash the pointer containing the base of the array, nor any convenient way to arrange that it be initialized. For example, the directory entries of early Unix systems might be described in C as

    struct {
        int     inumber;
        char    name[14];
    };
I wanted the structure not merely to characterize an abstract object but also to describe a collection of bits that might be read from a directory. Where could the compiler hide the pointer to name that the semantics demanded? Even if structures were thought of more abstractly, and the space for pointers could be hidden somehow, how could I handle the technical problem of properly initializing these pointers when allocating a complicated object, perhaps one that specified structures containing arrays containing structures to arbitrary depth?
The solution constituted the crucial jump in the evolutionary chain between typeless BCPL and typed C. It eliminated the materialization of the pointer in storage, and instead caused the creation of the pointer when the array name is mentioned in an expression. The rule, which survives in today's C, is that values of array type are converted, when they appear in expressions, into pointers to the first of the objects making up the array.
强调是我的。只需在上面的段落中用“元数据”替换“指针”一词,我认为我们已经得到了您的问题的答案。

4

除非这里有人参与C标准委员会,否则您不太可能得到权威的答案。但我能想到两个原因:

  1. 在许多(大多数?)情况下,您没有数组,只有一个指针。

  2. 存储有关数组的元数据会增加存储大小等等。 C的一般规则是,您不需要使用的就不要付费。


好的,这是StackOverflow。你永远不知道谁会回复。 :) - hpique

1

C不是面向对象的,因此它没有与对象相关联的方法概念。它的设计着眼于速度和简单性,常见的惯用语sizeof(array) / sizeof(array[0])短小简洁。


我不会称 sizeof(array) / sizeof(array[0]) 为直截了当的。特别是,当 array[0] 未分配时,我认为其中发生了什么并不明显。 - hpique
@hgpc:数组元素总是被分配的。但是你甚至可以使用 sizeof 对一个空指针进行“取消引用”。该运算符不会评估参数:struct tm *ptr = NULL; if (sizeof *ptr == sizeof (struct tm)) printf("OK\n"); - pmg
1
你是说(一堆东西的大小)/(一个东西的大小)不是一个直接计算物品数量的简单计算吗?另外请注意,sizeof(thing)计算的是thing的大小,但实际上并没有访问它,所以无论thing是否已经被分配都是无关紧要的。你有阅读文档吗? - Adam Liss
@Adam Liss 不是很明显吗,(一堆东西的大小) / (一个东西的大小)。sizeof(array[0])不是这样的(如果你考虑C++的话更糟糕;参见:https://dev59.com/zm855IYBdhLWcg3wUScW#4415646)。我并没有说我不理解它。 :) - hpique

0

这取决于效率。C是一种非常高效的编程语言。


鉴于无论如何都有一种找到数组长度的方法,为什么将其“正式化”会使C更少效率低下呢? - hpique
@hgpc - 不存储长度是高效的。您可以使用malloc创建任意大小的数组。 - Ed Heal
高效的编程语言会让人变得低效。 - aelam

0

C语言中的数组语法只是指针算术的一种语法糖。如果你想要一个真正具有长度和边界检查的数组,可以创建一个包含数组指针及其长度的结构体,并仅通过检查边界的函数来访问它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接