数组大小说明

发布于 2024-11-06 01:20:50 字数 721 浏览 2 评论 0原文

我正在为明天的 C 期末考试学习,并且有一个关于 sizeof 运算符的问题。

假设 int 的大小为 32 位,指针为 64 位。

如果有一个函数:

int
foo (int zap[])
{
    int a = sizeof(zap);
    return a;
}

因为 zap 是一个指针,foo 将返回 8,因为这是存储该特定指针所需的字节数。但是,使用以下代码:

int zip[] = { 0, 1, 2, 3, 4, 5 };
int i = sizeof(zip);

i 将是 6 * sizeof(int) = 6 * 4 = 24

为什么 sizeof(zip) 返回元素数量乘以每个元素的大小,而 sizeof(zap) 返回指针的大小?是不是zap的大小未指定,而zip则没有指定?编译器知道 zip6 个元素,但不知道 zap 可能有多大是。

I am studying for a final tomorrow in C, and have a question regarding the sizeof operator.

Let's say the size of an int is 32 bits and a pointer is 64 bits.

If there were a function:

int
foo (int zap[])
{
    int a = sizeof(zap);
    return a;
}

Because zap is a pointer, foo would return 8, as that's how many bytes are needed to store this particular pointer. However, with the following code:

int zip[] = { 0, 1, 2, 3, 4, 5 };
int i = sizeof(zip);

i would be 6 * sizeof(int) = 6 * 4 = 24

Why is it that sizeof(zip) returns the number of elements times the size of each element, whereas sizeof(zap) returns the size of a pointer? Is it that the size of zap is unspecified, and zip is not? The compiler knows that zip is 6 elements, but doesn't have a clue as to how large zap may be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一紙繁鸢 2024-11-13 01:20:50

这是 C 语法中的一种不对称。在 C 中,不可能将数组传递给函数,因此当您在函数声明中使用数组语法作为参数之一时,编译器会将其读取为指针。

在 C 中,大多数情况下,当您在表达式中使用数组时,数组会隐式转换为指向其第一个元素的指针,这正是调用函数时所发生的情况。在以下代码中:

int bar[] = {1,2,3,4};
foo(bar);

数组被转换为指向第一个元素的指针,这就是函数接收的内容。

然而,并不总是应用这种隐式转换规则。正如您发现的,例如 sizeof 运算符适用于数组,甚至 & (地址)运算符也适用于原始数组(即 sizeof(* &bar) == 4*sizeof(int))。

C 中的函数不能接收数组作为参数,它只能接收指向第一个元素的指针,或指向数组的指针......或者必须将数组包装在结构中。

即使您在函数声明中的括号之间放置一个数字...

void foo(int x[4])
{
    ...
}

该数字将被编译器完全忽略...该编译器的声明完全等同于

void foo(int *x)
{
    ...
}

,例如甚至调用它传递一个不同大小的数组将不会触发任何错误...

int tooshort[] = {1,2,3};
foo(tooshort);  /* Legal, even if probably wrong */

(实际上编译器可能会发出警告,但代码是完全合法的C,如果编译器遵循标准,则必须接受)

如果您认为这条关于数组的规则在in 函数参数很奇怪,我同意,但这就是 C 语言的定义方式。

This is sort of an asymmetry in the C syntax. In C it's not possible to pass an array to a function, so when you use the array syntax in a function declaration for one of the parameters the compiler instead reads it as a pointer.

In C in most cases when you use an array in an expression the array is implicitly converted to a pointer to its first element and that is exactly what happens for example when you call a function. In the following code:

int bar[] = {1,2,3,4};
foo(bar);

the array is converted to a pointer to the first element and that is what the function receives.

This rule of implict conversion is not however always applied. As you discovered for example the sizeof operator works on the array, and even & (address-of) operator works on the original array (i.e. sizeof(*&bar) == 4*sizeof(int)).

A function in C cannot recevive an array as parameter, it can only receive a pointer to the first element, or a pointer to an array... or you must wrap the array in a structure.

Even if you put a number between the brackets in the function declaration...

void foo(int x[4])
{
    ...
}

that number is completely ignored by the compiler... that declaration for the compiler is totally equivalent to

void foo(int *x)
{
    ...
}

and for example even calling it passing an array with a different size will not trigger any error...

int tooshort[] = {1,2,3};
foo(tooshort);  /* Legal, even if probably wrong */

(actually a compiler MAY give a warning, but the code is perfectly legal C and must be accepted if the compiler follows the standard)

If you think that this rule about arrays when in function arguments is strange then I agree, but this is how the C language is defined.

有深☉意 2024-11-13 01:20:50

因为 zip 是一个数组,并且编译器在编译时知道它的大小。这只是对两个不同的事物使用相同的符号的情况,这在 C 中很常见。

int
foo (int zap[])

完全等同于

int
foo (int *zap)

编译器不知道 zap 可能有多大(所以它把找出答案的任务留给了程序员) 。

Because zip is an array and the compiler knows its size at compile-time. It just a case of using the same notation for two different things, something quite usual in C.

int
foo (int zap[])

is completely equivalent to

int
foo (int *zap)

The compiler doesn't have any idea how big zap could be (so it leaves the task of finding out to the programmer).

吹梦到西洲 2024-11-13 01:20:50

zip 是一个 6 * sizeof(int) 的内存块,因此它的大小为 24(在您的架构上)。
zap (它也可以在函数声明中写为 int *zap),但是可以指向任何内存地址,并且编译器无法知道从多少空间开始该(或什至包含该)地址已被分配。

zip is a memory block of 6 * sizeof(int) so it has a size of 24 (on your architecture).
zap (it could be also written as int *zap in your function declaration) however can point to any memory address and the compiler has no way of knowing how much space starting at this (or even containing this) address has been allocated.

向地狱狂奔 2024-11-13 01:20:50

zip 的大小在编译时已知,而 zap 的大小则未知。这就是为什么您在 sizeof(zap) 上获取指针的大小,并在 sizeof(zip) 上获取数组的大小。

The size of zip is known at compile time and the size of zap is not. That is why you are getting the size of a pointer on sizeof(zap) and the size of the array on sizeof(zip).

混吃等死 2024-11-13 01:20:50

在某些情况下,数组会退化为指针。函数调用就是其中之一。

There are some situations wherearrays decay to pointers. Function calls is one of those.

紫南 2024-11-13 01:20:50

因为它已经用 6 个元素静态初始化了。

because it has been statically initialized with 6 elemens.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文