繁体   English   中英

C 指向整数数组数组的指针

[英]C pointer to array of array of integers

在 C 中初始化(常量)整数数组(不同维度)的等效项是什么?

在javascript中它是这样的:

myarray=[ [1,2,3,4], [123,234], [1], [1,2] ]

 console.log(myarray=[ [1,2,3,4], [123,234], [1], [1,2] ])

我如何在 C 中做同样的事情?

示例:这在 C 中有效:

const unsigned char *cf[] = { "\x2", "\x0,\x1,\x2", "\x3,\x4"};

我希望做同样的事情,但没有引号。

直接输入 2, [0,1,2], [3,4]

我解释得更好:

这有效:

int c1[]={1,2,3,4};
int c2[]={5,6};
int c3[]={2,3,4}

int *arr[]={c1,c2,c3};

所以我可以访问每个元素作为arr[0][x] arr[1][x]

现在我有一个大数组。 我该如何初始化它?

const unsigned char *cf[] = { "\x2", "\x0,\x1,\x2", "\x3,\x4"};

我希望做同样的事情,但没有引号。


代码可以使用复合文字来形成小的unsigned char数组。 然而cf[] (指向unsigned char的指针数组)不知道每个数组有多大。

不完全是“不同维度的整数数组的数组”。

int foo() {
  const unsigned char *cf[] = {
      (unsigned char[]) { 2, ',', 0 }, 
      (unsigned char[]) { 0, ',', 1, ',', 2, 0 }, 
      (unsigned char[]) { 3, ',', 4, 0 }
  };
  return cf[0][0];
}

注意: "\\x2"是 2 个字节长。
"\\x0,\\x1,\\x2"是 6 个字节长。
"\\x3,\\x4"是 4 个字节长。

