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

#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;
}

不出所料,它返回5.

编辑:人们指出了this个答案,但语法确实有点不同,即索引方法

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

因此,我相信这两个问题都是合理的,并且对问题的处理方法略有不同.感谢大家的大力帮助和透彻的讲解!

推荐答案

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

减go 两个指针(前提是它们都指向同一个数组对象,或者其中一个指针指向数组的最后一个元素)将得到这两个指针之间的对象数(数组元素).

表达式&a产生a的地址,并具有int (*)[5]类型(指向int的5元素数组的指针).表达式&a + 1产生a之后int的下一个5元素数组的地址,并且还具有类型int (*)[5].表达式*(&a + 1)解引用&a + 1的结果,从而产生a的最后一个元素之后的第一个int的地址,并且具有int [5]类型,在本文中,int [5]"衰减"为int *类型的表达式.

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

图片可能有助于:

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

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

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

请注意,表达式*(&a + 1)的结果是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.

100, 6.5.6/9

C++相关问答推荐

字符串令牌化xpath表达式

如何将字符**传递给需要常量字符指针的常量数组的函数

为什么中断函数会以这种方式影响数组?

tick.q中的Kdb+键控表语法

在for循环中指向数组开头之前

如何在GET_STRING输入后对少数几个特定字符串进行C判断?

为什么Linux无法映射这个PT_LOAD ELF段?

如何在不读取整个字符串的情况下删除UTF8字符串的尾随空格以提高性能?

Linux分段故障(核心转储)

将复合文字数组用作临时字符串缓冲区是否合理?

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

在git补丁中自动添加C的宏

gdb - 你能找到持有内部 glibc 锁的线程吗?

在 C 中的 scanf() 格式说明符中使用宏获取字符串长度

c 函数指针,另一种语法

C 程序调用 malloc 导致总线错误?

在 C 语言中,不使用 sscanf 从字符串中读取数据

当最大成员是原始类型时,联合是否可以大于最大成员?

括号中的 C 函数声明显然永远调用自身,有什么意义?

使用指针与使用索引来访问数组的性能差异能有人解释一下吗?