Форум программистов, компьютерный форум CyberForum.ru

Небольшое тестовое задание в финской компании. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 35, средняя оценка - 4.97
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 17:51     Небольшое тестовое задание в финской компании. #1
Привествую всех жителей форума.
Сразу отмечу, что решения просить не хочу, а просто хочу показать задание, которая давала компания суунто (Suunto, Finland) на должность программиста (кто не в курсе, компания занимается производством компьютеров для спортсменов, дайверов ... ) в далеком 2005 году.

Тема перенесена от сюда:
Удалить комментарии из строки

(кстати там же картинка - не могу опять ее же прицепить)

http://www.cyberforum.ru/attachment....p;d=1316092021

-----

кстати когда проходил там собеседование на программера задание было в написании парсера следующего (до сих пор храню)

(К сожалению оригинал задания не сохранился, да и толку от него нет -- он на финском.)

C++
1
2
3
4
"\n[[+-{$(width)}]{$(rows)}+"
"[\\n|[$(space){$(width)}|]"
"{$(rows)}]{$(height)}\\n]"
"{$(lines)}[+-{$(width)}]{$(rows)}+\\n"
Это строка
в строке:
[] - цикл
{число} количество повторений цикла []{10}, либо единичного сивола !{10}
пример: 1{5} = 11111
[12]{5} = 1212121212
[!] = !
[!]{0} = пусто
\x0000 - символ по хекс коду (\x0F0)
\x - экранированный символ (n, t, \, итд по списку + [] {} $)
$(переменная) переменная, получаемая ран-тайм. переменные могут передаваться в [] и {}
например count = 10
sym = !
[$(sym)]{$(count)} = !!!!!!!!!!
парсер должен из всего этого безобразия собрать строку
(результат в аттаче) принимая, что
"height" = 2;
"width" = 13;
"rows" = 10;
"lines" = 5;
"space" = пробел или что другое

Но! запрещены регулярные выражения, запрещен С++, запрещены функции типа strXXX. Только голый С, допускаются функции памяти (выделить/освободить) (статические буферы так же допускаются), указатели. На решение неделя.
----------------
Вдруг кому тоже интересно будет

Что будет не ясно, спрашивайте.

Тут сразу стоит отметить, что из 4 человек, которые, все ж, принесли задание на проверку никто не решил ее в полном объеме.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.09.2011, 17:51     Небольшое тестовое задание в финской компании.
Посмотрите здесь:

работа с файлами + небольшое шифрование C++
C++ Небольшое задание по матрицам
C++ Небольшое исправление
C++ Небольшое исправление (2)
C++ Небольшое уточнение
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
16.09.2011, 15:21     Небольшое тестовое задание в финской компании. #61
talis, ну, собственно, в реализации ничего сложного, просто действия меняются местами. Сначала разворачиваем строку, а потом запрашиваем значения переменных, а не наоборот, как у меня. Только вот я не привык реализовывать сверх того, что надо. Закажут - сделаем. Иначе - лесом))

Добавлено через 1 минуту
talis, со списком потом было бы легче работать (как мне кажется), да и ограничения на память. Зарезервированные слова - типа [],{},$. Видим зарезервированное слово - вытаскиваем строку до парного зарезервированного слова и передаем её рекурсивно парсеру.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
16.09.2011, 15:43     Небольшое тестовое задание в финской компании. #62
silent_1991, а я вот сразу дерево сделаю
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
16.09.2011, 15:46     Небольшое тестовое задание в финской компании. #63
Да, было бы разрешено всё, тут бы и spirit подключили...
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
16.09.2011, 19:04     Небольшое тестовое задание в финской компании. #64
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Какие символы следует экранировать? Понятно, что \n - перевод строки, \t - табуляция. Ну и служебные символы надо экранировать. А вот экранировать, скажем, \ или " я не вижу смысла, эти символы и так будут восприняты парсером как обычные.

Добавлено через 1 минуту
А, не, \ тоже надо экранировать, естественно. А остальное, мне кажется, нет смысла.

Добавлено через 2 часа 56 минут
Эх, написал... но код меня что-то совсем не радует... Какой-то он незрелый, что-ли, получился...

service_functions.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef SERVICE_FUNCTIONS_H
#define SERVICE_FUNCTIONS_H
 
#include <stdio.h>
#include <stdlib.h>
 
typedef char char_t;
typedef char_t * str_t;
 
#define false 0
#define true !0
 
void error(str_t msg);
 
void *allocate(size_t size);
void *reallocate(void *mem, size_t size);
void deallocate(void *mem);
 
str_t get_str(FILE *stream);
 
int str_to_int(str_t number, size_t radix);
 
size_t str_len(str_t str);
int str_cmp(str_t str1, str_t str2);
str_t str_n_cpy(str_t dest, str_t src, size_t n);
str_t str_cpy(str_t dest, str_t src);
str_t str_chr(str_t str, char_t ch);
str_t str_str(str_t where_str, str_t what_str);
void str_replace(str_t *str, str_t dest, str_t src);
 
#endif
service_functions.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#include "service_functions.h"
 
void error(str_t msg)
{
    fprintf(stderr, "%s", msg);
 
    exit(-1);
}
 
void *allocate(size_t size)
{
    void *mem = malloc(size);
 
    if (mem == NULL)
        error("Memory allocate error!\n");
 
    return mem;
}
 
void *reallocate(void *mem, size_t size)
{
    void *new_mem = realloc(mem, size);
 
    if (new_mem == NULL)
        error("Memory reallocate error!\n");
 
    return mem;
}
 
void deallocate(void *mem)
{
    free(mem);
}
 
str_t get_str(FILE *stream)
{
#define QUANTUM 32
 
    str_t str = (str_t)allocate(QUANTUM * sizeof(char_t));
 
    size_t multiplier = 1;
 
    size_t i = 0;
 
    while (true)
    {
        if (i >= multiplier * QUANTUM)
            str = (str_t)reallocate(str, ++multiplier * QUANTUM * sizeof(char_t));
 
        fread(str + i++, sizeof(char_t), 1, stream);
 
        if (str[i - 1] == '\n')
        {
            str[i - 1] = '\0';
 
            break;
        }
    }
 
    return str;
 
#undef QUANTUM
}
 
int str_to_int(str_t num, size_t radix)
{
    int result = 0;
    size_t len = str_len(num);
 
    size_t i;
 
    for (i = 0; i < len; ++i)
    {
        if (num[i] >= '0' && num[i] <= '9')
            result = result * radix + (num[i] - '0');
        else
            result = result * radix + (num[i] + 10 - 'A');
    }
 
    return result;
}
 
size_t str_len(str_t str)
{
    size_t len = 0;
 
    while (*str++ != '\0')
        ++len;
 
    return len;
}
 
int str_cmp(str_t str1, str_t str2)
{
    size_t len1 = str_len(str1);
    size_t len2 = str_len(str2);
 
    size_t i;
 
    if (len1 != len2)
        return len1 < len2 ? -1 : 1;
 
    for (i = 0; i < len1; ++i)
    {
        if (str1[i] < str2[i])
        {
            return -1;
        }
        else
        {
            if (str1[i] > str2[i])
                return 1;
        }
    }
 
    return 0;
}
 
str_t str_n_cpy(str_t dest, str_t src, size_t n)
{
    size_t i;
 
    for (i = 0; i < n; ++i)
        dest[i] = src[i];
 
    return dest;
}
 
str_t str_cpy(str_t dest, str_t src)
{
    size_t src_len = str_len(src);
 
    dest[src_len] = '\0';
 
    return str_n_cpy(dest, src, src_len);
}
 
str_t str_chr(str_t str, char_t ch)
{
    while (*str != '\0')
        if (*str++ == ch)
            return str - 1;
 
    return NULL;
}
 
str_t str_str(str_t where_str, str_t what_str)
{
    int key;
 
    size_t i;
 
    while (*where_str != '\0')
    {
        key = 1;
 
        for (i = 0; what_str[i] != '\0'; ++i)
        {
            if (where_str[i] != what_str[i])
            {
                key = -1;
 
                break;
            }
        }
 
        if (key == 1)
            return where_str;
 
        ++where_str;
    }
 
    return NULL;
}
 
