如何找到数组中的元素数量?

问题描述 投票:42回答:12

我有一个int数组,我需要找到它中的元素数量。我知道这与sizeof有关,但我不确定如何使用它。

c arrays sizeof
12个回答
38
投票

如果你的数组在范围内,你可以使用sizeof来确定它的大小(以字节为单位)并使用除法来计算元素的数量:

#define NUM_OF_ELEMS 10
int arr[NUM_OF_ELEMS];
size_t NumberOfElements = sizeof(arr)/sizeof(arr[0]);

如果您将数组作为函数参数接收或在堆中分配数组,则无法使用sizeof确定其大小。你必须以某种方式存储/传递大小信息才能使用它:

void DoSomethingWithArray(int* arr, int NumOfElems)
{
    for(int i = 0; i < NumOfElems; ++i) {
        arr[i] = /*...*/
    }
}

0
投票

超级容易。

只需使用sizeof()将分配的字节数除以数组数据类型的字节数。

例如。给定一个名为myArray的整数数组

int numArrElements = sizeof(myArray) / sizeof(int);

现在,如果数组的数据类型不是常数并且可能会更改,则使等式中的除数使用第一个值的大小作为数据类型的大小

EG

int numArrElements = sizeof(myArray) / sizeof(myArray[0]);

-1
投票

我大多发现一种简单的方法来执行循环内部的数组长度

 int array[] = {10, 20, 30, 40};
 int i;
 for (i = 0; i < array[i]; i++) {
    printf("%d\n", array[i]);
 }

-4
投票

实际上,没有适当的方法来计算动态整数数组中的元素。但是,sizeof命令在Linux中正常工作,但在Windows中无法正常工作。从程序员的角度来看,不建议使用sizeof来获取动态数组中的元素数量。我们应该在制作数组时跟踪元素的数量。


17
投票
int a[20];
int length;
length = sizeof(a) / sizeof(int);

并且您可以使用其他方法使您的代码不被硬编码为int

假如你有一个数组array

你只需要:

int len = sizeof(array) / sizeof(array[0]);

10
投票

我个人认为sizeof(a)/ sizeof(* a)看起来更干净。

我也更喜欢将它定义为宏:

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

然后你可以在for循环中使用它,因此:

for (i = 0; i < NUM(a); i++)

5
投票

除非是字符数组,否则无法找到数组中的元素数。考虑以下示例:

int main()
{
    int arr[100]={1,2,3,4,5};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("%d", &size);
    return 1;
}

即使元素数为5,上面的值也给出了值100。如果它是一个字符数组,您可以线性搜索数组末尾的空字符串,并在您通过时增加计数器。


2
投票

我使用上面建议的以下代码来评估我的二维数组中的元素数量:

#include <stdio.h>
#include <string.h>

void main(void)
{
    char strs[3][20] =
    {
        {"January"},
        {"February"},
        {""}
    };

    int arraysize = sizeof(strs)/sizeof(strs[0]);

    for (int i = 0; i < arraysize; i++)
    {
        printf("Month %d is: %s\n", i, strs[i]);
    }

}

它工作得很好。据我所知,你不能在C数组中混淆不同的数据类型,并且你应该拥有所有数组元素的相同大小(如果我是对的),因此你可以利用这个小技巧来利用它:

  1. 计数整数2d数组中sizeof()函数的字节数(在本例中为3 * 20 = 60字节)
  2. 使用sizeof()函数计算第一个数组元素strs [0]的字节数(在本例中为20个字节)
  3. 将整个大小除以一个元素的大小,这将给你元素的数量

对于C中的2d数组,此剪切应该是可移植的,但是在其他编程语言中,它无法工作,因为您可以在不同大小的数组中使用不同的数据类型(如JAVA中)。


2
投票
#include<stdio.h>
int main()
{
    int arr[]={10,20,30,40,50,60};
    int *p;
    int count=0;

    for(p=arr;p<&arr+1;p++)
        count++;

    printf("The no of elements in array=%d",count);

    return 0;
}

OUTPUT = 6

说明

p是指向一维数组的指针,在循环for(p=arr,p<&arr+1;p++)中,我使p指向基址。假设它的基地址是1000;如果我们增加p然后它指向1002,依此类推。现在来看&arr的概念 - 它基本上代表整个数组,如果我们在整个数组中加1,即&arr+1,它给出地址1012,即下一个1-D数组的地址(在我们的例子中,int的大小是2),因此条件变为1000 <1012。

所以,基本上情况变成了

for(p=1000;p<1012;p++)

现在让我们检查条件并计算值

  • 第一次p=1000p<1012条件是true:进入循环,将count的值增加到1。
  • 第二次p=1002p<1012条件是true:进入循环,将count的值增加到2。
  • ...
  • 第6次p=1010p<1012条件是true:进入循环,将count的值增加到6。
  • 上次p=1012p<1012条件为假:在count=6声明中打印printf的值。

0
投票

如果我们不知道数组中元素的数量以及用户在运行时何时给出输入。然后我们可以编写代码

C代码:

while(scanf("%d",&array[count])==1) { 
  count++;
}

C ++代码:

while(cin>>a[count]) {
  count++;
}

现在,计数将具有输入的数组元素的数量。


0
投票

