计算 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}