void str_replace(str_t *str, str_t dest, str_t src)
{
    str_t substr = str_str(*str, dest);
    size_t substr_pos = substr - *str;
 
    size_t old_len = str_len(*str);
    size_t dest_len = str_len(dest);
    size_t src_len = str_len(src);
    
    str_t new_str;
    size_t new_len = old_len + src_len - dest_len + 1;
 
    if (substr == NULL)
        return;
 
    new_str = (str_t)allocate(new_len * sizeof(char_t));
 
    str_n_cpy(new_str, *str, substr_pos);
    str_n_cpy(new_str + substr_pos, src, src_len);
    str_n_cpy(new_str + substr_pos + src_len, *str + substr_pos + dest_len, old_len - substr_pos - dest_len);
 
    new_str[new_len - 1] = '\0';
 
    deallocate(*str);
 
    *str = new_str;
}
var.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef VAR_H
#define VAR_H
 
#include "service_functions.h"
 
#define BUF_SIZE 32
 
typedef struct
{
    char_t name[BUF_SIZE];
    char_t value[BUF_SIZE];
} var_t;
 
extern var_t vars[];
static size_t vars_top = 0;
 
size_t search_var(str_t name);
size_t add_var(str_t name, str_t value);
 
#endif
var.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "var.h"
 
size_t search_var(str_t name)
{
    size_t i;
 
    for (i = 0; i < vars_top; ++i)
        if (str_cmp(name, vars[i].name) == 0)
            return i;
 
    return -1;
}
 
size_t add_var(str_t name, str_t value)
{
    if (search_var(name) == -1)
    {
        str_cpy(vars[vars_top].name, name);
        str_cpy(vars[vars_top].value, value);
    }
 
    return vars_top++;
}
interpreter.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef INTERPRETER_H
#define INTERPRETER_H
 
#include <stdio.h>
#include <stdlib.h>
 
#include "service_functions.h"
#include "var.h"
 
extern var_t vars[BUF_SIZE * 2];
 
int check_brackets(str_t src_code);
void var_sub(str_t *src_code, FILE *input);
void parse(str_t src_code, FILE *output, FILE *err);
 
void interpret(str_t src_code, FILE *input, FILE *output, FILE *err);
 
#endif
interpreter.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
#include "interpreter.h"
 
var_t vars[BUF_SIZE * 2];
 
int check_brackets(str_t src_code)
{
    size_t src_len = str_len(src_code);
 
    str_t stack = (str_t)allocate(src_len * sizeof(char_t));
    size_t top = 0;
 
    size_t i;
 
    for (i = 0; i < src_len; ++i)
    {
        switch (src_code[i])
        {
        case '[':
        case '{':
        case '(':
            stack[top++] = src_code[i];
 
            break;
 
        case ']':
            if (stack[--top] != '[')
            {
                deallocate(stack);
 
                return -1;
            }
 
            break;
 
        case '}':
            if (stack[--top] != '{')
            {
                deallocate(stack);
 
                return -1;
            }
 
            break;
 
        case ')':
            if (stack[--top] != '(')
            {
                deallocate(stack);
 
                return -1;
            }
 
            break;
        }
    }
 
    deallocate(stack);
 
    if (top != 0)
        return -1;
 
    return 0;
}
 
void var_sub(str_t *src_code, FILE *input)
{
    str_t var_start_pos, var_end_pos;
 
    char_t var_name[BUF_SIZE];
    char_t var_value[BUF_SIZE];
    size_t var_index;
 
    size_t i;
 
    for (i = 0; i < str_len(*src_code); ++i)
    {
        var_start_pos = str_str(*src_code + i, "$(");
        var_end_pos = str_chr(*src_code + i, ')');
 
        if (var_start_pos == NULL || var_end_pos == NULL)
            break;
 
        if (var_start_pos != *src_code && *(var_start_pos - 1) == '\\')
        {
            i = var_start_pos - *src_code + 1;
 
            continue;
        }
 
        str_n_cpy(var_name, var_start_pos, var_end_pos - var_start_pos + 1);
 
        var_name[var_end_pos - var_start_pos + 1] = '\0';
 
        if ((var_index = search_var(var_name)) == -1)
        {
            if (input == stdin)
                printf("%s = ", var_name);
 
            str_cpy(var_value, get_str(input));
 
            var_index = add_var(var_name, var_value);
        }
        else
        {
            str_cpy(var_value, vars[var_index].value);
        }
 
        str_replace(src_code, var_name, vars[var_index].value);
    }
}
 