问题很简单:给定一个C ++数组(例如x中的int x[10]),你将如何获得其中的元素数量?

一个明显的解决方案是以下宏(定义1):

#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )

我不能说这是不正确的,因为当你给它一个数组它确实给出了正确的答案。但是,当您提供不是数组的东西时,相同的表达式会让您感到虚假。例如,如果你有

int * p;

然后countof( p )总是在一台机器上给你1,其中int指针和int具有相同的大小(例如在Win32平台上)。

此宏还错误地接受具有成员函数operator []的类的任何对象。例如,假设你写

class IntArray {
private:
    int * p;
    size_t size;
public:
    int & operator [] ( size_t i );
} x;

那么sizeof( x )将是x对象的大小,而不是x.p指向的缓冲区的大小。因此,你不会得到countof( x )的正确答案。

因此我们得出结论,定义1并不好,因为编译器不会阻止您滥用它。它无法强制只传入一个数组。

什么是更好的选择?

好吧,如果我们希望编译器确保countof的参数始终是一个数组,我们必须找到一个只允许数组的上下文。相同的上下文应该拒绝任何非数组表达式。

一些初学者可能会尝试这个(定义2):

template <typename T, size_t N>
size_t countof( T array[N] )
{
   return N;
}

他们认为,这个模板函数将接受N个元素的数组并返回N.

不幸的是,这不能编译,因为C ++将数组参数视为与指针参数相同,即上面的定义相当于:

template <typename T, size_t N>
size_t countof( T * array )
{
    return N;
}

现在很明显,函数体无法知道N是什么。

但是,如果函数需要数组引用,则编译器会确保实际参数的大小与声明匹配。这意味着我们可以通过一个小修改使定义2工作(定义3):

template <typename T, size_t N>
size_t countof( T (&array)[N] )
{
    return N;
}

这个计数非常有效,你不能通过给它一个指针来欺骗它。但是,它是一个功能,而不是宏。这意味着您不能在需要编译时常量的地方使用它。特别是,你不能写像:

int x[10];

int y[ 2*countof(x) ]; // twice as big as x

我们可以做些什么吗?

有人(我不知道它是谁 - 我只是在一段来自未知作者的代码中看到它)提出了一个聪明的想法:将N从函数体转移到返回类型(例如使函数返回一个N元素的数组),然后我们可以获得N的值而不实际调用该函数。

确切地说,我们必须使函数返回一个数组引用,因为C ++不允许您直接返回数组。

这个的实现是:

template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];

#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))

不可否认,语法看起来很糟糕。实际上,一些解释是必要的。

首先,顶级的东西

char ( &_ArraySizeHelper( ... ))[N];

_ArraySizeHelper是一个函数,它返回一个引用(注意&)到N个元素的char数组。

接下来,函数参数是

T (&array)[N]

这是对N个元素的T数组的引用。

最后,countof被定义为函数_ArraySizeHelper的结果的大小。注意我们甚至不需要定义_ArraySizeHelper(), - 声明就足够了。

有了这个新定义,

int x[10];

int y[ 2*countof(x) ]; // twice as big as x

变得有效,就像我们想要的那样。

我现在开心吗?好吧,我认为这个定义肯定比我们访问过的其他定义更好,但它仍然不是我想要的。首先,它不适用于函数内定义的类型。这是因为模板函数_ArraySizeHelper需要一个可在全局范围内访问的类型。

我没有更好的解决方案。如果您知道,请告诉我。


0
投票

sizeof返回它的参数的字节大小。这不是你想要的,但它可以帮助你。

假设你有一个数组:

int array[4];

如果将sizeof应用于数组(sizeof(array)),它将返回其大小(以字节为单位),在这种情况下,它的大小为int的4 *,因此总共可能为16个字节(取决于您的实现)。

如果将sizeof应用于数组的元素(sizeof(array[0])),它将返回其大小(以字节为单位),在本例中为int的大小,因此总共可能有4个字节(取决于您的实现)。

如果你将第一个除以第二个,它将是:(4 * int的大小)/(int的大小)= 4;这正是你想要的。

所以这应该做:

sizeof(array) / sizeof(array[0])

现在您可能希望有一个宏来封装这个逻辑,而不必再考虑应该如何完成它:

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

您需要括起所有宏的括号,就像在任何其他复杂的宏中一样,并且还包含每个变量,以避免与运算符优先级相关的意外错误。

现在你可以在任何这样的数组上使用它:

int array[6];
ptrdiff_t nmemb;

nmemb = ARRAY_SIZE(array);
/* nmemb == 6 */

请记住,声明为数组的函数的参数不是真正的数组,而是指向数组的第一个元素的指针,因此这对它们不起作用:

void foo(int false_array[6])
{
        ptrdiff_t nmemb;

        nmemb = ARRAY_SIZE(false_array);
        /* nmemb == sizeof(int *) / sizeof(int) */
        /* (maybe  ==2) */
}

但是如果将指针传递给数组而不仅仅是数组,它可以在函数中使用:

void bar(int (*arrptr)[7])
{
        ptrdiff_t nmemb;

        nmemb = ARRAY_SIZE(*arrptr);
        /* nmemb == 7 */
}
© www.soinside.com 2019 - 2024. All rights reserved.