首页 文章

如何在C中确定数组的大小?

提问于
浏览
767

如何在C中确定数组的大小?

也就是说,阵列可以容纳的元素数量是多少?

20 回答

  • 969

    执行摘要:

    int a[17];
    size_t n = sizeof(a)/sizeof(a[0]);
    

    要确定数组的大小(以字节为单位),可以使用 sizeof 运算符:

    int a[17];
    size_t n = sizeof(a);
    

    在我的计算机上,int是4个字节长,所以n是68 .

    为了确定数组中元素的数量,我们可以将数组的总大小除以数组元素的大小 . 您可以使用类型执行此操作,如下所示:

    int a[17];
    size_t n = sizeof(a) / sizeof(int);
    

    并获得正确答案(68/4 = 17),但如果 a 的类型发生了变化,如果您忘记更改 sizeof(int) ,则会有一个令人讨厌的错误 .

    因此,首选除数是 sizeof(a[0]) ,即数组零点元素的大小 .

    int a[17];
    size_t n = sizeof(a) / sizeof(a[0]);
    

    另一个优点是,您现在可以轻松地在宏中参数化数组名称并获取:

    #define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))
    
    int a[17];
    size_t n = NELEMS(a);
    
  • 5

    sizeof 方式是正确的方式iff您正在处理未作为参数接收的数组 . 作为参数发送到函数的数组被视为指针,因此 sizeof 将返回指针's size, instead of the array' s .

    因此,在内部函数中,此方法不起作用 . 相反,始终传递一个额外的参数 size_t size ,表示数组中的元素数 .

    测试:

    #include <stdio.h>
    #include <stdlib.h>
    
    void printSizeOf(int intArray[]);
    void printLength(int intArray[]);
    
    int main(int argc, char* argv[])
    {
        int array[] = { 0, 1, 2, 3, 4, 5, 6 };
    
        printf("sizeof of array: %d\n", (int) sizeof(array));
        printSizeOf(array);
    
        printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
        printLength(array);
    }
    
    void printSizeOf(int intArray[])
    {
        printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
    }
    
    void printLength(int intArray[])
    {
        printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
    }
    

    输出(在64位Linux操作系统中):

    sizeof of array: 28
    sizeof of parameter: 8
    Length of array: 7
    Length of parameter: 2
    

    输出(在32位Windows操作系统中):

    sizeof of array: 28
    sizeof of parameter: 4
    Length of array: 7
    Length of parameter: 1
    
  • 1

    值得注意的是, sizeof 在处理已经衰减到指针的数组值时没有帮助:即使它指向数组的开头,对于编译器它也与指向单个元素的指针相同阵列 . 指针不会用于初始化它的数组的任何其他内容 .

    int a[10];
    int* p = a;
    
    assert(sizeof(a) / sizeof(a[0]) == 10);
    assert(sizeof(p) == sizeof(int*));
    assert(sizeof(*p) == sizeof(int));
    
  • 23

    “技巧”的大小是我所知道的最好的方式,其中一个很小但是(对我来说,这是一个主要的烦恼)使用括号的重要变化 .

    正如维基百科条目所表明的那样,C的 sizeof 不是一个函数;这是 operator . 因此,除了参数是类型名称之外,它不需要围绕其参数使用括号 . 这很容易记住,因为它使参数看起来像一个转换表达式,它也使用括号 .

    所以:如果你有以下内容:

    int myArray[10];
    

    您可以使用以下代码找到元素的数量:

    size_t n = sizeof myArray / sizeof *myArray;
    

    对我来说,这比使用括号的替代方案更容易阅读 . 我也赞成在分区的右侧使用星号,因为它比索引更简洁 .

    当然,这也是编译时间,因此无需担心影响程序性能的划分 . 所以尽可能使用此表单 .

    当你有一个而不是一个类型时,最好在实际对象上使用sizeof,因为那时你不必担心发出错误并说明错误的类型 .

    例如,假设您有一个函数可以将一些数据作为字节流输出,例如通过网络输出 . 让我们调用函数 send() ,并将其作为参数作为指向要发送的对象的指针,以及对象中的字节数 . 因此,原型变为:

    void send(const void *object, size_t size);
    

    然后你需要发送一个整数,所以你这样编码:

    int foo = 4711;
    send(&foo, sizeof (int));
    

    现在,通过在两个地方指定 foo 的类型,你已经介绍了一种微妙的射击方式 . 如果一个改变但另一个没改变,则代码中断 . 因此,总是这样做:

    send(&foo, sizeof foo);
    

    现在你受到了保护 . 当然,您复制变量的名称,但如果您更改它,则很可能以编译器可以检测到的方式中断 .

  • 4
    int size = (&arr)[1] - arr;
    

    请查看this link以获取解释

  • 41

    您可以使用sizeof运算符,但它不适用于函数,因为它将采用指针的引用,您可以执行以下操作来查找数组的长度:

    len = sizeof(arr)/sizeof(arr[0])
    

    最初在这里找到的代码:C program to find the number of elements in an array

  • 10

    如果您知道数组的数据类型,则可以使用以下内容:

    int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};
    
    int noofele = sizeof(arr)/sizeof(int);
    

    或者,如果您不知道数组的数据类型,可以使用以下内容:

    noofele = sizeof(arr)/sizeof(arr[0]);
    

    注意:只有在运行时未定义数组(如malloc)并且数组未在函数中传递时,此方法才有效 . 在这两种情况下, arr (数组名称)都是指针 .

  • 109

    每个人都在使用的宏 ARRAYELEMENTCOUNT(x) 评估 incorrectly . 实际上,这只是一个敏感问题,因为你可以't have expressions that result in an '数组'类型 .

    /* Compile as: CL /P "macro.c" */
    # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))
    
    ARRAYELEMENTCOUNT(p + 1);
    

    实际上评估为:

    (sizeof (p + 1) / sizeof (p + 1[0]));
    

    /* Compile as: CL /P "macro.c" */
    # define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])
    
    ARRAYELEMENTCOUNT(p + 1);
    

    它正确评估为:

    (sizeof (p + 1) / sizeof (p + 1)[0]);
    

    这显然与数组的大小没有太大关系 . 我刚刚注意到很多错误都没有真正观察C预处理器的工作原理 . 您总是包装宏参数,而不是可能涉及的表达式 .


    这是对的;我的例子很糟糕 . 但这实际上应该是应该发生的事情 . 正如我之前提到的那样 p + 1 将最终作为指针类型并使整个宏无效(就像你试图在带有指针的函数中使用宏一样)参数) .

    在一天结束时,在这个特定的实例中,故障并没有浪费每个人's time; huzzah!), because you don' t表达式的类型为'array' . 但是我认为关于预处理器评估小数的真正意义重大 .

  • 11

    您可以使用 & 运算符 . 这是源代码:

    #include<stdio.h>
    #include<stdlib.h>
    int main(){
    
        int a[10];
    
        int *p; 
    
        printf("%p\n", (void *)a); 
        printf("%p\n", (void *)(&a+1));
        printf("---- diff----\n");
        printf("%zu\n", sizeof(a[0]));
        printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));
    
    
        return 0;
    };
    

    这是示例输出

    1549216672
    1549216712
    ---- diff----
    4
    The size of array a is 10
    
  • 3

    对于 multidimensional arrays 来说,这有点复杂 . 通常人们定义明确的宏常数,即

    #define g_rgDialogRows   2
    #define g_rgDialogCols   7
    
    static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
    {
        { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
        { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
    };
    

    但是这些常量也可以在编译时使用sizeof进行评估:

    #define rows_of_array(name)       \
        (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
    #define columns_of_array(name)    \
        (sizeof(name[0]) / sizeof(name[0][0]))
    
    static char* g_rgDialog[][7] = { /* ... */ };
    
    assert(   rows_of_array(g_rgDialog) == 2);
    assert(columns_of_array(g_rgDialog) == 7);
    

    请注意,此代码适用于C和C.对于具有两个以上维度的数组使用

    sizeof(name[0][0][0])
    sizeof(name[0][0][0][0])
    

    无限的,无限的 .

  • 659

    C中数组的大小:

    int a[10];
    size_t size_of_array = sizeof(a);      // Size of array a
    int n = sizeof (a) / sizeof (a[0]);    // Number of elements in array a
    size_t size_of_element = sizeof(a[0]); // Size of each element in array a                                          
                                           // Size of each element = size of type
    
  • 3
    sizeof(array) / sizeof(array[0])
    
  • 20
    #define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))
    
  • 15

    “你已经介绍了一种在脚下射击自己的微妙方式”

    C'原生'数组不存储它们的大小 . 因此,建议将数组的长度保存在单独的变量/ const中,并在每次传递数组时传递它,即:

    #define MY_ARRAY_LENGTH   15
    int myArray[MY_ARRAY_LENGTH];
    

    你应该总是避免使用原生数组(除非你不能,在这种情况下,请注意你的脚) . 如果您正在编写C,请使用STL 's ' vector'容器 . "Compared to arrays, they provide almost the same performance",它们更有用!

    // vector is a template, the <int> means it is a vector of ints
    vector<int> numbers;  
    
    // push_back() puts a new value at the end (or back) of the vector
    for (int i = 0; i < 10; i++)
        numbers.push_back(i);
    
    // Determine the size of the array
    cout << numbers.size();
    

    见:http://www.cplusplus.com/reference/stl/vector/

  • 14

    @ Magnus:标准将sizeof定义为产生对象中的字节数,而sizeof(char)始终为1 . 字节中的位数是特定于实现的 .

    编辑:ANSI C标准部分5.3.3 Sizeof:

    sizeof运算符产生其操作数的对象表示中的字节数 . [...] sizeof(char),sizeof(signed char)和sizeof(unsigned char)为1; sizeof应用于任何其他基本类型的结果是实现定义的 .

    第1.6节C内存模型:

    C存储器模型中的基本存储单元是字节 . 字节至少足以包含基本执行字符集的任何成员,并且由连续的位序列组成,其数量是实现定义的 .

  • 8

    @Skizz:我很确定我是对的,虽然我现在可以给你的最好的“来源”是维基百科,来自关于sizeof的文章:

    维基百科错了,Skizz是对的 . 根据定义,sizeof(char)是1 .

    我的意思是,只要仔细阅读维基百科条目,就会发现这是错误的 . "multiples of char" . sizeof(char) 永远不能是"1"以外的任何东西 . 如果它是2,则意味着 sizeof(char) 的大小是char的两倍!

  • 4

    如果你真的想这样做来传递你的数组我建议实现一个结构来存储一个指向你想要一个数组的类型的指针和一个表示数组大小的整数 . 然后你可以将它传递给你的功能 . 只需将数组变量值(指向第一个元素的指针)分配给该指针即可 . 然后你可以去 Array.arr[i] 获取第i个元素并使用 Array.size 来获取数组中的元素数量 .

    我为你提供了一些代码 . 它不是很有用,但您可以使用更多功能扩展它 . 说实话,如果这些是您想要的东西,您应该停止使用C并使用内置这些功能的其他语言 .

    /* Absolutely no one should use this...
       By the time you're done implementing it you'll wish you just passed around
       an array and size to your functions */
    /* This is a static implementation. You can get a dynamic implementation and 
       cut out the array in main by using the stdlib memory allocation methods,
       but it will work much slower since it will store your array on the heap */
    
    #include <stdio.h>
    #include <string.h>
    /*
    #include "MyTypeArray.h"
    */
    /* MyTypeArray.h 
    #ifndef MYTYPE_ARRAY
    #define MYTYPE_ARRAY
    */
    typedef struct MyType
    {
       int age;
       char name[20];
    } MyType;
    typedef struct MyTypeArray
    {
       int size;
       MyType *arr;
    } MyTypeArray;
    
    MyType new_MyType(int age, char *name);
    MyTypeArray newMyTypeArray(int size, MyType *first);
    /*
    #endif
    End MyTypeArray.h */
    
    /* MyTypeArray.c */
    MyType new_MyType(int age, char *name)
    {
       MyType d;
       d.age = age;
       strcpy(d.name, name);
       return d;
    }
    
    MyTypeArray new_MyTypeArray(int size, MyType *first)
    {
       MyTypeArray d;
       d.size = size;
       d.arr = first;
       return d;
    }
    /* End MyTypeArray.c */
    
    
    void print_MyType_names(MyTypeArray d)
    {
       int i;
       for (i = 0; i < d.size; i++)
       {
          printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
       }
    }
    
    int main()
    {
       /* First create an array on the stack to store our elements in.
          Note we could create an empty array with a size instead and
          set the elements later. */
       MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
       /* Now create a "MyTypeArray" which will use the array we just
          created internally. Really it will just store the value of the pointer
          "arr". Here we are manually setting the size. You can use the sizeof
          trick here instead if you're sure it will work with your compiler. */
       MyTypeArray array = new_MyTypeArray(2, arr);
       /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
       print_MyType_names(array);
       return 0;
    }
    
  • -1

    最好的方法是保存此信息,例如,在结构中:

    typedef struct {
         int *array;
         int elements;
    } list_s;
    

    实现所有必要的功能,例如创建,销毁,检查相等以及您需要的所有其他功能 . 作为参数传递更容易 .

  • 14

    函数 sizeof 返回数组在内存中使用的字节数 . 如果要计算数组中元素的数量,则应将该数字除以数组的 sizeof 变量类型 . 假设 int array[10]; ,如果计算机中的变量类型整数是32位(或4个字节),为了获得数组的大小,您应该执行以下操作:

    int array[10];
    int sizeOfArray = sizeof(array)/sizeof(int);
    

相关问题