C 如何计算数组的元素数
我在测试代码时遇到了一个问题。我定义了一个宏来获取数组的元素数,如下所示:C 如何计算数组的元素数,c,arrays,counting,C,Arrays,Counting,我在测试代码时遇到了一个问题。我定义了一个宏来获取数组的元素数,如下所示: #定义数组大小(arr)sizeof(arr)/sizeof(arr[0]) 此宏可以很好地计算初始值设定项与存储容量匹配的数组的元素数(例如,int-buf[]={1,2,3};),但对于声明为:int-buf[20]={1,2,3}的数组,效果不是很好 现在我知道像这样计算数组元素是很容易的,但是大量的元素呢?你怎么算?你知道,数数可能是个杀手 考虑以下代码: #include <stdio.h> #in
#定义数组大小(arr)sizeof(arr)/sizeof(arr[0])
此宏可以很好地计算初始值设定项与存储容量匹配的数组的元素数(例如,int-buf[]={1,2,3};
),但对于声明为:int-buf[20]={1,2,3}的数组,效果不是很好代码>
现在我知道像这样计算数组元素是很容易的,但是大量的元素呢?你怎么算?你知道,数数可能是个杀手
考虑以下代码:
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(arr) sizeof(arr) / sizeof(arr[0])
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize);
int main(void)
{
int dst[20] = { 1,2,3 };
int src[] = { 4,5,6 };
size_t dstSize = 3; // dstSize = ARRAY_SIZE(dst) doesn't work
size_t srcSize = ARRAY_SIZE(src);
g_strcat(dst, dstSize, sizeof(int), src, srcSize);
size_t n, newSize = dstSize + srcSize;
for (n = 0; n < newSize; n++) {
printf("%d ", dst[n]);
}
putchar('\n');
return 0;
}
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize)
{
memcpy((char *)_Dst + (dstSize * bytes), _Src, srcSize * bytes);
}
#包括
#包括
#定义数组大小(arr)sizeof(arr)/sizeof(arr[0])
void g_strcat(void*_Dst、size_t dstSize、size_t字节、const void*_Src、size_t srcSize);
内部主(空)
{
int-dst[20]={1,2,3};
int src[]={4,5,6};
size_t dstSize=3;//dstSize=ARRAY_size(dst)不起作用
大小=数组大小(src);
g_strcat(dst、dstSize、sizeof(int)、src、srcSize);
大小n,newSize=dstSize+srcSize;
对于(n=0;n
您的宏工作正常。声明:
int dst[20] = { 1,2,3 };
在堆栈内存中创建以下内容:
|1|2|3|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
即使仅使用前三个值初始化,数组大小仍为20
关于评论中的问题:我将如何连接到数组?数组必须足够大以容纳另一个字符串:
如果使用字符串(而不是数字数组),则使用字符串函数int len=strlen(字符串)
可用于在连接之前测试字符串变量的现有用法
与sizeof
宏不同,strlen
是一个在字符数组中查找第一个空字符的函数:
char string[20] = {"yes"};
在内存中创建以下内容:
|y|e|s|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
strlen
从string
的地址开始计数字符,直到遇到第一个空字符。(或0):
然后可以使用strncat(string、newStr、count)
将指定数量的字符count连接到已知容量的字符串,从而避免缓冲区溢出
请记住,例如,size==20的字符串变量仅限于包含长度==19的字符串。必须为空字符保留第20个位置。如果我们可以假设最后一个初始化的元素不是零(因为这与隐式初始化为零没有区别): 如果您想以不同的方式计算这两种情况,那么您就完全不走运了(除非您使用Clang或GCC-XML或其他方式解析代码):
以上两种方法都将给出
3
,对此无能为力。如果只部分初始化一个基本数据类型列表(即int
s的数组),其余元素将初始化为0
C99标准6.7.8.21
如果大括号内的列表中的初始值设定项少于聚合的元素或成员,或者列表中的字符少于
用于初始化已知大小的数组的字符串文字
如果是阵列中的元素,则骨料的剩余部分应为
与具有静态存储的对象隐式初始化相同
持续时间
在您的例子中,您试图确定初始值设定项列表的大小。我真的想不出一个有效的理由需要这样做,但您可以简单地检查元素何时开始一致地等于零。当然,如果您故意将元素设置为零,则此操作将失败
您编写的宏将正常工作(即:返回数组中的元素数),但如果在接受指向数组的指针作为参数的函数中使用该宏,则该宏将失败
尽管如此,您无法在任何有意义的意义上确定初始值设定项列表的大小,除非您这样做,将初始值设定项列表定义为宏:
代码清单
通过将一次性阵列放入新的块作用域,可以最大限度地减少内存浪费,即:
#包括
#定义列表{1,2,3}
内部主(空)
{
int i[20]=列表;
int initListSize=0;
{
int t[]=列表;
initListSize=sizeof(t)/sizeof(int);
}
printf(“t中的元素:%d\n”,initListSize);
返回0;
}
这会将临时阵列的存储寿命限制在大括号之间的狭窄范围内。同样,我可以看到这可能是一个有用的实验,但我看不到这会进入生产代码。如果要确定数组的初始值设定项数量,请声明一个数组来保存初始值设定项元素,并在其上应用宏
array\u SIZE()
。然后使用memcpy()
将初始值设定项复制到dst[20]
数组
现在您可以轻松获得元素的数量
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(arr) sizeof(arr) / sizeof(arr[0])
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize);
int main(void)
{
int dst[20], src[] = { 4,5,6 };
int initializer_list[] = { 1,2,3 };
size_t init_size = ARRAY_SIZE(initializer_list);
memcpy(dst, initializer_list, init_size * sizeof(int));
size_t dstSize = init_size;
size_t srcSize = ARRAY_SIZE(src);
g_strcat(dst, dstSize, sizeof(int), src, srcSize);
dstSize += srcSize;
size_t n;
for (n = 0; n < dstSize; n++) {
printf("%d ", dst[n]);
}
putchar('\n');
return 0;
}
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize)
{
memcpy((char *)_Dst + (dstSize * bytes), _Src, srcSize * bytes);
}
#包括
#包括
#定义数组大小(arr)sizeof(arr)/sizeof(arr[0])
void g_strcat(void*_Dst、size_t dstSize、size_t字节、const void*_Src、size_t srcSize);
内部主(空)
{
int-dst[20],src[]={4,5,6};
int初始值设定项_list[]={1,2,3};
size\t init\u size=数组大小(初始值设定项列表);
memcpy(dst、初始值设定项列表、初始值大小*sizeof(int));
大小=初始大小;
大小=数组大小(src);
g_strcat(dst、dstSize、sizeof(int)、src、srcSize);
dstSize+=srcSize;
尺寸;
对于(n=0;nsize_t trailing_zero_bytes(const void* data, size_t size) {
for (; size > 0; size--) {
if (((const char*)data)[size - 1] != 0) {
break;
}
}
return size;
}
#define ARRAY_SIZE(arr) \
((sizeof(arr) - trailing_zero_bytes(arr, sizeof(arr)) + sizeof(arr[0]) + 1) / sizeof(arr[0]))
int s1[5] = { 4,5,6 }; // 2 zeros implied
int s2[5] = { 4,5,6,0 }; // 1 zero implied
#include <stdio.h>
#define LIST {1,2,3}
int main(void)
{
int i[20] = LIST;
int t[] = LIST;
printf("elements in i: %d\n", sizeof(i)/sizeof(int));
printf("elements in t: %d\n", sizeof(t)/sizeof(int));
return 0;
}
elements in i: 20
elements in t: 3
#include <stdio.h>
#define LIST {1,2,3}
int main(void)
{
int i[20] = LIST;
int initListSize = 0;
{
int t[] = LIST;
initListSize = sizeof(t) / sizeof(int);
}
printf("elements in t: %d\n", initListSize);
return 0;
}
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(arr) sizeof(arr) / sizeof(arr[0])
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize);
int main(void)
{
int dst[20], src[] = { 4,5,6 };
int initializer_list[] = { 1,2,3 };
size_t init_size = ARRAY_SIZE(initializer_list);
memcpy(dst, initializer_list, init_size * sizeof(int));
size_t dstSize = init_size;
size_t srcSize = ARRAY_SIZE(src);
g_strcat(dst, dstSize, sizeof(int), src, srcSize);
dstSize += srcSize;
size_t n;
for (n = 0; n < dstSize; n++) {
printf("%d ", dst[n]);
}
putchar('\n');
return 0;
}
void g_strcat(void *_Dst, size_t dstSize, size_t bytes, const void *_Src, size_t srcSize)
{
memcpy((char *)_Dst + (dstSize * bytes), _Src, srcSize * bytes);
}