将数组分配给数组

时间:2013-09-23 14:53:20

标签: c++ arrays

所以我正在玩一些数组,我无法弄清楚为什么这不起作用。

int numbers[5] = {1, 2, 3};
int values[5] = {0, 0, 0, 0, 0};
values = numbers; 

出现以下错误:

Error   1   error C2106: '=' : left operand must be l-value c:\users\abc\documents\visual studio 2012\projects\consoleapplication7\consoleapplication7\main.cpp 9   1   ConsoleApplication7

为什么我不能这样做?错误是什么意思?

6 个答案:

答案 0 :(得分:25)

由于C ++与C的向后兼容性,数组具有各种丑陋的行为。其中一种行为是数组不可分配。请改用std::arraystd::vector

#include <array>
...
std::array<int,5> numbers = {1,2,3};
std::array<int,5> values = {};
values = numbers;

如果出于某种原因必须使用数组,则必须通过循环或使用循环的函数复制元素,例如std::copy

#include <algorithm>
...
int numbers[5] = {1, 2, 3};
int values[5] = {};
std::copy(numbers, numbers + 5, values);

作为旁注,您可能已经注意到我初始化values数组的方式有所不同,只是提供了一个空的初始化列表。我依赖于标准中的规则,该规则说如果为聚合提供初始化列表,无论多么偏倚,所有未指定的元素都会被初始化。对于整数类型,值初始化意味着初始化为零。所以这两者完全等同:

int values[5] = {0, 0, 0, 0, 0};
int values[5] = {};

答案 1 :(得分:6)

你不能用C ++分配数组,这是愚蠢的,但它是真的。您必须逐个复制数组元素。或者您可以使用内置函数,例如memcpystd::copy

或者您可以放弃数组,而是使用std::vector。他们可以被分配。

答案 2 :(得分:3)

数组名称是常量而不是可修改的l值,您无法修改它。

values = numbers; 
// ^
// is array name

读取编译器错误消息:"error C2106: '=' : left operand must be l-value"可修改的l值可以出现在=的lhs。

您可以为指针指定数组名称,例如:

int* ptr = numbers;

注意:数组名称是常量,但您可以修改其内容,例如value[i] = number[i]0 <= i < 5的有效表达式。

  

为什么我不能这样做?

基本上这种约束是由语言强加的,内部数组名称用作基地址,通过索引基地址,您可以访问内容继续为数组分配的内存。所以在C / C ++中,数组名称出现在lhs而不是l值。

答案 3 :(得分:0)

values = numbers; 因为数字和值是指针。

int numbers[5] = {1, 2, 3};
int values[5] = {0, 0, 0, 0, 0};
for(int i = 0;i < 5; i ++){
    values[i] = numbers[i];
}

答案 4 :(得分:0)

std::array是一个好主意,但这也是可能的:

struct arr { int values[5]; };

struct arr a{{1, 2, 3}};
struct arr b{{}};

a = b;

否则,请使用std::memcpystd::copy

答案 5 :(得分:0)

我认为不可分配性的原因是C想要确保指向数组中任何元素的任何指针几乎总是保持有效。

考虑允许动态调整大小的向量:调整大小自动发生后,较旧的指针变为无效(可怕)。

PS。按照矢量的设计原理,以下块效果很好。

import SwiftUI

struct ContentView: View {
    @State private var baseNumber = ""
    @State private var dimensionSelection = 1
    @State private var baseUnitSelection = 0
    @State private var convertedUnitSelection = 0

    let temperatureUnits = ["Celsius", "Fahrenheit", "Kelvin"]
    let lengthUnits = ["meters", "kilometers", "feet", "yards", "miles"]
    let timeUnits = ["seconds", "minutes", "hours", "days"]
    let volumeUnits = ["milliliters", "liters", "cups", "pints", "gallons"]
    let dimensionChoices = ["Temperature", "Length", "Time", "Volume"]
    let dimensions: [[String]]

    init () {
        dimensions = [temperatureUnits, lengthUnits, timeUnits, volumeUnits]
    }

    var convertedValue: Double {

        var result: Double = 0
        let base = Double(baseNumber) ?? 0
        if temperatureUnits[baseUnitSelection] == "Celsius" {
            if convertedUnitSelection == 0 {
                result = base
            } else if convertedUnitSelection == 1 {
                result = base * 9/5 + 32
            } else if convertedUnitSelection == 2 {
                result = base + 273.15
            }
        }

        return result
    }


    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Enter a number", text: $baseNumber)
                        .keyboardType(.decimalPad)
                }

                Section(header: Text("Select the type of conversion")) {
                    Picker("Dimension", selection: $dimensionSelection) {
                        ForEach(0 ..< dimensionChoices.count) {
                            Text(self.dimensionChoices[$0])
                        }
                    }.pickerStyle(SegmentedPickerStyle())
                }

                Group {
                    Section(header: Text("Select the base unit")) {
                        Picker("Base Unit", selection: $baseUnitSelection) {
                            ForEach(0 ..< self.dimensions[self.dimensionSelection].count) {
                                Text(self.dimensions[self.dimensionSelection][$0])
                            }
                        }.pickerStyle(SegmentedPickerStyle())
                    }

                    Section(header: Text("Select the unit to convert to")) {
                        Picker("Converted Unit", selection: $convertedUnitSelection) {
                            ForEach(0 ..< self.dimensions[self.dimensionSelection].count) {
                                Text(self.dimensions[self.dimensionSelection][$0])
                            }
                        }.pickerStyle(SegmentedPickerStyle())
                    }
                }

                Section(header: Text("The converted value is")) {
                    Text("\(convertedValue) \(dimensions[dimensionSelection][convertedUnitSelection])")
                }

            }.navigationBarTitle("Unit Converter")
        }
    }
}