c 在结构中定义不同大小的数组 [英] c define arrays in struct with different sizes

查看:50
本文介绍了c 在结构中定义不同大小的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为两种类型的对象定义一个结构体.两者都具有完全相同的数据结构并执行相同的任务(成员方法).

I need to define a struct for two types of objects. Both have exactly the same data structure and perform same tasks (member methods).

唯一的区别是两种类型的数组大小不同,一种使用 SIZE_A,另一种使用 SIZE_B.

The ONLY difference is that the array sizes are different in the two types, one using SIZE_A, the other SIZE_B.

不希望重复结构和函数的定义.

Duplicating the definition of the struct and functions is not wanted.

如何使用一种类型的结构",并用不同大小初始化其数组?

How could I use one type of 'struct', and initialize its arrays with different sizes?

#define SIZE_A 100
#define SIZE_B 200

typedef struct{
  int matr[SIZE_A][SIZE_A];  // for another type matr[SIZE_B]
  int arr[SIZE_A];           // for another type arr[SIZE_B]
  int size;                  // will be initialized to SIZE_A or SIZE_B
  int var1, var2;
}s;

void task1(s* si){
  ...
}

void task2(s* si){
  ...

推荐答案

我会让 matr 成为结构末尾的灵活数组.然后,我会将 arr 数组粘贴到 matr 的最后一行.

I would make matr a flexible array at the end of your struct. Then, I would stick the arr array into the last row of matr.

typedef struct {
    int size;
    int var1, var2;
    int matr[];
} s;

static inline int size_ok_s (int size) {
    switch (size) {
    case SIZE_A:
    case SIZE_B:
        return 1;
    default:
        break;
    }
    return 0;
}

s * create_s (int size) {
    s *x = 0;
    if (size_ok_s(size)) {
        x = malloc(sizeof(*x) + sizeof(int[size+1]));
        if (x) x->size = size;
    }
    return x;
}

要实现统一的界面,可以使用宏:

To achieve a uniform interface, you can use a macro:

#define s_matr(x) ((int (*)[(x)->size])(size_ok_s((x)->size) ? (x)->matr : 0))
#define s_arr(x)  (s_matr(x)[(x)->size])

因此,要访问 s *foo 的 ith 行和 jthmatr,以及它的kth元素的arr:

So, to access the ith row and jth column of s *foo's matr, and its kth element of arr:

s *foo = create_s(SIZE_A);
/* ... */
    s_matr(foo)[i][j] = 0;
    s_arr(foo)[k] = 0;

灵活的数组成员是 C.99 的一个新特性,在 §6.7.2.1 ¶16 中描述.在 C.99 之前,C 程序员经常使用所谓的 struct hack:

Flexible array members are a new feature of C.99 described in §6.7.2.1 ¶16. Prior to C.99, C programmers often used what was known as the struct hack:

typedef struct {
    int size;
    int var1, var2;
    int matr[1];
} s;

s * create_s (int size) {
    s *x = 0;
    if (size_ok_s(size)) {
        x = malloc(sizeof(*x) + sizeof(int[size]));
        if (x) x->size = size;
    }
    return x;
}

这是一个 hack,因为在 C.89-90 中,使用大于 0 的值索引 matr 数组在技术上是访问超出其边界的对象.然而,这是一种常见的做法,并且具有广泛的可移植性.C.99 正式批准了具有灵活数组成员的机制,尽管它需要在数组声明中不指定大小的语法.

This is a hack since in C.89-90, indexing the matr array with a value greater than 0 is technically accessing an object beyond its boundary. However, it was a common practice, and widely portable. C.99 formally sanctioned the mechanism with the flexible array member, although it requires the syntax of not specifying a size in the array declaration.

这篇关于c 在结构中定义不同大小的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