sizeof如何知道操作数数组的大小?

发布于 2024-09-16 01:01:45 字数 118 浏览 9 评论 0原文

这可能是一个愚蠢的问题,但是当您不传入数组中的元素数量时, sizeof 运算符如何知道数组操作数的大小。我知道它不会返回数组中的总元素,而是返回字节大小,但为了得到它,它仍然必须知道数组何时结束。只是好奇这是如何工作的。

This may be a stupid question but how does the sizeof operator know the size of an array operand when you don't pass in the amount of elements in the array. I know it doesn't return the total elements in the array but the size in bytes, but to get that it still has to know when the array ends. Just curious as to how this works.

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

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

发布评论

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

评论(12

榆西 2024-09-23 01:01:45

sizeof 在编译时解释,编译器知道数组是如何声明的(以及它占用了多少空间)。在动态分配的数组上调用 sizeof 可能不会执行您想要的操作,因为(正如您提到的)未指定数组的终点。

sizeof is interpreted at compile time, and the compiler knows how the array was declared (and thus how much space it takes up). Calling sizeof on a dynamically-allocated array will likely not do what you want, because (as you mention) the end point of the array is not specified.

不打扰别人 2024-09-23 01:01:45

您难以理解这一点的潜在问题可能是因为您像许多人一样混淆了数组和指针。但是,数组不是指针double da[10] 是一个由十个 double 组成的数组,而不是 double*,当您询问时,编译器肯定知道这一点评估sizeof(da)。如果编译器知道 sizeof(double),您不会感到惊讶吗?

数组的问题在于,它们在许多上下文中会自动衰减为指向其第一个元素的指针(例如当它们传递给函数时)。但数组仍然是数组,指针仍然是指针。

The problem underlying your trouble to understand this might be because you are confusing arrays and pointers, as so many do. However, arrays are not pointers. A double da[10] is an array of ten double, not a double*, and that's certainly known to the compiler when you ask it evaluate sizeof(da). You wouldn't be surprised that the compiler knows sizeof(double)?

The problem with arrays is that they decay to pointers to their first elements automatically in many contexts (like when they are passed to functions). But still, array are arrays and pointers are pointers.

浮生未歇 2024-09-23 01:01:45

除了一种情况外,sizeof 在编译时就完成它的事情。在编译时,编译器会跟踪对象的完整类型[编辑:好吧,无论如何,它知道有关对象类型的所有信息 - 如果类型不完整,那么就不会不包含大小,尝试使用 sizeof 将失败],并且 sizeof 基本上只是将其中一条信息从编译器“导出”到正在编译的代码中,因此它本质上成为结果代码中的常量。

例外情况是 sizeof 应用于可变长度数组 (VLA)1。当应用于 VLA 时,sizeof 计算其操作数(否则不会计算),并生成 VLA 的实际大小。在这种情况下,结果不是常数。


<子>1。 VLA 在 C99 中正式成为 C 的一部分,但在此之前已有一些编译器支持它们。尽管不是 C++ 的正式组成部分,但某些编译器(例如 g++)也将 VLA 包含为 C++ 的扩展。

Except in one case, sizeof does it's thing at compile time. At compile time, the compiler keeps track of the full type of an object [Edit: well, everything it knows about the type of the object, anyway -- if the type isn't complete so that doesn't include the size, attempting to use sizeof will fail], and sizeof basically just "exports" one piece of that information from the compiler into the code being compiled, so it becomes essentially a constant in the resulting code.

The exception is when sizeof is applied to variable length array (VLA)1. When applied to a VLA, sizeof evaluates its operand (which it doesn't otherwise), and produces the actual size of the VLA. In this case, the result is not a constant.


1. VLAs officially became a part of C in C99, but some compilers supported them before that. Although not officially part of C++, some compilers (e.g., g++) include VLAs as an extension to C++ as well.

孤独陪着我 2024-09-23 01:01:45

编译器知道应用程序中每种类型的大小,并且 sizeof 只是请求编译器为您生成该值。

The compiler knows the size of each type in your application, and sizeof just requests the compiler to produce that value for you.

缘字诀 2024-09-23 01:01:45

Sizeof 是一个编译时运算符;它具有与编译器一样多的信息。 (显然编译器确实知道数组的大小)。

这就是为什么如果您在指针上调用 sizeof ,您将获得指针的宽度,而不是该指针指向的数组的大小。

Sizeof is a compile time operator; it has as much information as the compiler does. (And obviously the compiler does know the size of the array).

This is why if you call sizeof on a pointer you get the width of the pointer, not the size of the array to which that pointer points.

执手闯天涯 2024-09-23 01:01:45

Sizeof 只能应用于完全定义的类型。编译器要么能够在编译时确定大小(例如,如果您有像 int foo[8]; 这样的声明),要么能够确定必须添加代码来跟踪变量的大小-length 数组(例如,如果您有一个像 int foo[n+3]; 这样的声明)。

与此处的其他答案相反,请注意,从 C99 开始,sizeof() 不一定在编译时确定,因为数组可能是可变长度的。

Sizeof can only be applied to completely defined types. The compiler will either be able to determine the size at compile time (e.g., if you had a declaration like int foo[8];), or it will be able to determine that it has to add code to track the size of a variable-length array (e.g., if you had a declaration like int foo[n+3];).

Contrary to other answers here, note that as of C99, sizeof() is not necessarily determined at compile time, since arrays may be variable-length.

临走之时 2024-09-23 01:01:45

如果您在局部变量上使用 sizeof,它就会知道您声明了多少个元素。如果您在函数参数上使用 sizeof,它不会知道;它将参数视为指向数组的指针,sizeof 给出指针的大小。

If you're using sizeof on a local variable, it knows how many elements you declared. If you're using sizeof on a function parameter, it doesn't know; it treats the parameter as a pointer to the array and sizeof gives the size of a pointer.

梦萦几度 2024-09-23 01:01:45

引用自 wiki

这是我们的责任
编译器的作者实现
sizeof 运算符以特定的方式
对于给定的实现是正确的
语言。运算符的大小
必须考虑到
底层的实现
内存分配方案以获得
各种数据类型的大小。大小是
通常是一个编译时运算符,
意味着在编译过程中,sizeof
其操作数被替换为
结果值。这一点在
C 生成的汇编语言代码
或 C++ 编译器。为此原因,
sizeof 符合运算符的资格,甚至
尽管它的使用有时看起来像
函数调用。

Quote from wiki:

It is the responsibility of the
compiler's author to implement the
sizeof operator in a way specific and
correct for a given implementation of
the language. The sizeof operator
must take into account the
implementation of the underlying
memory allocation scheme to obtain the
sizes of various datatypes. sizeof is
usually a compile-time operator, which
means that during compilation, sizeof
and its operand get replaced by the
result-value. This is evident in the
assembly language code produced by a C
or C++ compiler. For this reason,
sizeof qualifies as an operator, even
though its use sometimes looks like a
function call.

濫情▎り 2024-09-23 01:01:45

sizeof 运算符“知道”所有原子数据类型的大小,因为结构体、联合体和数组可以仅通过组装原子类型来构造,很容易确定任何类型的数组的大小。它使用基本算术来确定复杂类型(在编译时)。

The sizeof operator 'knows' the size of all atomic datatypes, since structs, unions and arrays can only be constructed by assembling the atomic types it's easy to determine the size of array of any type. It uses basic arithmetic to determine complex types (during compile time).

黑寡妇 2024-09-23 01:01:45

sizeof通常在编译时评估。值得注意的例外是 C99 的可变长度数组。

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        int count = atoi(argv[1]);
        int someArray[count];

        printf("The size is %zu bytes\n", sizeof someArray);
    }
    else puts("No");
}