`

C中的等价物是什么...

简短的回答是,在 C 中没有任何等效的东西来执行您在javascript中显示的内容。

在 C 中做类似事情的最常见方法是使用结构:

typedef struct {
   int a[4];
   int b[2];
   int c[1];
   int d[2];
} ARR;

const ARR arr = {{1,2,3,4}, {123, 234}, {1}, {1,2}};

C99(及更高版本)实现了灵活的数组成员 这是相似的,但同样,不完全是你想要的。 (即它也使用struct构造。)

没有简单的方法可以做到这一点,这取决于您是否确切地知道您的输入。

我所做的是为int *nums存储 N + 1 大小,然后将总长度存储在第一个内存位置。

#include <stdio.h>
#include <stdlib.h>
#define SIZE_ARRAY 4

struct myArray{
  int *nums;  
};

int main()
{
    struct myArray myArrays[SIZE_ARRAY];
    myArrays[0].nums = malloc(sizeof(int) * 5);
    *(myArrays[0].nums) = 4;//the size of the allocated memory
    *(myArrays[0].nums + 1) = 1;
    *(myArrays[0].nums + 2) = 2;
    *(myArrays[0].nums + 3) = 3;
    *(myArrays[0].nums + 4) = 4;

    myArrays[1].nums = malloc(sizeof(int) * 3);
    *(myArrays[1].nums) = 2;//the size of the allocated memory
    *(myArrays[1].nums + 1) = 123;
    *(myArrays[1].nums + 2) = 234;

    myArrays[2].nums = malloc(sizeof(int) * 2);
    *(myArrays[2].nums) = 1;//the size of the allocated memory
    *(myArrays[2].nums + 1) = 1;

    myArrays[3].nums = malloc(sizeof(int) * 3);
    *(myArrays[3].nums) = 2;//the size of the allocated memory
    *(myArrays[3].nums + 1) = 1;
    *(myArrays[3].nums + 2) = 2;

    printf("[");
    for(int i = 0; i < SIZE_ARRAY; ++i)
    {
        printf("[");
        for (int j = 0; j < *(myArrays[i].nums); ++j)
        {
            printf("%d", *(myArrays[i].nums + j + 1));

            if (j < *(myArrays[i].nums) - 1)
            {
                printf(", ");
            }
        }

        printf("]");

        if (i < SIZE_ARRAY - 1)
        {
            printf(", ");
        }
    }
    printf("]");

    return 0;
}

它提供了预期的输出,但不如 javascript 代码灵活。

C 语言的难点在于没有存储异构元素列表的内置数据类型。 但是当然,C 是 C,你可以使用指针和结构自己构建一些东西,就像我下面的例子。 令人讨厌的实现细节是您需要某种方式来存储每个数组的大小,因此需要一个结构。

#include <stdio.h>

typedef struct container_t
{
  int size;
  int *item;
} container_t;

int main(void)
{  
  int a[] = {1,2,3,4};
  int b[] = {123,234};
  int c[] = {1};
  int d[] = {1,2};
  container_t s[] = {
                      {sizeof(a)/sizeof(a[0]), a},
                      {sizeof(b)/sizeof(b[0]), b},
                      {sizeof(c)/sizeof(c[0]), c},
                      {sizeof(d)/sizeof(d[0]), d}
                    };

  for(int i = 0; i < sizeof(s)/sizeof(s[0]); i++)
  {    
    printf("[");
    for(int j = 0; j < s[i].size; j++)
      printf("%d,", s[i].item[j]);
    printf("]\r\n");
  }
}

输出:

[1,2,3,4,]

[123,234,]

[1,]

[1,2,]

假设语法是这里的问题(而不是性能),您可以尝试从头开始创建它。

在这两种情况下,语法都比您的 Javascript 代码稍微复杂一些。 我不确定在 C 中可以缩短多少,但是您可能可以使其在 C++ 中更容易阅读。

不过,我在下面提供了两种方法。 通过使用可变参数来处理较小数组的创建或通过解析字符串数组,这可以说更容易阅读,但可能会慢一点。

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

// I don't know what type you had in mind...
typedef int type_t;
#define type_t_specifier "%d"

typedef struct tab { // Helper struct
    type_t* data;
    size_t size;
} tab;

tab ctb(size_t size, ...) { // Parse one of the subarrays into the temporary struct
    tab res;
    res.size = size;
    res.data = (type_t*)malloc(res.size * sizeof(type_t));
    va_list valist;
    va_start(valist, size);
    for (int i = 0; i < size; i++) {
        res.data[i] = va_arg(valist, int);
    }
    return res;
}

typedef struct array_t { // Array struct
    type_t** data;
    size_t* sizes;
} array_t;

array_t create_array1(size_t size, ...) { // Create the array using variable arguments
    array_t array;
    array.data = (type_t**)malloc(size * sizeof(type_t*));
    array.sizes = (size_t*)malloc((size + 1) * sizeof(size_t));
    array.sizes[0] = size;
    va_list valist;
    va_start(valist, size);
    for (int i = 0; i < size; i++) {
        tab temp = va_arg(valist, tab);
        array.data[i] = (type_t*)malloc(temp.size * sizeof(type_t));
        array.sizes[i + 1] = temp.size;
        array.data[i] = temp.data;
    }
    return array;
}

array_t create_array2(size_t size, const unsigned char** temp) { // Or you can simply parse an array of strings instead
    array_t array;
    array.data = (type_t**)malloc(size * sizeof(type_t*));
    array.sizes = (size_t*)malloc((size + 1) * sizeof(size_t));
    array.sizes[0] = size;
    for (int i = 0; i < size; i++) {
        int nsize = 1;
        for (int j = 0; temp[i][j] != '\0'; j++) {
            if (temp[i][j] == ',') {
                nsize++;
            }
        }
        array.data[i] = (type_t*)malloc(nsize * sizeof(type_t));
        array.sizes[i + 1] = nsize;
        int start = 0;
        int cnt = 0;
        for (int j = 0; j <= strlen(temp[i]); j++) {
            if (temp[i][j] == ',' || temp[i][j] == '\0') {
                sscanf(&(temp[i][start]), type_t_specifier, &array.data[i][cnt++]);
                start = j + 1;
            }
        }
    }
    return array;
}

void delete_array(array_t array) { // Clean up the array
    for (int i = 0; i < array.sizes[0]; i++) {
        free(array.data[i]);
    }
    free(array.data);
    free(array.sizes);
}

void print_array(array_t array) { // Just to check if it works
    for (int i = 0; i < array.sizes[0]; i++) {
        for (int j = 0; j < array.sizes[i + 1]; j++) {
            fprintf(stderr, type_t_specifier, array.data[i][j]);
            if (j != array.sizes[i + 1] - 1) fprintf(stderr, " ");
            else fprintf(stderr, "\n");
        }
    }
}

int main(void) {
    array_t myarray;
    // You can either complicate the syntax a tiny bit by providing the lengths of each of the subarrays
    myarray = create_array1(4, ctb(4, 1, 2, 3, 4), ctb(2, 123, 234), ctb(1, 1), ctb(2, 1, 2));
    print_array(myarray);
    delete_array(myarray);
    // Or parse an array of strings to create your array
    const unsigned char* temp[] = { "1,2,3,4", "123,234", "1", "1,2" };
    myarray = create_array2(4, temp);
    print_array(myarray);
    delete_array(myarray);
    return 0;
}
// We need to parse the size of the outer array in both cases.

可以提高性能的一种方法也是连续存储内存。 这将使以后使用更快,但在构造数组时可能会花费更多时间。

或者,如果您想让它更容易使用,您可以简单地解析您的原始 javascript 数组。 如果可能的话,我真的会避免解析字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM