2013-05-10 6 views
7

Пожалуйста, посмотрите на файл followng заголовкаКак создать массив байтов в C++?

#pragma once 

class MissileLauncher 
{ 
public: 
    MissileLauncher(void); 

private: 
    byte abc[3]; 
}; 

Это вызвало ошибку

Error 1 error C2143: syntax error : missing ';' before '*' 

Я пытался сделать это таким образом

byte *abc; 

но это также не удалось, то же самое ошибка. Тем не менее, я заметил, что я могу вызвать другие встроенные массивы tyes таким образом, например, для массива int. Почему это происходит с байтом? Как это решить? Я хотел бы присвоить значения в файле cpp. Есть идеи?

+2

Там нет '*' в коде вы представляете, так что это не может генерировать это сообщение об ошибке. Пожалуйста, будьте аккуратны. – delnan

+2

Кроме того, откуда берется 'byte'? Это не стандартный тип. –

ответ

17

Попробуйте

class MissileLauncher 
{ 
public: 
    MissileLauncher(void); 

private: 
    unsigned char abc[3]; 
}; 

или

using byte = unsigned char; 

class MissileLauncher 
{ 
public: 
    MissileLauncher(void); 

private: 
    byte abc[3]; 
}; 

** Примечание: В старых компиляторах (не C++ 11) заменить using линию typedef unsigned char byte;

+0

'char' не должен быть одним байтом – Yola

7

Байт не является стандартным типом на C или C++. Попробуйте char, который обычно и не менее 8 бит.

+0

Спасибо за ответ. Итак, используя char array? Может ли он отправлять значения в порты USB так же, как и байты? \ – Soldier

+1

Когда вы используете символ, это точно один байт; поэтому отправьте «char» на USB-порт в C/C++, вы фактически отправляете байт. –

+0

Спасибо большое! +1 от меня! – Soldier

10

Если вы хотите ровно один байт, uint8_t, определенный в cstdint, будет наиболее выразительным.

http://www.cplusplus.com/reference/cstdint/

+0

Также, C++ 11 кажется. –

+0

@MichaelPrice, нет, он доступен и на предыдущих C++. Используйте вместо . Я использую его сегодня в некотором коде, когда мы говорим. :-) –

+0

@ KellyBeard - доступен только после отправки C++ 11 (в качестве стандартного переносного метода). и не совсем то же самое. –

6

Может быть, вы можете использовать тип std::bitset доступный в C++ 11. Его можно использовать для представления фиксированной последовательности из разрядов N, которые могут быть использованы обычной логикой.

#include<iostream> 
#include<bitset> 

class MissileLauncher { 
public: 
    MissileLauncher() {} 
    void show_bits() const { 
    std::cout<<m_abc[2]<<", "<<m_abc[1]<<", "<<m_abc[0]<<std::endl; 
    } 

    bool toggle_a() { 
    // toggles (i.e., flips) the value of `a` bit and returns the 
    // resulting logical value 
    m_abc[0].flip(); 
    return m_abc[0]; 
    } 

    bool toggle_c() { 
    // toggles (i.e., flips) the value of `c` bit and returns the 
    // resulting logical value 
    m_abc[2].flip(); 
    return m_abc[2]; 
    } 

    bool matches(const std::bitset<3>& mask) { 
    // tests whether all the bits specified in `mask` are turned on in 
    // this instance's bitfield 
    return ((m_abc & mask) == mask); 
    } 

private: 
    std::bitset<3> m_abc; 
}; 