void parse(str_t src_code, FILE *output, FILE *err)
{
    size_t src_len = str_len(src_code);
 
    str_t block;
    size_t block_size;
    
    char_t num[BUF_SIZE];
 
    int level;
    
    size_t loop_count;
 
    char_t ch;
 
    size_t i, j;
 
    for (i = 0; i < src_len; ++i)
    {
        if (src_code[i] == '[')
        {
            for (j = i + 1, level = 1; level != 0; ++j)
            {
                if (src_code[j] == '[')
                {
                    ++level;
                }
                else
                {
                    if (src_code[j] == ']')
                        --level;
                }
            }
 
            block_size = j - i - 1;
 
            block = (str_t)allocate(block_size * sizeof(char_t));
 
            str_n_cpy(block, src_code + i + 1, block_size - 1);
 
            block[block_size - 1] = '\0';
 
            loop_count = 1;
 
            i = j;
 
            if (src_code[i] == '{')
            {
                j = str_chr(src_code + i + 1, '}') - src_code;
 
                if (i == j - 1)
                {
                    fprintf(err, "Syntax error!\n");
 
                    exit(-1);
                }
 
                str_n_cpy(num, src_code + i + 1, j - i - 1);
 
                num[j - i - 1] = '\0';
 
                loop_count = str_to_int(num, 10);
            }
 
            i = j;
 
            for (j = 0; j < loop_count; ++j)
                parse(block, output, err);
 
            deallocate(block);
        }
        else
        {
            if (src_code[i] == ']')
                continue;
            
            if (src_code[i] == '{' || src_code[i] == '}')
            {
                fprintf(err, "Syntax error!\n");
 
                exit(-1);
            }
 
            if (src_code[i] == '\\')
            {
                switch (src_code[i + 1])
                {
                case 't':
                    ch = '\t';
 
                    break;
 
                case 'n':
                    ch = '\n';
 
                    break;
 
                case '\\':
                    ch = '\\';
 
                    break;
 
                case 'x':
                    str_n_cpy(num, src_code + i + 2, 4);
 
                    num[4] = '\0';
 
                    ch = (char_t)str_to_int(num, 16);
 
                    i += 4;
 
                    break;
 
                default:
                    ch = src_code[i + 1];
 
                    break;
                }
 
                i += 2;
            }
            else
            {
                ch = src_code[i++];
            }
 
            loop_count = 1;
 
            if (src_code[i] == '{')
            {
                j = str_chr(src_code + i + 1, '}') - src_code;
 
                if (i == j - 1)
                {
                    fprintf(err, "Syntax error!\n");
 
                    exit(-1);
                }
 
                str_n_cpy(num, src_code + i + 1, j - i - 1);
 
                num[j - i - 1] = '\0';
 
                loop_count = str_to_int(num, 10);
 
                i = j + 1;
            }
 
            for (j = 0; j < loop_count; ++j)
                fprintf(output, "%c", ch);
 
            --i;
        }
    }
}
 
void interpret(str_t src_code, FILE *input, FILE *output, FILE *err)
{
    size_t src_len = str_len(src_code);
    str_t src_copy = (str_t)allocate((src_len + 1) * sizeof(char_t));
 
    str_cpy(src_copy, src_code);
 
    if (check_brackets(src_copy) != 0)
    {
        printf("Brackets is unbalanced!\n");
 
        deallocate(src_copy);
 
        exit(-1);
    }
    else
    {
        var_sub(&src_copy, input);
        parse(src_copy, output, err);
    }
 
    printf("\n");
 
    deallocate(src_copy);
}
main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
 
#include "service_functions.h"
#include "var.h"
#include "interpreter.h"
 
