C 数组指针如何存储其大小?

C 数组指针如何存储其大小?,c,arrays,pointers,C,Arrays,Pointers,结果显而易见: #include "stdio.h" #define COUNT(a) (sizeof(a) / sizeof(*(a))) void test(int b[]) { printf("2, count:%d\n", COUNT(b)); } int main(void) { int a[] = { 1,2,3 }; printf("1, count:%d\n", COUNT(a)); test(a); return 0; } 我的问题是: 声明“a

结果显而易见:

#include "stdio.h"

#define COUNT(a) (sizeof(a) / sizeof(*(a)))

void test(int b[]) {
  printf("2, count:%d\n", COUNT(b));
}

int main(void) {
  int a[] = { 1,2,3 };

  printf("1, count:%d\n", COUNT(a));
  test(a);

  return 0;
}
我的问题是:

  • 声明“a”时,长度(计数/大小)信息存储在哪里
  • 为什么在将“a”传递给test()函数时,长度(计数/大小)信息会丢失
  • 没有
  • 因为它一开始就没有储存

  • main()
    中引用数组时,实际的数组声明定义是可见的,因此
    sizeof(a)
    以字节为单位给出数组的大小

    当您在函数中引用数组时,参数实际上是“
    void test(int*b)
    ,指针的大小除以它指向的对象的大小,在32位平台上正好是1,而在具有LP64体系结构的64位平台上(或者在像Windows-64这样的LLP64平台上)则是2)因为指针是8字节,
    int
    是4字节

    没有一种通用的方法来确定传入函数的数组的大小;您必须显式地手动传递它


    从评论中可以看出:

    我还有两个问题:

  • 您所说的“.实际声明是可见的…”是什么意思?[T] 编译器(或操作系统)可以通过sizeof(a)函数获取长度信息吗
  • 为什么指针&(a[0])不包含作为指针“a”的长度信息
  • 我认为你在学习C或其他更现代的语言之前就已经学习了Java。最终,它归结为“因为这就是C的定义方式”。操作系统不参与;这纯粹是一个编译器问题

    • sizeof()
      是运算符,而不是函数。除非您处理的是VLA(可变长度数组),否则它将在编译时进行计算,并且是一个常量值
    main()
    中,数组定义(当我说“声明”时我说错了)就在那里,当
    sizeof()
    操作符应用于实际数组的名称时(与函数的数组参数相反),返回的大小就是数组的大小(以字节为单位)

  • 因为这是C而不是Algol,Pascal,Java,C#

    C不存储数组周期的大小。这是生活中的事实。并且,当数组被传递给函数时,大小信息不被传递给函数;数组“衰减”为指向数组第0个元素的指针,并且只传递该指针

  • 声明“a”时,长度(计数/大小)信息存储在哪里
  • 没有。顺便说一句,这个问题没有意义

  • 为什么在将“a”传递给test()函数时,长度(计数/大小)信息会丢失
  • 数组在传递给函数时衰减为指针(指向第一个元素)。所以答案是“无处可寻”,与前面的问题类似,这个问题同样没有任何意义。

    在C语言中没有“数组指针”这样的东西

    大小不存储在任何位置
    a
    不是指针,
    a
    int[3]
    类型的对象,这是编译器在编译时所熟知的事实。因此,当您要求编译器在编译时计算
    sizeof(a)/sizeof(*a)
    时,编译器知道答案是
    3

    当您将
    a
    传递给函数时,您有意要求编译器将数组类型转换为指针类型(因为您将函数参数声明为指针)。对于指针,
    sizeof
    表达式会产生完全不同的结果

  • 声明“a”时,长度(计数/大小)信息存储在哪里
  • 它没有存放在任何地方。
    sizeof
    运算符(在
    COUNT()
    宏中使用)返回整个数组的大小,当它被指定一个真数组作为操作数时(就像在第一个
    printf()中一样)

  • 为什么在将“a”传递给test()函数时,长度(计数/大小)信息会丢失 不幸的是,在C语言中,函数的数组参数是虚构的。数组不能传递给函数;该参数被视为指针,函数调用中传递的数组参数被“衰减”为简单指针。
    sizeof
    运算符返回指针的大小,该大小与用作参数的数组大小无关

    作为一个旁注,C++中可以有一个函数参数作为数组的引用,在这种情况下,函数的完整数组类型是可用的(即,参数不会衰减为指针,而<代码> 将返回完整数组的大小)。但是,在这种情况下,参数必须与数组类型完全匹配(包括元素的数量),这使得该技术仅对模板最有用

    例如,下面的C++程序会实现你所期望的:

    1, count:3
    2, count:1
    
    #包括“stdio.h”
    #定义计数(a)(sizeof(a)/sizeof(*(a)))
    模板
    无效测试(int&b)[T]){
    printf(“2,计数:%d\n,计数(b));
    }
    int main(int argc,char*argv[]){
    int a[]={1,2,3};
    printf(“1,计数:%d\n,计数(a));
    测试(a);
    返回0;
    }
    
    数组指针不存储大小。但是,
    []
    类型实际上不是指针。这是另一种类型。当你说
    inta[]={1,2,3}
    您定义了一个包含3个元素的数组,由于它是这样定义的,所以sizeof(a)给出了整个数组的大小

    然而,当您将参数声明为int a[]时,它与int*a几乎相同,sizeof(a)将是指针的大小(这可能与
    int
    的大小相同,但并不总是相同)

    在C语言中,无法将大小存储在指针类型中,因此如果需要大小,则必须将其作为附加参数传递或使用
    struct

    #include "stdio.h"
    
    #define COUNT(a) (sizeof(a) / sizeof(*(a)))
    
    template <int T>
    void test(int (&b)[T]) {
      printf("2, count:%d\n", COUNT(b));
    }
    
    int main(int argc, char *argv[]) {
      int a[] = { 1,2,3 };
    
      printf("1, count:%d\n", COUNT(a));
      test(a);
    
      return 0;
    }
    
    它没有存储。编译器知道a是什么,因此知道它的大小。因此编译器可以用实际大小替换
    sizeof()

    1. Where is the length(count/size) info stored when "a" is declared?
    
    在这种情况下,b被声明为p
    2. Why is the length(count/size) info lost when "a" is passed to the test() function?