所以我正在玩一些数组,我无法弄清楚为什么这不起作用。
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
为什么我不能这样做?错误是什么意思?
答案 0 :(得分:25)
由于C ++与C的向后兼容性,数组具有各种丑陋的行为。其中一种行为是数组不可分配。请改用std::array
或std::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 ++分配数组,这是愚蠢的,但它是真的。您必须逐个复制数组元素。或者您可以使用内置函数,例如memcpy
或std::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::memcpy
或std::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")
}
}
}