这段代码如何在不使用 sizeof() 的情况下确定数组大小? [英] How does this piece of code determine array size without using sizeof( )?

查看:30
本文介绍了这段代码如何在不使用 sizeof() 的情况下确定数组大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过一些 C 面试问题,我发现了一个问题,说明如何在不使用 sizeof 运算符的情况下在 C 中找到数组的大小?",有以下解决方案.它有效,但我不明白为什么.

#include int main() {int a[] = {100, 200, 300, 400, 500};整数大小 = 0;大小 = *(&a + 1) - a;printf("%d\n", 大小);返回0;}

正如预期的那样,它返回 5.

人们指出这个答案,但语法确实有点不同,即索引方法

size = (&arr)[1] - arr;

所以我相信这两个问题都是有效的,并且解决问题的方法略有不同.感谢大家的大力帮助和详尽的解释!

解决方案

当你给一个指针加 1 时,结果是指向类型的对象序列(即数组)中下一个对象的位置).如果p 指向一个int 对象,那么p + 1 将指向一个序列中的下一个int.如果 p 指向 int 的 5 元素数组(在本例中为表达式 &a),则 p +1 将指向序列中下一个 5 元素的 int 数组.

将两个指针相减(假设它们都指向同一个数组对象,或者一个指向数组的最后一个元素之后的一个)得出这两个指针之间的对象(数组元素)的数量.

表达式&a 产生a 的地址,类型为int (*)[5](指向5- int 的元素数组).表达式&a + 1 产生a 之后的int 的下一个5 元素数组的地址,并且还有类型int (*)[5].表达式 *(&a + 1) 取消引用 &a + 1 的结果,从而产生第一个 int 的地址> 跟在 a 的最后一个元素之后,并且类型为 int [5],在这个上下文中它是decays"到 int * 类型的表达式.

类似地,表达式 a decays"指向数组第一个元素的指针,类型为int *.

一张图片可能有帮助:

int [5] int (*)[5] int int *+---+ +---+||<- &a ||<-a|- |+---+||||<- a + 1|- |+---+|||||- |+---+|||||- |+---+||||+---+ +---+||<- &a + 1 ||<- *(&a + 1)|- |+---+|||||- |+---+|||||- |+---+|||||- |+---+||||+---+ +---+

这是同一个存储的两个视图 - 在左侧,我们将其视为 int 的 5 元素数组的序列,而在右侧,我们将其视为int 的序列.我还展示了各种表达式及其类型.

请注意,表达式 *(&a + 1) 会导致未定义行为:

<块引用>...
如果结果指向数组对象的最后一个元素,则它不得用作被评估的一元 * 运算符的操作数.

C 2011 在线草案, 6.5.6/9

Going through some C interview questions, I've found a question stating "How to find the size of an array in C without using the sizeof operator?", with the following solution. It works, but I cannot understand why.

#include <stdio.h>

int main() {
    int a[] = {100, 200, 300, 400, 500};
    int size = 0;

    size = *(&a + 1) - a;
    printf("%d\n", size);

    return 0;
}

As expected, it returns 5.

edit: people pointed out this answer, but the syntax does differ a bit, i.e. the indexing method

size = (&arr)[1] - arr;

so I believe both questions are valid and have a slightly different approach to the problem. Thank you all for the immense help and thorough explanation!

解决方案

When you add 1 to a pointer, the result is the location of the next object in a sequence of objects of the pointed-to type (i.e., an array). If p points to an int object, then p + 1 will point to the next int in a sequence. If p points to a 5-element array of int (in this case, the expression &a), then p + 1 will point to the next 5-element array of int in a sequence.

Subtracting two pointers (provided they both point into the same array object, or one is pointing one past the last element of the array) yields the number of objects (array elements) between those two pointers.

The expression &a yields the address of a, and has the type int (*)[5] (pointer to 5-element array of int). The expression &a + 1 yields the address of the next 5-element array of int following a, and also has the type int (*)[5]. The expression *(&a + 1) dereferences the result of &a + 1, such that it yields the address of the first int following the last element of a, and has type int [5], which in this context "decays" to an expression of type int *.

Similarly, the expression a "decays" to a pointer to the first element of the array and has type int *.

A picture may help:

int [5]  int (*)[5]     int      int *

+---+                   +---+
|   | <- &a             |   | <- a
| - |                   +---+
|   |                   |   | <- a + 1
| - |                   +---+
|   |                   |   |
| - |                   +---+
|   |                   |   |
| - |                   +---+
|   |                   |   |
+---+                   +---+
|   | <- &a + 1         |   | <- *(&a + 1)
| - |                   +---+
|   |                   |   |
| - |                   +---+
|   |                   |   |
| - |                   +---+
|   |                   |   |
| - |                   +---+
|   |                   |   |
+---+                   +---+

This is two views of the same storage - on the left, we're viewing it as a sequence of 5-element arrays of int, while on the right, we're viewing it as a sequence of int. I also show the various expressions and their types.

Be aware, the expression *(&a + 1) results in undefined behavior:

...
If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

C 2011 Online Draft, 6.5.6/9

这篇关于这段代码如何在不使用 sizeof() 的情况下确定数组大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