typedef fixed length array

2019-01-02 17:05发布

问题:

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]).

回答1:

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.



回答2:

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.



回答3:

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


回答4:

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];


回答5:

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.



标签: