typedef 定长数组

发布于 2024-10-09 00:25:28 字数 342 浏览 1 评论 0原文

我必须定义一个 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])

I have to define a 24-bit data type.I am using char[3] to represent the type. Can I typedef char[3] to type24? I tried it in a code sample. I put typedef char[3] type24; in my header file. The compiler did not complain about it. But when I defined a function void foo(type24 val) {} in my C file, it did complain. I would like to be able to define functions like type24_to_int32(type24 val) instead of type24_to_int32(char value[3]).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

我一直都在从未离去 2024-10-16 00:25:29

要正确使用数组类型作为函数参数或模板参数,请创建一个结构体而不是 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];

To use the array type properly as a function argument or template parameter, make a struct instead of a typedef, then add an operator[] to the struct so you can keep the array like functionality like so:

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

type24 x;
x[2] = 'r';
char c = x[2];
℉絮湮 2024-10-16 00:25:29

下面是一个简短的示例,说明了为什么 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 编译器默认会发出警告。

Here's a short example of why typedef array can be confusingly inconsistent. The other answers provide a workaround.

#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);
}

This produces the output

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

because type24 as a parameter is a pointer. (In C, arrays are always passed as pointers.) The gcc8 compiler will issue a warning by default, thankfully.

腻橙味 2024-10-16 00:25:29

构建接受的答案,一种多维数组类型,即固定长度数组的固定长度数组,不能用

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

相反的方式声明,可以按照接受的答案声明和使用中间一维数组类型:

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

或者,可以在单个(可以说是令人困惑的)语句中声明 T

typedef char T[N][M];

它定义了一个类型NM 字符数组(此处请注意顺序)。

Building off the accepted answer, a multi-dimensional array type, that is a fixed-length array of fixed-length arrays, can't be declared with

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

instead, the intermediate 1D array type can be declared and used as in the accepted answer:

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

or, T can be declared in a single (arguably confusing) statement:

typedef char T[N][M];

which defines a type of N arrays of M chars (be careful about the order, here).

分分钟 2024-10-16 00:25:29

我们可以将位域用于具有特定大小的类型。让我们用它创建一个结构体并为位字段指定 24

typedef struct {
  unsigned int _24bits: 24;
} utype24;

然后我们可以为其分配一个范围在 [ 0 , 16777215 ]

utype24 var = {16777215};
printf("%d", var._24bits);

output : 16777215

之间的值

16777215 来自哪里:

<预>24 位:
2^24-1 = 16777215(最大值)

We can use bitfields for type which has specific size. Let's create a struct with it and give 24 for bitfield.

typedef struct {
  unsigned int _24bits: 24;
} utype24;

Then we can assign a value to it which has range between [ 0 , 16777215 ]

utype24 var = {16777215};
printf("%d", var._24bits);

output : 16777215

Where 16777215 coming from :
24 bits:
2^24-1 = 16777215 (Max. value)
┊风居住的梦幻卍 2024-10-16 00:25:28

typedef 是

typedef char type24[3];

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

更好的解决方案是

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

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

The typedef would be

typedef char type24[3];

However, this is probably a very bad idea, because the resulting type is an array type, but users of it won't see that it's an array type. If used as a function argument, it will be passed by reference, not by value, and the sizeof for it will then be wrong.

A better solution would be

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

You probably also want to be using unsigned char instead of char, since the latter has implementation-defined signedness.

忘东忘西忘不掉你 2024-10-16 00:25:28

你想要

typedef char type24[3];

C 类型声明这样很奇怪。如果您声明该类型的变量,则可以将类型准确地放置在变量名称所在的位置。

You want

typedef char type24[3];

C type declarations are strange that way. You put the type exactly where the variable name would go if you were declaring a variable of that type.

2024-10-16 00:25:28

来自 R.. 的回答

但是,这可能是一个非常糟糕的主意,因为结果类型
是一个数组类型,但它的用户不会看到它是一个数组类型。
如果用作函数参数,它将通过引用传递,而不是通过
value,那么它的 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

From R..'s answer:

However, this is probably a very bad idea, because the resulting type
is an array type, but users of it won't see that it's an array type.
If used as a function argument, it will be passed by reference, not by
value, and the sizeof for it will then be wrong.

Users who don't see that it's an array will most likely write something like this (which fails):

#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]);
}

It will compile with the following warnings:

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);
         ^

And produces the following output:

0
1
-453308976
32767
野味少女 2024-10-16 00:25:28

在 C 中,数组不能作为函数参数按值传递

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

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

然后按值传递,但当然这样使用起来不太方便: x.byte[0]< /code> 而不是 x[0]

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

如果您乐意通过指针传递,您可以坚持使用数组并执行以下操作:

type24_to_int32(const type24 *value);

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

(*value)[0]

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

Arrays can't be passed as function parameters by value in C.

You can put the array in a struct:

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

and then pass that by value, but of course then it's less convenient to use: x.byte[0] instead of x[0].

Your function type24_to_int32(char value[3]) actually passes by pointer, not by value. It's exactly equivalent to type24_to_int32(char *value), and the 3 is ignored.

If you're happy passing by pointer, you could stick with the array and do:

type24_to_int32(const type24 *value);

This will pass a pointer-to-array, not pointer-to-first-element, so you use it as:

(*value)[0]

I'm not sure that's really a gain, since if you accidentally write value[1] then something stupid happens.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文