[C/C++]原生数组不可赋值引起的编译错误该如何解决?

在 C/C++ 中,原生数组(C-style array)不可直接赋值的特性确实导致编译错误

下面是本人在刷算法题写cmp函数时遇到的错误:

1
2
3
4
5
6
7
bool cmp(int a[5], int b[5]) {
if(a[4] != b[4])
return a[4] > b[4];
if(a[1] != b[1])
return a[1] > b[1];
return a[0] < b[0];
}

根本原因

  1. 数组名本质 数组名 arr1 实际上是一个指向首元素的常量指针int* const) 在传递时,数组作为函数参数时退化为指针
  2. 看似接受两个长度为5的数组,但实际等价于
1
bool cmp(int* a, int* b) { ... }

有些编译器可能不会报错,但我装的mingw估计管的挺严的,没让我过编译

修正方案

  1. 显示传递数组大小
1
bool cmp(int* a, int* b, size_t size) { ... }
  1. 使用数组引用
1
bool cmp(int (&a)[5], int (&b)[5]) { ... }

别几把用你那静态数组了,还是看看远处的array和vector吧

1
2
3
bool cmp(const array<int,5>& a, const array<int,5>& b) { ... }

bool cmp(const vector<int>& a, const vector<int>& b) { ... }

为什么array和vector可以?

std::arraystd::vector 之所以支持直接赋值和完整的拷贝语义,是因为它们是基于**类模板(class template)**设计的容器类型。而原生数组是 C/C++ 的内置基础类型

  1. 臭几把原生数组在C/C++中是基础的数据结构,它们的实现比较原始,

    • 没有构造函数、析构函数或成员函数

    • 没有重载的赋值运算符(operator=

    • 直接操作内存,无法实现深拷贝

  2. std::array是一个模板类,封装了原生数组并且提供了更加安全的接口,类本身重载了operator=,有更好的封装接口,赋值操作是逐个元素拷贝的

  3. 至于std::vector大人不必多说,是动态数组容器,拥有完整的拷贝语义(深拷贝)

准备新生赛ing…