为什么c++中内置数组类型不支持数组之间的赋值,支持这种操作需要什么信息?
展开全部
源代码级别和C语言兼容性的考虑。当年的C++完全向下兼容C;虽然现在标准C和标准C++有相当大的差别,但是表面上的公共语言特性都没有很大改变。
C语言中,数组在许多情况下都会隐式转换为对应的指向数组首个元素的指针(对应的类型转换称为退化)。有了数组的退化特性,同时通过p[i]和*(p+i)的等价性就可以以比较方便的语法形式引用数组的元素;且在参数传递时数组退化为指针对一般目的而言是比较高效的,无需按值传递(复制)整个数组。这样做的副作用就是对于operator=而言,为了维护左操作数作为数组名或对应指针名表现的行为的一致性(注意C语言中没有运算符重载,内置运算符的行为对于各种类型而言语义大体一致),数组在这里退化为指针而不表示整个数组。而数组退化得到的指针是常量,因此数组无法作为operator=的左操作数。
理论上要实现数组的内置赋值操作也不复杂,不过应该需要比较严格的类型检查,比如数组类型(元素类型和长度)完全相同或者元素类型相同但左操作数的长度大于等于右操作数的长度,但这样应用很有限,并不是必要的。而且会导致上面的“=”的二义性问题。
实际上用循环对元素进行逐个赋值就可以解决这个问题。C标准库函数memcpy可以实现连续存储器区域按值复制的赋值语义,同样适用于数组(C/C++的数组占据连续的地址空间)。
C++中,可以使用循环或对应的std::memcpy。此外,也可以自行实现成员为数组的结构体/类,然后重载operator[]和operator=实现可用=表示赋值的自定义数组。例如:
template<typename _elementType>
class MyArray
{
private:
_elementType* m_array;
public:
operator=(const _elementType&); //赋值:复制元素的实现可以用std::copy。
operator=(_elementType*); //指针兼容的赋值:考虑内存管理,比较麻烦,不一定需要实现。内置数组是寄存器/自动存储类对象(动态分配得到的是指针不是数组),没有这个问题。
_elementType& operator[](std::size_t); //引用元素。
const _elementType& operator[](std::size_t) const;
operator _elementType*(); //退化。
operator const _elementType*() const;
};
(当然不支持“=”的设计也有一些缺陷。这样的语言特性导致数组不是first level citizen,除了直观性问题外,还有其它的副作用。例如,多维数组事实上是数组的数组,如果要用循环实现多维数组间部分元素的复制,支持内置“=”的话一个一重循环就够了,编译器可以推断出复制细节;而现在的需要用多重循环“=”,或者使用一重循环嵌套memcpy之类的用于实现复制细节的函数,形式上更麻烦。)
====
[原创回答团]
C语言中,数组在许多情况下都会隐式转换为对应的指向数组首个元素的指针(对应的类型转换称为退化)。有了数组的退化特性,同时通过p[i]和*(p+i)的等价性就可以以比较方便的语法形式引用数组的元素;且在参数传递时数组退化为指针对一般目的而言是比较高效的,无需按值传递(复制)整个数组。这样做的副作用就是对于operator=而言,为了维护左操作数作为数组名或对应指针名表现的行为的一致性(注意C语言中没有运算符重载,内置运算符的行为对于各种类型而言语义大体一致),数组在这里退化为指针而不表示整个数组。而数组退化得到的指针是常量,因此数组无法作为operator=的左操作数。
理论上要实现数组的内置赋值操作也不复杂,不过应该需要比较严格的类型检查,比如数组类型(元素类型和长度)完全相同或者元素类型相同但左操作数的长度大于等于右操作数的长度,但这样应用很有限,并不是必要的。而且会导致上面的“=”的二义性问题。
实际上用循环对元素进行逐个赋值就可以解决这个问题。C标准库函数memcpy可以实现连续存储器区域按值复制的赋值语义,同样适用于数组(C/C++的数组占据连续的地址空间)。
C++中,可以使用循环或对应的std::memcpy。此外,也可以自行实现成员为数组的结构体/类,然后重载operator[]和operator=实现可用=表示赋值的自定义数组。例如:
template<typename _elementType>
class MyArray
{
private:
_elementType* m_array;
public:
operator=(const _elementType&); //赋值:复制元素的实现可以用std::copy。
operator=(_elementType*); //指针兼容的赋值:考虑内存管理,比较麻烦,不一定需要实现。内置数组是寄存器/自动存储类对象(动态分配得到的是指针不是数组),没有这个问题。
_elementType& operator[](std::size_t); //引用元素。
const _elementType& operator[](std::size_t) const;
operator _elementType*(); //退化。
operator const _elementType*() const;
};
(当然不支持“=”的设计也有一些缺陷。这样的语言特性导致数组不是first level citizen,除了直观性问题外,还有其它的副作用。例如,多维数组事实上是数组的数组,如果要用循环实现多维数组间部分元素的复制,支持内置“=”的话一个一重循环就够了,编译器可以推断出复制细节;而现在的需要用多重循环“=”,或者使用一重循环嵌套memcpy之类的用于实现复制细节的函数,形式上更麻烦。)
====
[原创回答团]
参考资料: 原创
2012-03-01
展开全部
数组名其实代表着一个指针常量,所以将一下数组名赋值给另一个数组,就像是把常量5赋值给常量3一样,虽然语法正确,但在语意层面上会产生错误。
C++语言并未支持数组的赋值操作,编译器在编译时必须知道数组的长度,才能产生执行代码,支持数组对数组的操作。
C++语言并未支持数组的赋值操作,编译器在编译时必须知道数组的长度,才能产生执行代码,支持数组对数组的操作。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
for(i = 0; i < n; i++)
b[i] = a[i];
或者用memcpy
void * memcpy ( void * destination, const void * source, size_t num );
http://www.cplusplus.com/reference/clibrary/cstring/memcpy/
b[i] = a[i];
或者用memcpy
void * memcpy ( void * destination, const void * source, size_t num );
http://www.cplusplus.com/reference/clibrary/cstring/memcpy/
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询