【C++ 深入浅出】int a[ ]数组和vector容器作为函数参数时加或不加引用&的区别

一. int a[ ] 数组作为函数参数(传递地址 0x7fff2bc25750)

int a[5] = {1,2,3,4,5};

  • *(a+i) <=> a[i]; // a为数组名

  • C++数组名作为函数参数传递后,其大小信息丢失,只剩下指向数组中第一个元素的信息,这也是为什么如果在接受数组参数的函数中访问数组的各个元素,需在定义数组的域范围将数组大小作为另一辅助参数传递

  • 实际上是将数组作为指针(常量地址)来传递,而该指针指向数组的第一个元素(意思是数组名是第一个元素的地址)。至于后面数组在哪里结束,C++的函数传递机制并不负责

  • 指针 p p 指向变量 a a 意思是 指针变量的内容值是 a a 的地址,也就是说 p = &a

  • test(a); // 在调用时数组只要写函数名,不需要写后面的括号
    void test(int a[]) { }
    等价于
    void test(int *a) { }

  • 二维数组的第二个括号内的参数必须写,调用数组时也是直接写函数名

void f(int x[][5]) {
  ...;
}
...
int a [10][5];
f(a); // 调用数组时也是直接写函数名

1.1 具体示例

int b[]; <==> int *const b;

数组名 b b 也是个指针(地址),只不过它是一个 c o n s t const 指针,也就是说 b b 的内容值不能被修改, b b 指向某个地方的事实不能被更改,b = &b[0]

数组名作为函数参数传递后,其大小信息丢失,只剩下指向数组中第一个元素的信息

函数参数表中的数组实际上是一个指针
sizeof(a) == sizeof(int *)

[]运算符可以对数组做,也可以对指针做

void test(int a[ ]); 接受地址,如0x7fff2bc25750

#include <iostream>

using namespace std;
 
// C++中数组作为函数参数是传地址,如传进去的地址是:0x7fff2bc25750
void test(int *a) // int a[]; 等价于 int *a;
{
  cout << endl;
 
  cout << "in func..." << endl;
  cout << "array address: " << a << endl; // 0x7fff2bc25750

  // 数组名作为函数参数传递后,其大小信息丢失,只剩下指向数组中第一个元素的信息
  cout << "array size: " << sizeof(a) << endl; // 8,因为地址的大小是8
  cout << "array element count: " << sizeof(a) / sizeof(a[0]) << endl; // sizeof(a[0])的大小是4,第一个是int还是知道的
 
  cout << "changing the 3th element's value to 10." << endl;
  
  *(a + 2) = 10;
  // a[2] = 10;
}
 
int main()
{
  int a[] = {1, 2, 3, 4, 5};
  int *b = a; // 新定义的指针的大小是8
  cout << "point b size: " << sizeof(b) << endl << endl;
  cout << "in main..." << endl;
  cout << "array address: " << a << endl; // 0x7fff2bc25750
  cout << "array size: " << sizeof(a) << endl;  // 20
  cout << "array element count: " << sizeof(a) / sizeof(a[0]) << endl; // 5
 
  test(a); // 在调用时数组只要写函数名即可
 
  cout << endl << "the 3th element's value: " << a[2] << endl;
 
  return 0;
}

输出结果如下:

point b size: 8

in main...
array address: 0x7fff5c8761e0
array size: 20
array element count: 5

in func...
array address: 0x7fff5c8761e0
array size: 8
array element count: 2
changing the 3th element's value to 10.

the 3th element's value: 10

二. vector 数组作为函数参数

2.1 vector数组加或不加引用&有很大区别

vector <int> a;

  • vector容器:不加引用&无法改变原vector的值,只是拷贝了一个副本
  • vector中的数组名v不是指针(地址),跟普通数组名是不同
#include <iostream>
#include <vector>
 
using namespace std;
 
// vector容器:不加引用无法改变原vector的值
// vector中的数组名v不是指针,跟普通数组名不同

// 不加引用&
void test1(vector<int> v) { 
    v[0] = 27; 
}

// 加引用&
void test2(vector<int> &v) { 
    v[0] = 27; 
}

int main()
{
  int a[] = {1, 2, 3, 4, 5};
  vector<int> v({36,0,834,29,13});
  test1(v); // v不是指针,跟普通数组名不同
  cout << "after test1 v[0] = " << v[0] << endl; // 36
  
  test2(v); 
  cout << "after test2 v[0] = " << v[0] << endl; // 27
 
  return 0;
}

2.2 vector忘记加引用的后果

想起了2月3日在牛客网做数组中的逆序对这个题时的悲惨经历,因为忘记在vector时加引用,浪费了我20分钟才Debug出来

你不加引用的话,是无法修改原vector的,谈何归并排序

发布了270 篇原创文章 · 获赞 111 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_43827595/article/details/104454424