2017-01-30 2 views
1

У меня есть 2, один со строкой и один с номером. Как я могу создать массив const из определения с строкой и номером. Также есть дополнительная константа, которая должна быть в этом массиве.C char string для массива

Как я могу написать этот код, чтобы иметь 0x22, 0x41, 0x42, 0x42, 0x21 в массиве foobar, из определений FOO и BAR?

#define FOO "AB" 
#define BAR 33 

extern int rs232_write(const unsigned char *data, unsigned char count); 

const unsigned char foobar[] = 
{ 
    0x22, 
    FOO[0], /*what must i put here, this do not work*/ 
    FOO[1], 
    0x42, 
    BAR, 
}; 


int main(void) 
{ 
    rs232_write(foobar,sizeof(foobar)); 
    return 1; 
} 

В НКУ, к примеру, я получаю сообщение об ошибке:

./001.c:9:5: error: initializer element is not constant 
    FOO[0], /*what must i put here*/ 
    ^

Строка всегда иметь одинаковую длину. я также попробовать наоборот:

#define FOO "AB" 
#define BAR 33 

extern int rs232_write(const unsigned char *data, unsigned char count); 

const char foobar[] = \ 
    "\x22" \ 
    FOO \ 
    "\x42" \ 
    BAR /*what must i put here, this also not work*/ 


int main(void) 
{ 
    rs232_write(foobar,sizeof(foobar)); 
    return 1; 
} 

Здесь я получаю также ошибки, например, GCC принтами:

./002.c:2:13: error: expected ‘,’ or ‘;’ before numeric constant 
#define BAR 33 
      ^

Я работаю на микроконтроллере с не так много места, поэтому я бы чтобы избежать создания массива во время выполнения, и мой компилятор поддерживает только C89.

+0

Что не так с кодом вы показать нам? –

+0

См. Комментарий, компилятор не принимает его (также пытался с gcc), «ошибка: элемент инициализации не является константой» и «error: expected», «or»; «перед числовой константой» – 12431234123412341234123

+0

При публикации вопросов о ошибках сборки, всегда включают точные ошибки (в неотредактированной и немодифицированной и, самое главное, полной * форме) в теле вопроса. Предпочтительно прямая копия пасты полного журнала построения. –

ответ

1

Самый простой, используя memcpy:

#include <stdio.h> 
#include <string.h> 

#define FOO "AB" 
#define BAR 33 

extern int rs232_write(const unsigned char *data, unsigned char count); 

unsigned char _foobar[] = 
{ 
    0x22, 
    0, 0, 
    0x42, 
    BAR, 
}; 
const unsigned char *foobar; 

int main(void) 
{ 
    foobar = (const unsigned char *)memcpy(_foobar + 1, FOO, 2) - 1; 
    rs232_write(foobar,sizeof(foobar)); 
    return 0; 
} 

Уродливые, используя X Macro и compound literal:

В этом случае вы могут использовать первые две цифры:

const unsigned char foobar[] = 
{ 
    0x22, 
    'A', 'B', 
    0x42, 
    33, 
}; 

или полная строка "AB"

#include <stdio.h> 

#define FOO X('A', 'B', '\0') 
#define BAR 33 

extern int rs232_write(const unsigned char *data, unsigned char count); 

const unsigned char foobar[] = 
{ 
    0x22, 
    #define X(a, b, c) a, b 
    FOO, 
    #undef X 
    #define X(a, b, c) ((char []){a, b, c}) 
    0x42, 
    BAR, 
}; 

int main(void) 
{ 
// rs232_write(foobar,sizeof(foobar)); 
    printf("%s\n", FOO); 
    return 0; 
} 

Выход:

AB 
+0

memcpy(), или в моем случае, просто напишите два значения, это я пытался избежать. но X Macro будет работать. Я не знал, что вы можете создать массив и одновременно вызвать вызов функции. – 12431234123412341234123

+0

Не является вызовом функции, посмотрите на ссылку: _Those функции в том, что макросы могут вызывать другие макросы, что макросы могут быть переопределены и что вложенный вызов макроса не расширяется до тех пор, пока макрос, который его вызывает, не будет расширен во время одного из его вызовы._ –

+0

Нет, я говорю о чем-то вроде 'strcpy (buffer, ((char []) {0x44,0x61,0})), что я могу вызвать strcpy() с массивом, который я не создавал раньше, и без строки, а не о макросах. – 12431234123412341234123

1

Это должно работать:

#include<stdio.h> 

#define FOO 'A','B' 
#define BAR 33 

const char foobar[] = { 
    0x22, 
    FOO, 
    0x42, 
    BAR, 
    '\0' 
}; 

int main(void) 
{ 
    printf("%s\n", foobar); 
    return 0; 
} 

КСТАТИ это очень плохо для инициализации массива, так, может быть, вы можете объяснить вашу цель лучше.

+0

Но мне все еще нужно FOO как строка в других местах, так что можно создать строку const из этого определения? – 12431234123412341234123

+0

Он основан на двоичном протоколе rs232, который я не могу изменить, и мне нужно отправить имя и версию программного обеспечения в один пакет (группа кадров). – 12431234123412341234123

0

Проблема заключается в том, что компилятор не знает, во время компиляции, где строковый литерал "AB" будет помещен в память. Его местоположение будет определено при подключении программы или, возможно, при загрузке в память.

Поэтому использование этого параметра не приведет к константе времени компиляции, необходимой для инициализации массива foobar.

В этом случае у вас действительно нет опции, кроме как использовать установку foobar[1] и foobar[2] один раз во время выполнения. Однако даже в очень маленькой встроенной системе это не повлечет за собой слишком большие издержки как в памяти, так и во времени. Если программа работает более чем на несколько секунд, она, скорее всего, даже не будет измерима.

+0

Меня не волнует время, но использование памяти в моей программе уже является проблемой, и я стараюсь уменьшить ее, чтобы не было необходимости в оптимизации. 20 байт RAM может звучать крайне мало, но вы заметите это только с 1KiB – 12431234123412341234123

+0

@ 12431234123412341234123 Добавление инициализации во время выполнения добавит еще две инструкции. Если у вас есть только этот единственный массив, это вряд ли вызовет проблему. Если у вас много таких массивов, вы можете использовать только один, а затем инициализировать все во время выполнения. Код (часто) меньше данных. И почему бы вам не включить оптимизацию? Вы пытались построить, например, '-Os'? Разве это имеет значение? –

+0

@ 12431234123412341234123 О, и вы, вероятно, должны добавить все ограничения и целевую платформу к своему вопросу, это очень релевантная информация. –

1
#include <stdio.h> 
#include <stdlib.h> 

#define FOO   "ab" 
#define BAR   33 

#define STRINGIFY(x) STRINGIFY2(x) 
#define STRINGIFY2(x) #x 

const char foobar[] = "\x22" FOO "\x42" STRINGIFY(BAR); 

int main(void) 
{ 
    printf("foobar = |%s| (%ld+1 characters)\n", 
    foobar, (long) sizeof(foobar) - 1); 
    return EXIT_SUCCESS; 
} 

Запуск этой программы Выходы:

foobar = |"abB33| (6+1 characters) 
+0

Я хочу иметь байт 33 или в этом случае символ '!' в массиве, а не байтах 51 (0x33) или символе «3». Поэтому он должен печатать «abB!» – 12431234123412341234123

+0

@ 12431234123412341234123: Тогда почему бы не просто '#define BAR '\ x21" или '#define BAR"! "'? – AlexP

+0

Мне нужен BAR как целое число в других местах. но возможно я могу #define _BAR "!" и #define BAR _BAR [0] – 12431234123412341234123

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