我有一个int
数组,我需要找到其中的元素数。我知道它与它有关,sizeof
但我不确定如何准确使用它。
16 回答
如果您的数组在范围内,您可以使用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] = /*...*/
}
}
int a[20];
int length;
length = sizeof(a) / sizeof(int);
并且您可以使用另一种方法使您的代码不会被硬编码为int
说如果你有一个数组array
你只需要:
int len = sizeof(array) / sizeof(array[0]);
我个人认为 sizeof(a) / sizeof(*a) 看起来更干净。
我也更喜欢将其定义为宏:
#define NUM(a) (sizeof(a) / sizeof(*a))
然后你可以在for循环中使用它,因此:
for (i = 0; i < NUM(a); i++)
除非它是字符数组,否则不可能找到数组中元素的数量。考虑下面的例子:
int main()
{
int arr[100]={1,2,3,4,5};
int size = sizeof(arr)/sizeof(arr[0]);
printf("%d", size);
return 1;
}
即使元素的数量是五个,上面的值也给我们值 100。如果它是一个字符数组,您可以在数组末尾线性搜索空字符串,并在遍历时增加计数器。
实际上,我们无法计算数组中存储了多少元素
但是您可以使用 sizeof 运算符找到数组长度或大小。
但是为什么我们找不到我的数组中有多少元素。
因为当我们初始化一个数组编译器时,我们会在我们的程序上提供内存,比如 a[10](10 个大小为 4 的块),如果我们将某个值放在某个索引中,例如 a[0]=1,a[1],那么每个块都有垃圾值=2,a[3]=8; 并且其他块具有垃圾值没有人可以分辨哪个值是垃圾,哪个值不是垃圾 ,这就是我们无法计算数组中有多少元素的原因。我希望这能帮助你理解。小概念
超级容易。
只需将分配的字节数除以数组数据类型的字节数,使用sizeof()
.
例如,给定一个名为myArray
int numArrElements = sizeof(myArray) / sizeof(int);
现在,如果您的数组的数据类型不是常量并且可能会改变,那么让等式中的除数使用第一个值的大小作为数据类型的大小。
例如:
int numArrElements = sizeof(myArray) / sizeof(myArray[0]);
这样,代码与类型无关,无论数组的数据类型如何,都可以正常运行。
我使用上面建议的以下代码来评估二维数组中的元素数量:
#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 数组中混合不同的数据类型,并且所有数组元素的大小应该相同(如果我是对的),因此您可以通过这个小技巧来利用它:
- 使用 sizeof() 函数从整个二维数组中计算字节数(在本例中为 3*20 = 60 字节)
- 使用 sizeof() 函数从第一个数组元素 strs[0] 计算字节数(在本例中为 20 个字节)
- 将整个大小除以一个元素的大小什么会给你元素的数量
这个片段应该可以移植到 C 中的二维数组,但是在其他编程语言中它不能工作,因为你可以在不同大小的数组中使用不同的数据类型(比如在 JAVA 中)。
问题很简单:给定一个 C++ 数组(例如x
)int x[10]
,您将如何获得其中的元素数量?
一个明显的解决方案是以下宏(定义 1):
#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )
我不能说这是不正确的,因为当你给它一个数组时它确实给出了正确的答案。但是,当您提供不是数组的东西时,相同的表达式会给您一些虚假的东西。例如,如果您有
int * p;
然后countof( p )
总是在 int 指针和 int 大小相同的机器上给你 1 (例如在 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 是什么。
但是,如果一个函数需要一个数组引用,那么编译器会确保实际参数的大小与声明相匹配。这意味着我们可以通过小修改(定义 3)使定义 2 工作:
template <typename T, size_t N>
size_t countof( T (&array)[N] )
{
return N;
}
这个 countof 工作得很好,你不能通过给它一个指针来欺骗它。但是,它是一个函数,而不是宏。这意味着您不能在需要编译时间常数的地方使用它。特别是,您不能编写如下内容:
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];
say_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
需要在全局范围内可访问的类型。
我没有更好的解决方案。如果你知道一个,请告诉我。
#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;
}
输出=6
解释
p
是一个指向一维数组的指针,在循环中for(p=arr,p<&arr+1;p++)
我p
指向基地址。假设它的基地址是1000;如果我们递增p
,那么它指向 1002,依此类推。现在来到这个概念&arr
- 它基本上代表整个数组,如果我们将 1 添加到整个数组 ie &arr+1
,它会给出地址 1012 ,即下一个一维数组的地址(在我们的例子中 int 的大小是 2) ,因此条件变为 1000<1012。
所以,基本上条件变成了
for(p=1000;p<1012;p++)
现在让我们检查条件并计算值
- 第一次
p=1000
和p<1012
条件是true
:进入循环,将值递增count
到 1。 - 第二次
p=1002
和p<1012
条件是true
:进入循环,将值count
增加到2。 - ...
- 第 6 次
p=1010
和p<1012
条件是true
:进入循环,将值count
增加到 6。 - 上次
p=1012
和p<1012
条件为假:打印count=6
inprintf
语句的值。
void numel(int array1[100][100])
{
int count=0;
for(int i=0;i<100;i++)
{
for(int j=0;j<100;j++)
{
if(array1[i][j]!='\0')
{
count++;
//printf("\n%d-%d",array1[i][j],count);
}
else
break;
}
}
printf("Number of elements=%d",count);
}
int main()
{
int r,arr[100][100]={0},c;
printf("Enter the no. of rows: ");
scanf("%d",&r);
printf("\nEnter the no. of columns: ");
scanf("%d",&c);
printf("\nEnter the elements: ");
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
scanf("%d",&arr[i][j]);
}
}
numel(arr);
}
这显示了矩阵中元素的确切数量,而与您在初始化时提到的数组大小无关(如果这就是您的意思)
只有以这种格式声明数组时,我们才能找到数组中的元素数量
int a[]={1,2,3,4,5,6};
数组中的元素数是
n=sizeof(a) / sizeof(a[0]);
如果这样声明,我们应该无法计算数组大小int a[10]={1,2,3,4,5,6}
我主要找到了一种简单的方法来执行循环内的数组长度,就像那样
int array[] = {10, 20, 30, 40};
int i;
for (i = 0; i < array[i]; i++) {
printf("%d\n", array[i]);
}
sizeof
返回其参数的字节大小。这不是你想要的,但它可以提供帮助。
假设您有一个数组:
int array[4];
如果您应用sizeof
到数组 ( sizeof(array)
),它将返回其大小(以字节为单位),在这种情况下是 4 * 的大小int
,因此总共可能是 16 个字节(取决于您的实现)。
如果您应用sizeof
到数组 ( sizeof(array[0])
) 的一个元素,它将返回其大小(以字节为单位),在这种情况下是 an 的大小int
,因此总共可能是 4 个字节(取决于您的实现)。
如果将第一个除以第二个,它将是: (4 * an 的大小int
) / (an 的大小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 */
}
假设您有一个包含 elements 的数组1,3,4
。要知道它的长度,您需要使用sizeof
如下函数:
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
您可以通过打印输出来检查元素的数量,如下所示:
cout<<"This array has " << len << " elements";
完整的程序如下:
#include <iostream>
using namespace std;
int main()
{
int myArray[] = {1,3,4};
int len = sizeof(myArray) / sizeof(myArray[0]);
cout<<"The array has " << len << "elements";
return 0;
}
如果我们不知道数组中的元素数量以及用户在运行时何时给出输入。然后我们可以把代码写成
C代码:
while(scanf("%d",&array[count])==1) {
count++;
}
C++代码:
while(cin>>a[count]) {
count++;
}
现在计数将具有输入的数组元素的数量。
实际上,没有合适的方法来计算动态整数数组中的元素。但是,sizeof 命令在 Linux 中可以正常工作,但在 Windows 中不能正常工作。从程序员的角度来看,不建议使用 sizeof 来取动态数组中的元素个数。在制作数组时,我们应该跟踪元素的数量。