【问题标题】:Why the pointer hack for finding the size of an array in C giving different value when used in a called function [duplicate]为什么在被调用函数中使用时指针破解用于在 C 中查找数组的大小给出不同的值[重复]
【发布时间】:2018-12-05 23:01:30
【问题描述】:

这是说明问题的以下代码:

#include <stdio.h>

void func(int arr[]);

int main() {
    int arr[10];
    int n = *(&arr + 1) - arr;
    printf("%d\n", n);
    func(arr);
    return 0;
}

void func(int arr[]) {
    int n = *(&arr + 1) - arr;
    printf("%d\n", n);
}

以上代码的输出为:

10
268435906

【问题讨论】:

  • int n=*(&amp;arr+1)-arr;..你确定吗?
  • @SouravGhosh 不,这是正确的(因为它很可能会工作,即使它在技术上是无效的)。 &amp;arr + 1 是一个指向数组的指针,解除对它的引用(即*(&amp;arr + 1)),你会得到一个数组,然后它会衰减为指向其第一个元素的指针(它将指向arr 末尾之外的一个元素,即有效地指向arr[10])。
  • @JensGustedt:这个问题不是完全重复的,它使用不同的表达式来计算数组大小。

标签: c arrays function


【解决方案1】:

尽管使用语法定义void func(int arr[]),函数func 接收指向数组第一个元素的指针。 void func(int *arr) 的定义更清晰。

表达式*(&amp;arr+1)-arr 在编译时计算数组元素的数量如果arr 被定义为一个数组。如果arr 是指针,它会在指针之后取消引用内存并减去指针值,这是没有意义的,并且在大多数情况下具有未定义的行为。

获取数组元素个数的更常见(也更易读)的表达式是

n = sizeof(arr) / sizeof(*arr);

如果arr 是一个数组,则将其大小(以字节为单位)除以元素的大小(以字节为单位)得出元素的数量。表达式在编译时进行评估,没有运行时开销。如果arr 是一个指针,则将其大小除以它指向的类型的大小是已定义的,但没用,就像您的表达式一样。

【讨论】:

    【解决方案2】:

    每当数组作为参数传递给函数时,它们都会衰减为函数参数中的指针。

    C FAQ

    由于数组会立即衰减为指针,因此数组永远不会 实际上传递给一个函数。你可以假装一个函数 接收一个数组作为参数,并通过声明 对应的参数为数组:

    void f(char a[]) { ... }

    数组arr 的名称被编译器衰减为指向数组第一个元素的指针。因此,取消引用指针会产生存储在数组第一个位置的值。

    【讨论】:

      【解决方案3】:

      在函数中声明数组参数时,它根本不是数组,而是一个指针

      声明

      void funct(int arr[]);
      

      实际上等于

      void funct(int *arr);
      

      这就是您看到的结果之间的差异。在main 函数中&amp;arr 是指向数组的指针,但在func 中,表达式&amp;arr 是指向指针变量 的指针。这两个指针非常不同。

      【讨论】:

        猜你喜欢
        • 2019-11-13
        • 2017-03-24
        • 2018-02-20
        • 1970-01-01
        • 2016-11-20
        • 1970-01-01
        • 2014-05-04
        • 2019-07-10
        • 2022-01-17
        相关资源
        最近更新 更多