2014-09-25 4 views
1

Я хочу объявить тип данных переменной в зависимости от условия в C. Возможно ли это?Объявление типа данных переменной с использованием условия в c

Я написал программу для реализации стека с использованием целочисленного массива, , и я хочу, чтобы тот же код реализовал стек символов, который является ничем иным, как заменой некоторых «int» на «char» s, Так как это сделать? ?

Я тоже TrID что-то подобное,

if(x == 1) 
#define DATATYPE int 
else 
#define DATATYPE char 

и многое другое, но ничего не получалось.

+1

Вы можете сделать этот вид вещи элегантно в C++ с использованием шаблонов, но для C ваш единственный вариант действительно уродливые хаки с использованием макросов препроцессора. Проверьте возможности C11 '_Generic': https://en.wikipedia.org/wiki/C11_(C_standard_revision). –

+0

Ты _tried_ что? Вы должны знать, что препроцессор выполняет текстовую замену до того, как компилятор начнет использовать. –

ответ

5

Ваш код может работать с #if x==1 ... #endif если x является препроцессор символ, например, если вы скомпилируете команду -Dx=1option - gcc; пожалуйста, поймите, что C preprocessor является первой фазой C компилятора, который на самом деле видит препроцессора кода (используйте, например, gcc -C -E source.c > source.i, чтобы попасть в source.i препроцессированного форму source.c)

В общем, можно реализовать такие общие контейнеры с использованием огромные макросы препроцессора. См. sglib и this question. Или вы можете сгенерировать свой C-код с помощью какого-то специализированного генератора исходного кода (возможно, используя другой препроцессор, например m4 или gpp, или создайте собственный генератор на некоторых скриптовых языках).

В качестве альтернативы используйте много указателей void* и передайте размер данных в свои подпрограммы, например qsort(3). См. Glib containers

Возможно, вас заинтересует C++11 или Ocaml (или даже Common Lisp). Они предлагают стандартную библиотеку с несколькими родовыми containers (в C++ с templates в библиотеке, в Окамле с functors); Читайте также о generic programming

+0

Спасибо .. Я думаю, что «sglib» будет полезен. В то же время игра с указателями void * является немного сложной и заслуживающей внимания. :) .. Спасибо за другие ссылки, которыми вы поделились – nikhil

+0

Что означает «если вы скомпилируете с -Dx = 1» на самом деле означает..Я не понял, что – nikhil

+0

Добавил ссылку. Это флаг командной строки 'gcc' и любой другой компилятор командной строки, который я знаю (' clang', 'tcc',' nwcc' ...) –

1

У вас, вероятно, есть дефект дизайна. Вы действительно должны спросить себя, почему вы хотите угрожать C как динамический язык, такой как Python. C является статическим языком, поэтому типы фиксированы.

+0

Это может быть не дизайнерский недостаток *, а конструкторское решение * * –

0

Во-первых, пожалуйста, узнайте о препроцессоре. Теперь, на ваш вопрос.

Это не работает, из-за того, что компилятор только на самом деле видит:

if(x == 1) 
else 

# указывает на то, что команда будет выполняться препроцессора. Препроцессор - это действительно прославленная находка и замена, когда мы говорим о команде #define. например:

#define PI_5_DIGITS 3.14159f 

Предварительно процессор будет найти все вхождения тега PI_5_DIGITS и заменить его 3.14159.

Если вы хотите использовать это, сделайте x символом препроцессора, добавив переключатель, например.-Dx=1.

Ваш код, то необходимо будет изменить:

#ifdef x 
    #define DATATYPE int 
#else 
    #define DATATYPE char 
#endif 

Рекомендуемая литература:

http://www.phanderson.com/C/preprocess.html http://gcc.gnu.org/onlinedocs/cpp

+1

URL GCC действительно старый. Используйте http://gcc.gnu.org/onlinedocs/cpp/ –

+0

Исправлено ........... – Joshpbarron

+0

Неправильное исправление. URL-адрес GCC не содержит 'www' –

1

Используйте это решение, рекомендуем вам редизайн, создав-структуру для каждого значение в стеке tagged_t, а затем заполните данные, я надеюсь, что вы получите эту идею.

typedef union { 
int i; 
char c; 
float f; 
} evil; 

typedef struct { 
    evil value; 
    int type; 
} tagged_t; 

enum { 
    TYPE_INT, TYPE_CHAR, TYPE_FLOAT 
}; 

tagged_t bar; 
bar.value.c = 'a'; 
bar.type = TYPE_CHAR; 

See the answer of Yann Ramin

Смежные вопросы