I wanna turn to diverse functional entry acording to the received datas. The datas received from the serial port are at the length of 2 bytes . so I can't simply use Switch sentence. How can I make it?

Dani AI

Generated

Short answer and why the compiler errors appear: C's switch works only on integer (or promotable scalar) expressions and every case must be a compile-time integer constant. Trying to build a runtime string or a non-constant expression for a case causes messages like the ones in the thread. 's errors are consistent with that—switch cannot match against runtime strings or non-constant values.

Suggested approaches (complements to and )

  • Create a compact numeric key from the two bytes and dispatch on that (safe casts to unsigned types are important to avoid sign-extension). For a plain-C, fast, memory-friendly dispatch use a flat table of 65,536 function pointers indexed by (high_byte*256 + low_byte). Registration is O(1) and dispatch is a single array lookup.
  • If the command set is small, a nested switch (first byte, then second) is simple and readable.
  • For sparse/large sets, keep a small registration list or use a hash table (custom or a library) mapping a 16-bit key to a handler to save memory.

Example: flat table registration/dispatch (plain C)

typedef void (*handler_t)(void);

static handler_t table[256 * 256];  /* zero-initialized */

static inline unsigned int idx(unsigned char hi, unsigned char lo) {
    return (unsigned int)hi * 256u + (unsigned int)lo;
}

void register_handler(unsigned char hi, unsigned char lo, handler_t h) {
    table[idx(hi, lo)] = h;
}

void dispatch(unsigned char hi, unsigned char lo) {
    handler_t h = table[idx(hi, lo)];
    if (h) h();
}

Notes and gotchas

  • Ensure bytes are treated as unsigned (unsigned char or uint8_t) before arithmetic or shifts; otherwise values >= 128 can sign-extend and break keys.
  • A 256×256 pointer table uses about 256 KB on a 32-bit build (pointer size × 65,536); on 64-bit builds double that.
  • If named constants in case labels are desired, use compile-time integer #define or enum values (they must be constant expressions).

Recommended Answers

All 4 Replies

a map of function pointers using the received bytes (turned into a string maybe) as a key would work nicely.

If the data received is 2 bytes, why can't you use a switch?

#define SWITCH_DATA( L, R ) ((L << 8) | R)

switch (SWITCH_DATA( firstByte, secondByte ))

case SWITCH_DATA( 'A', 'B' ):
<do stuff for the "AB" command>
break;

and so on. Make sure the data is unsigned char, not just char, otherwise bytes >= 128 will cause trouble with sign extension.

a map of function pointers using the received bytes (turned into a string maybe) as a key would work nicely.

but my gcc complier seems not support the string type ,when I transform the two bytes data to a string and then use switch sentence, the complier says:"switch quantity is not an integer constant" ,"case label does not reduce to an integer constant"

If the data received is 2 bytes, why can't you use a switch?

#define SWITCH_DATA( L, R ) ((L << 8) | R)

switch (SWITCH_DATA( firstByte, secondByte ))

case SWITCH_DATA( 'A', 'B' ):
<do stuff for the "AB" command>
break;

and so on. Make sure the data is unsigned char, not just char, otherwise bytes >= 128 will cause trouble with sign extension.

I get even more confused. Would you please show me more examples.what should be the type of L and R. I mean (L<<8),it will clean data L.

I use redhat linux 9.0 to complie the program, and seems switch sentence does not support diverse types

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.