数组
一、数组的两个特殊性质
(1)不允许拷贝和赋值
不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。
int a[] = {0,1,2}; // 含有三个整数的数组
int s2 = a; // 错误:不允许使用一个数组初始化另一个数组
a2 = a; // 错误:不能把一个数组直接赋值给另一个数组
数组的拷贝可以使用memcpy()函数:
int des[5], src[3]
memcpy(des, src, sizeof(src));
(2)使用数组是通常将其转化成指针
在C++语言中,指针和数组有非常紧密的联系。使用数组的时候编译器一般会把它转换成指针。
通常情况下,使用取地址符来获取指向某个对象的指针,取地址符也可以用于任何对象。数组的元素也是对象,对数组使用下标运算符得到该数组指定位置的元素。因此像其他对象一样,对数组的元素使用取地址符就能的搭配指向该元素的指针:
string nums[] = {"one", "two", "three"}; // 数组元素是string对象
string *p = &nums[0]; // p指向nums的第一个元素
例子:
char pdata[256];
memset(pdata, 0, sizeof(pdata));
sprintf(pdata, "sdk(1) send rs485 data to camera.");
int len = strlen(pdata);
//第二个形参类型时char *
TransSerialPort(m_hSDK[0], pdata, len+1);//发送rs485数据
当使用vector<char> pdata时:
TransSerialPort(m_hSDK[0], &pdata[0], len+1);//发送rs485数据
然而,数组还有一个特性:在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针:
string *p2 = nums; // 等价于p2 = &nums[0]
在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。
二、数组作为函数参数
数组的两个特殊性质对我们定义和使用作用在数组上的函数有影响。因为不能拷贝数组,所以我们无法以值传递的方式使用数组参数。因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。
尽管不能以值传递的方式传毒数组,但是我们可以把形参写成类似数组的形式:
在数组中,值传递就是指针地址的传递,对于数组来说却是一个例外,因为数组的数据太多了,将其一一赋值既麻烦又浪费空间,所以数组作为参数传递给函数的只是数组首元素的地址,函数在需要用到后面元素时再按照这个地址和数组下标去查找,在C++中,如果要给一个函数传入一个数组,一般都是传入两个参数:一个数组指针和一个数组大小。所以,函数调用的数组会对本身的数组造成影响,这点和值传递是不同的。
同时,作为函数形参的数组和指针可以互换,这种转换仅限于函数形参的声明。这是一种便利,传递时数组会蜕变为指针,事实上数组从来没有传入过函数。
eg:以下3个声明是等价的
- void insert(int *);
- void insert(int []);
- void insert(int [10]); //这里的维度表示我们期望数组含有多少元素,实际不一定
数组长度不是参数类型的一部分。函数和编译器都不知道传统给它的数组的长度的大小。
2.如果我们要传入指定长度数组,又该怎么办呢?
我们可以将参数声明为数组的引用,此时,数组长度成为形参和实参的一部分。
eg:void insert( int (&arr)[10])
例如:
void print_3 (int (&datas) [3])
{
for (int i = 0; i < 3; ++i)
{
std::cout << datas[i] << " ";
}
std::cout << std::endl;
}
这时,我们如果这样使用是正确的
const int N = 3;
int datas[N] = {1, 2, 3};
print_3 (datas);
而我们如果这样使用,编译器会报错
int datas2[N - 1] = {1, 2};
print_3 (datas2);
在上面这个例子(print_3)的基础上,我们可以使用模板进行泛型实现
template<int N>
void print_4 (int (&datas)[N])
{
for (int i = 0; i < N; ++i)
{
std::cout << datas[i] << " ";
}
std::cout << std::endl;
}
这时候,我们可以传递任意大小数组,而不担心给函数传入了错误的参数
const int N = 3;
int datas[N] = {1, 2, 3};
print_4 (datas);
int datas2[N - 1] = {1, 2};
print_4 (datas2);
假如我们给传了错误参数,函数将会报错
const int N = 3;
int datas[N] = {1, 2, 3};
print_4<4 > (datas);
参考资料:
详谈C++中数组作为函数参数 - CSDN博客 http://blog.csdn.net/oNever_say_love/article/details/49422517
C++学习笔记(四)——关于数组作为函数参数的值传递和引用传递 - CSDN博客 http://blog.csdn.net/ForeverSober/article/details/45441685
C++给函数传数组参数 - CSDN博客 http://blog.csdn.net/hongjiqin/article/details/5739935
C语言中值得深入知识点----数组做函数参数、数组名a与&a区别、数组名a的"数据类型" - CSDN博客 http://blog.csdn.net/jin13277480598/article/details/51891816