[英]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.