2015-06-16 3 views
0

я в начинающем C++с ++ базовой инициализация массива из списка инициализаторов

Я думаю, что это тривиальный вопрос, но я не нашел ответ

почему этот код выдает ошибку? а если мы инициализировали массив в одной строке байт x [2] = {78,82} работает правильно?

Какая разница в указателе x в обоих случаях?

// example: one class, two objects 
#include <iostream> 
using namespace std; 
typedef unsigned char byte; 

int main() { 
    byte x[2]; 
    x = {78,82}; 
    cout << x << endl; 
} 

я только получаю эту ошибку из NetBeans

error: assigning to an array from an initializer list 
+1

C++, исходные массивы не могут быть (непосредственно) назначен. Вместо этого используйте 'std :: array'. Он обертывает необработанный массив в 'struct'. –

+0

Возможно, [это] (http://stackoverflow.com/questions/15603158/error-assigning-to-an-array-from-an-initializer-list) поможет вам – Noel

+0

Одно * сходство * заключается в том, что 'x' является не указатель в любом из случаев, это массив. – molbdnilo

ответ

3

почему этот код выдает ошибку?

Поскольку вы не можете назначать переменную массива. Массивы не могут передаваться по значению функциям или операторам как таковым. При использовании в контексте, где ожидается указатель, они распадаются на указатель на первый элемент.

Невозможно скопировать массив (или список инициализаторов) в другой, используя только указатели на первые элементы каждого массива. Для такой операции требуется информация о размере массивов.

Хороший анализ на почему присвоение не допускается here. Речь идет о распределении массива к массиву, но я полагаю, что это относится и к списку инициализаторов.

в то время как если мы инициализировали массив в одной строке байт x [2] = {78,82} работает правильно?

Это работает, потому что вы можете инициализировать переменную массива (в этом случае list initialization). Помните, что = выполняет разные действия в зависимости от того, используется ли он в объявлении или в заявлении без декларации. В объявлении это синтаксис для инициализации, в заявлении без декларации это оператор присваивания.

Какая разница в указателе x в обоих случаях?

x не является указателем, это массив. Разница только в том, что в одном случае вы инициализируете объекты в x, а в другом вы оставляете его неинициализированным, а затем пытаетесь присвоить ему список инициализаторов, что невозможно.

1

В массивах нет операторов присваивания. Вы должны скопировать элемент по элементу из исходного массива в целевой массив, например, с помощью стандартного алгоритма std::copy или используя стандартную функцию C memcpy или написать собственный цикл для задачи. Или вы можете установить отдельные элементы массива с помощью оператора индекса.

Однако стандарт позволяет инициализировать массивы со списками инициализатора как любые другие агрегаты, когда они определены

byte x[] = { 78, 82 }; // valid 
x = { 78, 82 }; // compilation error 

Также это заявление,

cout << x << endl; 

не имеет смысла, потому что этот массив не нуль- которые могут привести к неопределенному поведению.

Однако вы можете использовать стандартный класс std::array, который имеет оператор присваивания копии, потому что это класс, и компилятор неявно генерирует для него этот оператор.

Например

#include <iostream> 
#include <array> 

typedef unsigned char byte; 

int main() 
{ 
    std::array<byte, 2> x; 
    x = { { 78, 82 } }; 

    std::cout.write(reinterpret_cast<char *>(x.data()), x.size()) << std::endl; 
}  
Смежные вопросы