计算 C 中静态数组初始化的元素数
Count number of elements for static array initialization in C
有如下代码(C99):
#define MAX_ALLOCATIONS 2
#if !defined(ALLOCATIONS)
#define ALLOCATIONS {{1, 0, 0, 64},{1, 0, 0, 32}}
#endif
struct allocation
{
int thread_count_;
int node_run_;
int node_alloc_;
int size_alloc_;
};
static struct allocation allocations[MAX_ALLOCATIONS] = ALLOCATIONS;
编译此代码时,可以传递如下内容:-D'ALLOCATIONS={{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}'
.
是否可以得到一个计算分配数量的宏?例如,当它得到 {{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}
时,它应该计算 3。这将允许摆脱上面代码中的 MAX_ALLOCATIONS
。
是的,简单的方法是将 -DMAX_ALLOCATIONS=3
与 -D'ALLOCATIONS={{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}'
单独传递,但它很容易出错一个用户。
谢谢
定义数组allocations
时不需要使用MAX_ALLOCATIONS
。
您只需将ALLOCATIONS
定义为您的元素,数组的大小将自动确定。
当你在代码中需要那个数组的大小时,使用这个宏,它会给出数组中元素的数量 allocations
:
#define MAX_ALLOCATIONS (sizeof(allocations)/sizeof(allocations[0]))
这是一个常数值。
Is it possible to get a macro that would.
是的...也许使用宏,但肯定是通过编程方式。例如:
(编译于 Linux> gcc -o test -D'ALLOCATIONS="{{1, 0, 0, 8},{1, 0, 0, 16}, {1, 0, 0, 4}}"' *.c):
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h> // malloc()
typedef struct allocation_s
{
int thread_count_;
int node_run_;
int node_alloc_;
int size_alloc_;
} allocation_t;
/** **************************************************************************
* Print allocation records.
*/
int PrintRecords(
allocation_t *I__allocations,
int I__elements
)
{
int rCode = 0;
int index;
for(index=0; index < I__elements; ++index, ++I__allocations)
printf("{%d, %d, %d, %d}\n",
I__allocations->thread_count_,
I__allocations->node_run_,
I__allocations->node_alloc_,
I__allocations->size_alloc_
);
return(rCode);
}
/** **************************************************************************
* Read a record from allocation string.
*/
int ReadRecord(
char *I__string,
char **_O_next,
allocation_t *_O_record
)
{
int rCode = 0;
char *cp = I__string;
allocation_t record;
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
if('{' != *cp)
{
rCode=EINVAL;
fprintf(stderr, "[1]Allocations parsing error.\n");
goto CLEANUP;
}
while(*cp && (' ' == *cp || '{' == *cp))
++cp;
record.thread_count_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.node_run_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.node_alloc_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.size_alloc_ = strtoul(cp, &cp, 10);
cp=strchr(cp, '}');
if(!cp)
{
rCode=EINVAL;
fprintf(stderr, "[2]Allocations parsing error.\n");
goto CLEANUP;
}
++cp;
//RESULTS:
if(_O_record)
memcpy(_O_record, &record, sizeof(*_O_record));
if(_O_next)
*_O_next = (char *)cp;
CLEANUP:
return(rCode);
};
/** **************************************************************************
* Program start.
*/
int main(
int I__argC,
char *I__argV[]
)
{
int rCode=0;
char *rawDataString = ALLOCATIONS;
char *cp = rawDataString;
int elements = 0;
allocation_t *allocations_A = NULL;
allocation_t *allocationsPtr;
int index;
if('{' != *cp)
{
fprintf(stderr, "Allocations parsing error.\n");
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Count the elements.
*/
do {
rCode=ReadRecord(cp, &cp, NULL);
++elements;
} while(!rCode && ',' == *cp);
if(rCode)
{
fprintf(stderr, "ReadRecord() reports: %d\n", rCode);
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Allocate the array.
*/
errno=0;
allocations_A = malloc(sizeof(*allocations_A) * elements);
if(!allocations_A)
{
rCode=errno;
fprintf(stderr, "malloc() failed: errno:[%d] %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Initialize the array.
*/
cp = rawDataString;
allocationsPtr = allocations_A;
for(index=0; index < elements; ++index)
{
rCode=ReadRecord(cp, &cp, allocationsPtr++);
if(rCode)
{
fprintf(stderr, "ReadRecord() reports: %d\n", rCode);
goto CLEANUP;
}
}
/** -----------------------------------------------------------------------
* Print the array.
*/
PrintRecords(allocations_A, elements);
CLEANUP:
return(rCode);
}
示例输出:
{1, 0, 0, 8}
{1, 0, 0, 16}
{1, 0, 0, 4}
有如下代码(C99):
#define MAX_ALLOCATIONS 2
#if !defined(ALLOCATIONS)
#define ALLOCATIONS {{1, 0, 0, 64},{1, 0, 0, 32}}
#endif
struct allocation
{
int thread_count_;
int node_run_;
int node_alloc_;
int size_alloc_;
};
static struct allocation allocations[MAX_ALLOCATIONS] = ALLOCATIONS;
编译此代码时,可以传递如下内容:-D'ALLOCATIONS={{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}'
.
是否可以得到一个计算分配数量的宏?例如,当它得到 {{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}
时,它应该计算 3。这将允许摆脱上面代码中的 MAX_ALLOCATIONS
。
是的,简单的方法是将 -DMAX_ALLOCATIONS=3
与 -D'ALLOCATIONS={{1, 0, 0, 8},{1, 0, 0, 16},{1, 0, 0, 4}}'
单独传递,但它很容易出错一个用户。
谢谢
定义数组allocations
时不需要使用MAX_ALLOCATIONS
。
您只需将ALLOCATIONS
定义为您的元素,数组的大小将自动确定。
当你在代码中需要那个数组的大小时,使用这个宏,它会给出数组中元素的数量 allocations
:
#define MAX_ALLOCATIONS (sizeof(allocations)/sizeof(allocations[0]))
这是一个常数值。
Is it possible to get a macro that would.
是的...也许使用宏,但肯定是通过编程方式。例如:
(编译于 Linux> gcc -o test -D'ALLOCATIONS="{{1, 0, 0, 8},{1, 0, 0, 16}, {1, 0, 0, 4}}"' *.c):
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h> // malloc()
typedef struct allocation_s
{
int thread_count_;
int node_run_;
int node_alloc_;
int size_alloc_;
} allocation_t;
/** **************************************************************************
* Print allocation records.
*/
int PrintRecords(
allocation_t *I__allocations,
int I__elements
)
{
int rCode = 0;
int index;
for(index=0; index < I__elements; ++index, ++I__allocations)
printf("{%d, %d, %d, %d}\n",
I__allocations->thread_count_,
I__allocations->node_run_,
I__allocations->node_alloc_,
I__allocations->size_alloc_
);
return(rCode);
}
/** **************************************************************************
* Read a record from allocation string.
*/
int ReadRecord(
char *I__string,
char **_O_next,
allocation_t *_O_record
)
{
int rCode = 0;
char *cp = I__string;
allocation_t record;
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
if('{' != *cp)
{
rCode=EINVAL;
fprintf(stderr, "[1]Allocations parsing error.\n");
goto CLEANUP;
}
while(*cp && (' ' == *cp || '{' == *cp))
++cp;
record.thread_count_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.node_run_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.node_alloc_ = strtoul(cp, &cp, 10);
while(*cp && (' ' == *cp || ',' == *cp))
++cp;
record.size_alloc_ = strtoul(cp, &cp, 10);
cp=strchr(cp, '}');
if(!cp)
{
rCode=EINVAL;
fprintf(stderr, "[2]Allocations parsing error.\n");
goto CLEANUP;
}
++cp;
//RESULTS:
if(_O_record)
memcpy(_O_record, &record, sizeof(*_O_record));
if(_O_next)
*_O_next = (char *)cp;
CLEANUP:
return(rCode);
};
/** **************************************************************************
* Program start.
*/
int main(
int I__argC,
char *I__argV[]
)
{
int rCode=0;
char *rawDataString = ALLOCATIONS;
char *cp = rawDataString;
int elements = 0;
allocation_t *allocations_A = NULL;
allocation_t *allocationsPtr;
int index;
if('{' != *cp)
{
fprintf(stderr, "Allocations parsing error.\n");
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Count the elements.
*/
do {
rCode=ReadRecord(cp, &cp, NULL);
++elements;
} while(!rCode && ',' == *cp);
if(rCode)
{
fprintf(stderr, "ReadRecord() reports: %d\n", rCode);
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Allocate the array.
*/
errno=0;
allocations_A = malloc(sizeof(*allocations_A) * elements);
if(!allocations_A)
{
rCode=errno;
fprintf(stderr, "malloc() failed: errno:[%d] %s\n", rCode, strerror(rCode));
goto CLEANUP;
}
/** -----------------------------------------------------------------------
* Initialize the array.
*/
cp = rawDataString;
allocationsPtr = allocations_A;
for(index=0; index < elements; ++index)
{
rCode=ReadRecord(cp, &cp, allocationsPtr++);
if(rCode)
{
fprintf(stderr, "ReadRecord() reports: %d\n", rCode);
goto CLEANUP;
}
}
/** -----------------------------------------------------------------------
* Print the array.
*/
PrintRecords(allocations_A, elements);
CLEANUP:
return(rCode);
}
示例输出:
{1, 0, 0, 8}
{1, 0, 0, 16}
{1, 0, 0, 4}