sizeof is usually evaluated at compile time. The notable exception is C99's variable length arrays.

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        int count = atoi(argv[1]);
        int someArray[count];

        printf("The size is %zu bytes\n", sizeof someArray);
    }
    else puts("No");
}
深海蓝天 2024-09-23 01:01:45

Sizeof 总是在编译时计算。在多遍编译器中,生成符号表时,编译器必须确定声明的每个符号的大小,以进一步生成中间代码。因此,代码中的所有 sizeof 引用都会替换为确切的值。在中间代码生成阶段,所有运算符、语句都被转换为正确的中间代码(ASM/其他格式)。最后,m/c 代码生成阶段将其转换为机器代码。

上面看到的一些关于与 sizeof 相关的动态分配的讨论根本不在上下文中。任何对 size(*p) 的引用,其中 p 是任何数据类型的指针,编译器只是找出 *p 的数据类型并替换其大小,而不是去检查分配块的 MCB 头来查看分配的是什么内存大小。它不是在运行时。例如双 *p; sizeof(*p) 仍然可以在不为指针 p 分配任何内存的情况下完成。怎么可能呢?

Sizeof is always evaluated at compile time. In multi pass compiler while generating the symbol table compiler must determine the size of each symbol declared to proceed further to generate intermediate code. So for all sizeof referrences in the code replaces the exact value. At intermediate code generation stage all the operators,statements are converted to right intermediate code (ASM/other format). Finally, m/c code generation stage it converts it to the machine code.

Some discussions seen above w.r.t the dynamic allocations relating to sizeof is not in the context at all. Any reference to size(*p) where p is a pointer of any data type , compiler just finds out the data type of *p and replaces its size , not go to check the MCB header of the allocated block to see what is the allocated memory size. It is not at run time. For example double *p; sizeof(*p) can still be done without allocating any memory for pointer p. How is it possible?

花海 2024-09-23 01:01:45

sizeof 在编译时计算。这就是为什么当您创建动态数组时,您按以下方式创建它。

char * array;
int size;
//Get size somehow.
array = malloc(size*(sizeof(char)));

// 现在在编译过程中,编译器确切地知道 char 的大小。因为它必须将它们在内存中对齐。此时,操作系统知道它必须分配多少大小。

另一方面,可变长度数组是在堆栈上创建的。但是任何 malloc 分配的内存都会在堆上创建。

sizeof is calculated at compile-time. This is why when you create a dynamic array you create it the following way.

char * array;
int size;
//Get size somehow.
array = malloc(size*(sizeof(char)));

// now during the compile the compiler knows for sure the size of char. since it has to align them on the memory. At this point it the OS knows how much size it has to allocate.

Variable length arrays on the other hand are created on the Stack. But any malloc allocated memory would be created on the heap.

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