typedef固定长度数组

时间:2010-12-24 00:35:01

标签: c arrays gcc typedef

我必须定义一个24位数据类型。我使用char[3]来表示类型。我可以输入char[3]type24吗?我在代码示例中尝试过它。我将typedef char[3] type24;放在我的头文件中。编译器没有抱怨它。但是当我在我的C文件中定义一个函数void foo(type24 val) {}时,它确实抱怨了。我希望能够定义type24_to_int32(type24 val)而不是type24_to_int32(char value[3])等函数。

7 个答案:

答案 0 :(得分:272)

typedef将是

typedef char type24[3];

然而,这可能是一个非常糟糕的主意,因为结果类型是一种数组类型,但它的用户不会看到它是一个数组类型。如果用作函数参数,它将通过引用传递,而不是通过值传递,然后它的sizeof将是错误的。

更好的解决方案是

typedef struct type24 { char x[3]; } type24;

您可能还希望使用unsigned char代替char,因为后者具有实现定义的签名。

答案 1 :(得分:41)

你想要

typedef char type24[3];

C类型声明很奇怪。如果您声明了该类型的变量,则将类型精确地放在变量名称的位置。

答案 2 :(得分:27)

来自R..'s answer

  

然而,这可能是一个非常糟糕的主意,因为结果类型   是一个数组类型,但它的用户不会看到它是一个数组类型。   如果用作函数参数,它将通过引用传递,而不是通过引用传递   价值,以及它的大小将是错误的。

没有看到它是数组的用户很可能写这样的东西(失败):

#include <stdio.h>

typedef int twoInts[2];

void print(twoInts *twoIntsPtr);
void intermediate (twoInts twoIntsAppearsByValue);

int main () {
    twoInts a;
    a[0] = 0;
    a[1] = 1;
    print(&a);
    intermediate(a);
    return 0;
}
void intermediate(twoInts b) {
    print(&b);
}

void print(twoInts *c){
    printf("%d\n%d\n", (*c)[0], (*c)[1]);
}

它将使用以下警告进行编译:

In function ‘intermediate’:
warning: passing argument 1 of ‘print’ from incompatible pointer type [enabled by default]
    print(&b);
     ^
note: expected ‘int (*)[2]’ but argument is of type ‘int **’
    void print(twoInts *twoIntsPtr);
         ^

并产生以下输出:

0
1
-453308976
32767

答案 3 :(得分:11)

无法通过C中的值将数组作为函数参数传递。

您可以将数组放在结构中:

typedef struct type24 {
    char byte[3];
} type24;

然后按值传递,但当然使用起来不方便:x.byte[0]而不是x[0]

您的函数type24_to_int32(char value[3])实际上是通过指针传递的,而不是通过值传递的。它完全等同于type24_to_int32(char *value)3将被忽略。

如果你很高兴通过指针传递,你可以坚持使用数组并执行:

type24_to_int32(const type24 *value);

这将传递指向数组的指针,而不是指向第一个元素的指针,因此您将其用作:

(*value)[0]

我不确定这真的是一种收获,因为如果你不小心写了value[1]那么就会发生一些愚蠢的事情。

答案 4 :(得分:11)

要正确使用数组类型作为函数参数或模板参数,请创建一个结构而不是一个typedef,然后在结构中添加operator[],这样就可以保持数组的功能如下:

typedef struct type24 {
  char& operator[](int i) { return byte[i]; }
  char byte[3];
} type24;

type24 x;
x[2] = 'r';
char c = x[2];

答案 5 :(得分:0)

这是为什么typedef数组可能令人困惑的不一致的简短示例。其他答案提供了一种解决方法。

#include <stdio.h>
typedef char type24[3];

int func(type24 a) {
        type24 b;
        printf("sizeof(a) is %zu\n",sizeof(a));
        printf("sizeof(b) is %zu\n",sizeof(b));
        return 0;
}

int main(void) {
        type24 a;
        return func(a);
}

这将产生输出

sizeof(a) is 8
sizeof(b) is 3

因为type24作为参数是指针。 (在C语言中,数组始终作为指针传递。)幸好,gcc8编译器默认会发出警告。

答案 6 :(得分:0)

无法构建accepted answer多维数组类型,即固定长度数组的固定长度数组,不能用来声明

typedef char[M] T[N];  // wrong!

相反,可以像接受的答案中那样声明和使用中间一维数组类型:

typedef char T_t[M];
typedef T_t T[N];

或者T可以在一个(可能会引起混淆)的语句中声明:

typedef char T[N][M];

定义了N个字符的M个数组的类型(请注意此处的顺序)。