2013-12-03 2 views
0

Могу ли я # задавать константы динамически? Я хочу получить некоторые данные, прокрутить эти данные и затем назначить постоянное значение. Чтобы представить себе, что я хочу Я прилагаю глючный код:Определить константу на лету

const char *a[2]; 
a[0] = "foo"; 
a[1] = "bar"; 


for (ix=0; ix< 2; ix++) { 
    #define ix a[ix] 
} 

Так что я хотел бы иметь 0, как foo, 1 в bar и т.д.

Я хочу, чтобы иметь возможность присвоить значения в других значениях, как это:

anotherArr[0] ="something"; 

но это 0 должно быть foo. Я пытаюсь заменить ассоциативные массивы. Любые подсказки?

+3

Это невозможно, потому что определение разрешено во время компиляции - не во время выполнения. – Constantin

+1

"* Любой ключ? *" Возможно, выберете другой язык? – alk

ответ

0

No, #definepre-processor Конструкция: не задействовано никакое действие кода или компилятора.

4

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

3

Вы не можете. #define ZERO 0 в основном проходит через ваш код, заменяя все ZERO, которые он находит до 0 перед компиляцией. А затем код компилируется.

1

Это невозможно, так как определения решаются во время компиляции - не во время выполнения. Препроцессор просто заменит каждое ваше определение до, оно будет скомпилировано с тем, что вы там определили. Если строка содержит первый символ a # (или только пробелы перед), она передается в директиву preprocessor.

Вы хотите написать что-то наподобие anotherArr["foo"] = "bar";? В C++ вы можете использовать только зЬй :: Карту для этого:

std::map<std::string, std::string> map; 
map["foo"] = "bar"; 

Но чтобы решить вашу проблему в C вы бы нужно что-то еще, потому что нет никакой стандартной структуры данных, чтобы сделать что-то подобное. Но то, что вы, вероятно, можно использовать есть Хеш - т.е. http://troydhanson.github.io/uthash/index.html

#include <string.h> /* strcpy */ 
#include <stdlib.h> /* malloc */ 
#include <stdio.h> /* printf */ 
#include "uthash.h" 
struct my_struct { 
    char name[10];    /* key (string is WITHIN the structure) */ 
    int id; 
    UT_hash_handle hh;   /* makes this structure hashable */ 
}; 
int main(int argc, char *argv[]) { 
    const char **n, *names[] = { "joe", "bob", "betty", NULL }; 
    struct my_struct *s, *tmp, *users = NULL; 
    int i=0; 
    for (n = names; *n != NULL; n++) { 
    s = (struct my_struct*)malloc(sizeof(struct my_struct)); 
    strncpy(s->name, *n,10); 
    s->id = i++; 
    HASH_ADD_STR(users, name, s); 
    } 
    HASH_FIND_STR(users, "betty", s); 
    if (s) printf("betty's id is %d\n", s->id); 

    /* free the hash table contents */ 
    HASH_ITER(hh, users, s, tmp) { 
    HASH_DEL(users, s); 
    free(s); 
    } 
    return 0; 
} 

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

+0

Nitpicking?"* Если строка содержит в качестве первого символа # (или только пробелы перед), она передается препроцессору. *" Это не правильно. Весь контент предварительно обработанного файла передается на предварительный процессор. – alk

+0

Ну, конечно, весь файл сканируется, чтобы заменить определенные макросы предварительного процессора. Но только строки, начинающиеся с символа '#', передаются в препроцессор в качестве директивы. Я изменю формулировку, спасибо. – Constantin

0

Для расширения текущих ответов, мы можем взглянуть на исходном коде после предварительной обработки использования gcc -E

[email protected]:~$ cat a.c 
const char *a[2]; 
a[0] = "foo"; 
a[1] = "bar"; 


for (ix=0; ix< 2; ix++) { 
#define ix a[ix] 
} 
[email protected]:~$ gcc -E a.c 
# 1 "a.c" 
# 1 "<command-line>" 
# 1 "a.c" 
const char *a[2]; 
a[0] = "foo"; 
a[1] = "bar"; 


for (ix=0; ix< 2; ix++) { 

} 

Здесь вы можете увидеть, что после предварительной обработки петли теперь пусто, то есть компилятор обыкновению даже знаю о том, что #define вы просто пытались сойти с :).

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