typedef std::bitset<3> Mask; 
int main() { 
    MissileLauncher ml; 

    // notice that the bitset can be "built" from a string - this masks 
    // can be made available as constants to test whether certain bits 
    // or bit combinations are "on" or "off" 
    Mask has_a("001");  // the zeroth bit 
    Mask has_b("010");  // the first bit 
    Mask has_c("100");  // the second bit 
    Mask has_a_and_c("101"); // zeroth and second bits 
    Mask has_all_on("111"); // all on! 
    Mask has_all_off("000"); // all off! 

    // I can even create masks using standard logic (in this case I use 
    // the or "|" operator) 
    Mask has_a_and_b = has_a | has_b; 
    std::cout<<"This should be 011: "<<has_a_and_b<<std::endl; 

    // print "true" and "false" instead of "1" and "0" 
    std::cout<<std::boolalpha; 

    std::cout<<"Bits, as created"<<std::endl; 
    ml.show_bits(); 
    std::cout<<"is a turned on? "<<ml.matches(has_a)<<std::endl; 
    std::cout<<"I will toggle a"<<std::endl; 
    ml.toggle_a(); 
    std::cout<<"Resulting bits:"<<std::endl; 
    ml.show_bits(); 
    std::cout<<"is a turned on now? "<<ml.matches(has_a)<<std::endl; 
    std::cout<<"are both a and c on? "<<ml.matches(has_a_and_c)<<std::endl; 
    std::cout<<"Toggle c"<<std::endl; 
    ml.toggle_c(); 
    std::cout<<"Resulting bits:"<<std::endl; 
    ml.show_bits();  
    std::cout<<"are both a and c on now? "<<ml.matches(has_a_and_c)<<std::endl; 
    std::cout<<"but, are all bits on? "<<ml.matches(has_all_on)<<std::endl; 
    return 0; 
} 

Компиляция с помощью GCC 4.7.2

g++ example.cpp -std=c++11 

я получаю:

This should be 011: 011 
Bits, as created 
false, false, false 
is a turned on? false 
I will toggle a 
Resulting bits: 
false, false, true 
is a turned on now? true 
are both a and c on? false 
Toggle c 
Resulting bits: 
true, false, true 
are both a and c on now? true 
but, are all bits on? false 
+0

wow .. Большое спасибо за ответ! +1 от меня! – Soldier

1

Вы можете использовать Qt, который, в случае, если вы не знаете, C++ с кучей дополнительные библиотеки и классы и многое другое. Qt имеет очень удобный класс QByteArray, который, я уверен, подойдет вашим потребностям.

http://qt-project.org/

2

Байт не является стандартным типом данных в C/C++, но он все еще может быть использован так, как я полагаю, вы хотите. Вот как это сделать: Вспомните, что байт представляет собой восьмибитовый размер памяти, который может представлять любое из целых чисел от -128 до 127 включительно. (В этом диапазоне 256 целых чисел, восемь бит могут представлять 256 - два, поднятые до восьми - разные значения.). Также напомним, что символ в C/C++ - один байт (восемь бит). Итак, все, что вам нужно сделать, чтобы иметь тип данных байта в C/C++, должен помещать этот код в начало исходного файла: #define byte char Итак, теперь вы можете объявить байт abc [3];

-1

Байт не является стандартным типом в C/C++, поэтому он представлен char.

Преимущество этого в том, что вы можете обрабатывать basic_string в виде массива байтов, что позволяет безопасно хранить и передавать функции.Это поможет вам избежать утечек памяти и сбоев сегментации, которые могут возникнуть при использовании различных форм char[] и char*.

Например, это создает строку как массив байт нулевых значений:

typedef basic_string<unsigned char> u_string; 

u_string bytes = u_string(16,'\0'); 

Это позволяет для стандартных поразрядных операций с другими char значений, в том числе тех, которые хранятся в других string переменных. Например, чтобы XOR в char значения другого u_string по bytes:

u_string otherBytes = "some more chars, which are just bytes"; 
for(int i = 0; i < otherBytes.length(); i++) 
    bytes[i%16] ^= (int)otherBytes[i]; 
+0

Уход за разъяснением голоса? Мы используем этот шаблон в нескольких системах уровня производства на ежедневной основе с нулевыми утечками памяти. –

+0

Я не являюсь нисходящим, но использование строк для хранения двоичных данных - очень плохая практика. Вы используете строчную реализацию для использования 8-байтных символов. На практике, особенно в современных системах, многие строковые реализации внутренне кодируют свои строки как UTF-8 или UTF-16 (кодирование с переменной длиной). Это означает, что ваш вызов '.length' будет ссылаться на количество глифов, а не на количество байтов. Если вы используете это на производственных системах, вы должны волноваться. Строки и байт-массивы имеют очень разные значения. –

+0

@Chris Итак, вы говорите, что вместо этого нужно использовать массив 'char', чтобы гарантировать 8-байтные символы? Печально, что это решение - введение ручного управления памятью символа 'char *', что, по моему опыту, является причиной примерно половины утечек памяти, которые вы видите в коде C/C++. –

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