我必须定义一个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])这样的函数。
char[3]
type24
typedef char[3] type24;
void foo(type24 val) {}
type24_to_int32(type24 val)
type24_to_int32(char value[3])
在C语言中,数组不能按值作为函数参数传递。
你可以把数组放在一个结构体中:
typedef struct type24 { char byte[3]; } type24;
然后按值传递,但当然,这样使用:x.byte[0]而不是x[0]就不那么方便了。
x.byte[0]
x[0]
你的函数type24_to_int32(char value[3])实际上是通过指针传递,而不是通过值。它完全等价于type24_to_int32(char *value),并且3将被忽略。
type24_to_int32(char *value)
3
如果你乐意传递指针,你可以继续使用数组并执行:
type24_to_int32(const type24 *value);
这将传递一个指向数组的指针,而不是指向第一个元素的指针,所以你可以这样使用它:
(*value)[0]
我不确定这真的是一个增益,因为如果你不小心写了value[1],那么就会发生一些愚蠢的事情。
value[1]
类型定义为
typedef char type24[3];
然而,这可能是一个非常糟糕的主意,因为结果类型是一个数组类型,但它的用户不会看到它是一个数组类型。如果用作函数参数,它将通过引用传递,而不是通过值传递,并且它的sizeof将是错误的。
sizeof
一个更好的解决办法是
typedef struct type24 { char x[3]; } type24;
你可能也想使用unsigned char而不是char,因为后者具有实现定义的符号性。
unsigned char
char
你想要的
C类型声明在这方面很奇怪。如果要声明该类型的变量,则将类型放置在变量名所在的位置。
从R . .的回答:
然而,这可能是一个非常坏的主意,因为结果类型 是数组类型,但它的用户不会看到它是数组类型。 如果用作函数参数,它将通过引用传递,而不是通过 值,那么它的sizeof值将是错误的
没有看到它是一个数组的用户很可能会写这样的东西(这是失败的):
#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
要正确地将数组类型用作函数实参或模板形参,请创建一个struct而不是typedef,然后在结构中添加operator[],这样您就可以保持数组类函数,如下所示:
operator[]
typedef struct type24 { char& operator[](int i) { return byte[i]; } char byte[3]; } type24; type24 x; x[2] = 'r'; char c = x[2];
下面是一个简短的例子,说明为什么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编译器将在默认情况下发出警告。
构建在接受的答案之上的多维数组类型,即固定长度数组的固定长度数组,不能用声明
typedef char[M] T[N]; // wrong!
相反,中间1D数组类型可以声明并在接受的答案中使用:
typedef char T_t[M]; typedef T_t T[N];
或者,T可以在一个单独的(可以说是令人困惑的)语句中声明:
T
typedef char T[N][M];
它定义了一种M字符的N数组类型(此处注意顺序)。
M
N