2013-07-15 24 views
9

Bir C veri tipini bir değişkene depolamak mümkün mü? BöyleBir C veri tipini değişkende depolamak mümkün mü?

şey: Burada

void* type = (byte*); 

ben bağlı bir test vakası yazmış ve printf kullanılmak üzere belirli veri türleri kullanarak bir bayt dizisi yazdırmak çalışan bir senaryo olduğunu Parametreler:

void print_byteArray(const void* expected, size_t size, 
     bool asChars, bool asWCharT) { 
    int iterations; 
    char* format; 
    if (asChars) { 
     iterations = (size/(sizeof (char))); 
     format = "%c"; 
    } else if (asWCharT) { 
     iterations = (size/(sizeof (wchar_t))); 
     format = "%lc"; 
    } else { 
     iterations = (size/(sizeof (byte))); 
     format = "%x"; 
    } 
    int i; 
    for (i = 0; i < iterations; i++) { 
     if (asChars) { 
      printf(format, ((char*) expected)[i]); 
     } else if (asWCharT) { 
      printf(format, ((wchar_t*) expected)[i]); 
     } else { 
      printf(format, ((byte*) expected)[i]); 
     } 
    } 
    fflush(stdout); 
} 

Verimsiz kod gibi görünüyor. Hayal ediyorum bu bir could boyutu aşağı For döngüsü gövdesini tek satıra:

printf(format, ((type) expected)[i]); 

cevap

12

Hayır,

gcc bir sağladığı standart C. türünü saklayabilir böyle tip var typeof uzantısı yararlı olabilir. Bu anahtar kelimenin kullanımının sözdizimi sizeof gibi görünür, ancak yapı, typedef ile tanımlanan bir tür adı gibi anlamsal olarak davranır. Detay için bkz. here.

typeof kullanımı bazıları daha fazla örnek:

Bu puan x şeyin türüyle y beyan eder.

typeof (*x) y; 

Bu, y değerlerini bir dizi olarak bildirir.

typeof (*x) y[4]; 

Bu karakter işaretçiler bir dizi olarak y bildiriyor:

typeof (typeof (char *)[4]) y; 

Aşağıdaki geleneksel C bildirimi eşdeğerdir:

char *y[4]; 

kullanarak bildirimi anlamını görmek için typeof ve neden yazmak için yararlı bir yol olabilir, bu makrolarla yeniden yazabilirsiniz:

array (pointer (char), 4) y; 

Böylece array (pointer (char), 4) char 4 işaretçiler diziler türüdür: Şimdi beyanı bu şekilde yeniden yazılabilir.

0

C, statik olarak yazılmış bir dildir, bu nedenle kendi çalışma zamanı türü sisteminizi oluşturmanız gerekir. Ancak, biri sadece keyfi verileri yazdırmak istiyorsa, printf'un %s'unu kullanabilir ve geçici dize arabellekleriyle çalışabilir. Bu, yazdırmak istediğiniz verilerin sınırlı olduğu bazı durumlarda çalışacaktır:

#include <stdlib.h> /* EXIT_ */ 
#include <stdio.h> /* *printf */ 

#define PRINT_BUFFERS (4) 

struct Foo { 
    int key; 
    char value[32]; 
}; 

/** Assumes {key} is {[0, 99]} to comply with C90, otherwise use {snprintf}. */ 
static void Foo_to_string(const struct Foo *foo, char (*const a)[12]) { 
    sprintf(*a, "%d%.9s", foo->key, foo->value); 
} 
/** This is more convenient, but lacks generality. */ 
static const char *Foo_to_static(const struct Foo *foo) { 
    static char buffers[PRINT_BUFFERS][12]; 
    static unsigned n; 
    char *const a = buffers[n]; 
    sprintf(a, "%d%.9s", foo->key, foo->value); 
    n = (n + 1) % PRINT_BUFFERS; 
    return a; 
} 

int main(void) { 
    const struct Foo foo = { 42, "foo" }, bar = { 96, "bar" }, 
     baz = { 13, "baz_abcdefg" }; 
    /* This way is more general. */ 
    char a[12], b[12], c[12]; 
    Foo_to_string(&foo, &a); 
    Foo_to_string(&bar, &b); 
    Foo_to_string(&baz, &c); 
    printf ("Foo: %s; Bar: %s; Baz: %s.\n", a, b, c); 
    /* This way is convenient, but you have a max number of calls. */ 
    printf("Foo: %s; Bar: %s; Baz: %s.\n", Foo_to_static(&foo), 
     Foo_to_static(&bar), Foo_to_static(&baz)); 
    return EXIT_SUCCESS; 
} 
İlgili konular