具有不同长度数组成员C

时间:2016-06-23 10:32:46

标签: c struct initialization c99 allocation

我在C99中实现了一些查找数据(作为软件PLECS中的C脚本)。

我想创建一个struct数组,其中一个(稍后将是三个)数组成员,每个结构的长度不同(但总是已知)。我想在声明struct array时直接传递数据。

这是我到目前为止所尝试的内容。

#include <stdlib.h>

struct SomeStruct{
    double a;
    double *b;
};

struct SomeStruct StructArray[3] = {
    [0].a = 1,
    [0].b = (double*)malloc(2*sizeof(double)),
    [0].b = {1.01, 2.01}, //obviously wrong

    [1].a = 2,
    [1].b = (double*)malloc(3 * sizeof(double)),
    [1].b = { 1.01, 2.01, 3.01, }, //obviously wrong

    [2].a = 3,
    [2].b = (double*)malloc(4 * sizeof(double)),
    [2].b = { 1.01, 2.01, 3.01, 4.01 }, //obviously wrong
};

不幸的是我的C有点生疏,我无法弄清楚如何取消引用结构中的指针。 *([N] .b)不起作用。

这甚至可能吗?或者是否有更优雅的灵魂?

PS:数据将非常大,结构数组的长度约为200,并且每个数组中最多有三个长度为400的数组。这个代码是从MATLAB脚本生成的头文件。

编辑:以上问题已由@Gilles解决,以下仍有兴趣

这是另一种方法,在运行时初始化。为什么以下位不起作用?

#include <stdlib.h>

typedef struct {
    double a;
    double *b;
} SomeStruct;

SomeStruct StructArray[2]; //Sample struct

void initializeLUT() // Filling the Struct with Data
{
    StructArray[0].a = 1;
    StructArray[0].b = (double*)calloc(2, sizeof(double));
    StructArray[0].b = { 1.01, 2.01 }; // does not work

    StructArray[1].a = 2;
    StructArray[1].b = (double*)calloc(3, sizeof(double));
    *(StructArray[1].b) = { 1.01, 2.01, 3.01, }; //does not work either
}

3 个答案:

答案 0 :(得分:2)

在全局变量中,初始值设定项必须是常量。设计语言的原因在于,对于全局数据,初始化程序通常由嵌入在程序二进制文件中的数据组成,而不是在运行时执行的代码。因此,即使您将调用打包到malloc并将元素值打包到函数中,您仍然无法使用它来初始化数据。

如果你想拥有一个静态初始化程序,请将指针的初始化与最初指向的数组的初始化分离。创建初始数组全局变量,这是您为它们指定初始值设定项的唯一方法。

double row1[] = { 1.01, 2.01 };
double row2[] = { 1.01, 2.01, 3.01 };
double row3[] = { 1.01, 2.01, 3.01, 4.01 };
struct SomeStruct StructArray[3] = {
    [0].a = 1,
    [0].b = row1,
    [1].a = 2,
    [1].b = row2,
    [2].a = 3,
    [2].b = row3,
};

如果你想使用malloc,因为你想在运行时释放或调整数组大小,那么将指针初始化为NULL,并从你自己的初始化代码中调用malloc(例如在main或更好的情况下,在定义malloc的同一文件init_my_module中定义的函数my_module.c中调用StructArray,然后调用init_my_module来自main)。您可能仍需要为初始数组内容提供全局变量。

请注意,如果数组具有固定大小,则更好的方法是使SomeStruct直接包含数组,而不是指针。但是这种方法对于不同大小的数组不起作用:你可以有一个flexible array member的结构,但你不能将该结构放在一个数组中,因为数组元素需要有一个常数大小

另请注意,您应该将数组大小存储在某处(通常在结构的字段中)。

答案 1 :(得分:0)

由于数据显然是动态的,您需要在运行时初始化它。我认为您正在寻找另一个名为&#34;灵活数组成员&#34;的C99功能,而不是使用指定的初始值设定项,它允许结构以最安全的方式在结尾处具有可变大小的结构。例如:

#include <stdlib.h>
#include <string.h>

typedef struct 
{
  double a; // whatever this is supposed to be
  size_t size;
  double data[]; // flexible array member
} SomeStruct;


SomeStruct* SomeStruct_alloc (double a, size_t size, double data[size])
{
  SomeStruct* ss = malloc(sizeof(SomeStruct) + sizeof(double[size]));
  if(ss == NULL)
  {
    return NULL;
  }

  ss->a = a;
  ss->size = size;
  memcpy(ss->data, data, sizeof(double[size]));

  return ss;
}


int main()
{
  SomeStruct* arr[3];

  arr[0] = SomeStruct_alloc(1, 2, (double[2]){1.01, 2.01});
  arr[1] = SomeStruct_alloc(2, 3, (double[3]){1.01, 2.01, 3.01});
  arr[2] = SomeStruct_alloc(3, 4, (double[4]){1.01, 2.01, 3.01, 4.01});

  return 0;
}

答案 2 :(得分:0)

替换

$("#code").keyup(function(){
  
  var finalCode=$("#code").val();
  for($i=0;$i<=finalCode.length;$i++){
   // finalCode=finalCodeprev[i].toUpper();
    $("#outcode").html(finalCode);  
  }
  
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Enter Code: <input type="text" name="code" id="code">
<br>
You have enterd : <lable id="outcode"></lable>
     

你甚至可以定义一个宏来帮助你,也许:

StructArray[0].b = (double*)calloc(2, sizeof(double));
StructArray[0].b = { 1.01, 2.01 }; // does not work

然后将其用作

{
  double* p = calloc(2, sizeof(double));
  if (!p) { perror("calloc"); exit(EXIT_FAILURE); };
  static const double arr[] = { 1.01, 2.01 };
  memcpy (p, arr, 2*sizeof(double));
  StructArray[0].b = p;
}
顺便说一句,你可能会更好地使用flexible array members(总是在他们的#define FILLME(Ix,...) do { \ static const double arr[] = {__VA_ARGS__}; \ double*p = calloc(sizeof(arr)/sizeof(double), \ sizeof(double)); \ if (!p) \ { perror("calloc"); exit(EXIT_FAILURE); }; \ memcpy (p, arr, sizeof(arr)); \ StructArray[ix].b = p; \ } while(0) 中持续)