int main(void)
{
    str_t code = get_str(stdin);
 
    interpret(code, stdin, stdout, stderr);
 
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.09.2011, 16:45     Небольшое тестовое задание в финской компании.
Еще ссылки по теме:

Тестовое задание на Junior C++ dev C++
ООП. Тестовое задание собеседования. C++
C++ Тестовое задание для трудоустройства

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
17.09.2011, 16:45  [ТС]     Небольшое тестовое задание в финской компании. #65
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Päivää!
В аттаче мой вариант. Как тут кто-то верно заметил -- парсер прост, как машина "бреинфак".

Далее описание. Длинное. Можно не читать.
------------
код достаточно корявенький и длинный (ажна 3 блока копипасты кстати этим объясняется размер исходника + еще отступы - пробелы). Сейчас бы сделал все гораздо меньше.
Никаких деревьев. Все делается одним большим циклом по строке и пишется в другую строку (которая передается как параметр функции).
Из особенностей:
длина входной строки не ограничена
длина выходной строки ограничена и парсер заканчивает свою работу, при достижении конца этой строки (это можно отменить флагом в параметрах).
При парсинге не используются сторонние функции вообще.
Правила:
- переменная начинается с символа $ либо любого другого, переданного функции.
- переменная отдается в функцию со всеми параметрами. Функция должна вернуть C-строку, либо 0.

далее то, что выходит за рамки изначального задания и делалось джаст фо лулс + еще для использования в одном проектике.

- переменные (у меня они называются макросы) могут встречаться в любой части строки, в том числе в именах других макросов и в параметрах других макросов.
C
1
$macroname($pamarasmacro(), param2,,,)
тут сначала выполнится $paramasmacro() , потом колбеку придет имя макро с именем macroname и 5ю параметрами (3 последние пустые, первый тоже может быть пустой, если paramasmacro ничего не вернет).
C
1
$mac$t()roname($pamarasmacro(), param2,,,)
тоже валидная строка. используется динамическое получение имени макроса.

- Последовательности:
[] как и предполагалось -- повторение строки, но с течением времени заменил немного значение.
Во-первых цикл всегда выполняется минимум 1 раз то есть [!]{0} вернет !, а не ничего.
во-вторых цикл - это реальный цикл. и если я в строке укажу [$conter()]{5} то колбек будет дернут 5 раз. и каждый раз может вернуться разное значение:
C
1
"this is test: [ counter()]{5}!" = "this is test:  1 2 3 4 5!"
в аттаче в main.c есть пример таблицы умножения:
C
1
char mul_table[] = "$set(max, 13)\\n[[$(multiply) ]{$(max)}\\n]{$(max)}\\n";
Результат:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
    1     2     3     4     5     6     7     8     9    10    11    12    13 
    2     4     6     8    10    12    14    16    18    20    22    24    26 
    3     6     9    12    15    18    21    24    27    30    33    36    39 
    4     8    12    16    20    24    28    32    36    40    44    48    52 
    5    10    15    20    25    30    35    40    45    50    55    60    65 
    6    12    18    24    30    36    42    48    54    60    66    72    78 
    7    14    21    28    35    42    49    56    63    70    77    84    91 
    8    16    24    32    40    48    56    64    72    80    88    96   104 
    9    18    27    36    45    54    63    72    81    90    99   108   117 
   10    20    30    40    50    60    70    80    90   100   110   120   130 
   11    22    33    44    55    66    77    88    99   110   121   132   143 
   12    24    36    48    60    72    84    96   108   120   132   144   156 
   13    26    39    52    65    78    91   104   117   130   143   156   169
думаю понятно, откуда взялось 13. $set(max, 13)

Циклы могут быть вложенные (как в примере выше).

{} - итератор цикла [] либо последнего символа.
C
1
$macro(){5}
это не повторение значения макроса 5 раз, а повторение последнего символа результата.

esc последовательности:
такие последовательности идут после символа \. все неизвестное парсер пропускает как есть \i = \i
можно задать код символа в нескольких разных системах счисления:
C
1
2
3
4
5
6
\123 - 10
\xF0 - 16
\01234742 - 8
\B010010010  - 2
\T12210012 - 3 
\q12301230123 - 4
Кстати {} так же может принимать такие же значения. {xF} = {15}
----
еще про макросы:
общая длина макроса с параметрами задается в заголовке дефайном. Количество параметров там же

параметры отделяются друг от друга пробелами, либо запятыми. параметр в "это цельный параметр" - цельные параметры.

Маросы могут вернуть строку, могут вернуть другие макросы и вообще любые последовательности. (да, можно получить рекурсию )
....
Еще особенности: для парсера не существует ошибок. любую строку он съест и сделает, что сможет.

Все символы и возможности можно менять соответсвующими дефайнами. например скобки сделать <> вместо ()

На этом все. если вдруг что непонятно отвечу.
Вложения
Тип файла: zip rep-macro.zip (11.2 Кб, 13 просмотров)
Yandex
Объявления
17.09.2011, 16:45     Небольшое тестовое задание в финской компании.
Ответ Создать тему
Опции темы

Текущее время: 00:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru