C++学习笔记之数组

C++学习笔记之数组

https://www.runoob.com/cplusplus/cpp-arrays.html

C++当中,数组是用于存储固定大小相同类型元素顺序集合

数组是整体作为一个变量,其中又包含多个单独变量,作为其元素,如数组变量a,其包含a[0]~a[n]若干个元素作为一个个单独的变量
借助索引可以访问特定的元素

数组由连续的内存位置组成,比如长度为N的数组,对应的就是连续N个内存位置
内存位置由低到高,对应数组0~N-1的下标元素

1、声明数组

在声明数组的时候需要指定元素的类型和数量

类型 数组名[数组长度];

数组长度:大于0的整数常量
类型:任意有效C++数据类型

int arr[3];

2、初始化

数组可以逐个初始化或者使用一个初始化语句

int arr[3] = {1, 4, 7};

需要注意,{}中的元素个数不能多于[]中声明的元素个数
当然,也可以不指定[]中的数组长度,这样就按后面{}的元素个数初始化

int arr[] = {1, 4, 7};

对特定元素进行赋值:

arr[1] = 20;

在这里插入图片描述

3、访问数组元素

可以通过数组名加上索引的方式访问数组中指定的元素

int value = arr[1];

4、多维数组

超过一维的便是多维数组了,通常定义为:

类型 数组名[数组长度1][数组长度2]...[数组长度N];
int arr[2][3][4];

4.1、二维数组

多维数组最简单的形式是二维数组
本质:一维数组的列表

类型 数组名[x][y];

在这里插入图片描述

4.1.1、初始化

有两种写法:
可以按行初始化,也可以整体赋值

int arr[2][3] = {   // 每行是3个元素数组
	{1, 2, 3},
    {4, 5, 6}
};
int arr[2][3] = {1, 2, 3, 4, 5, 6};   
4.1.2、访问元素

组合两个维度的索引进行定位

int value = arr[1][2];

5、指向数组的指针

int arr[3];

数组变量arr可以看作是指向&arr[0]的指针,也就是指向数组第一个元素的位置,即首地址

int arr[3];
cout << arr << endl;   // 数组变量(相当于arr[0]地址)
cout << &arr[0] << endl;    // 取第一个元素的地址

在这里插入图片描述
数组名就是指向数组第一个元素的常量指针

int *p;
int arr[3];
p = arr;

使用数组名作为常量指针是合法的,反之亦然
将数组名赋值给指针,那么指针就指向该数组的首地址,可以借助指针对于数组进行一些操作

int *p;
int arr[3] = {1, 3, 4};
p = arr;
cout << *(p + 2) << endl;
cout << arr[2] << endl;

在这里插入图片描述

在这里*(p + 2)arr[2]的取值是一样的,都是4
arr[2]代表的是数组arr的第三个元素,从arr[0]开始,往后两个,这也就是(p + 2)代表的含义,前面我们了解到,数组是一块连续的内存,因而当p = arr后,p就指向arr[0]的地址,往后移动两个,指针变量便加2,移动两个步长(与指针变量的类型有关),因此(p + 2)就指向arr[2]的地址,等价于&arr[2],借助*(解引用)从该内存中取出内容,便是arr[2]

6、传递数组给函数

C++ 中可以通过指定不带索引的数组名来传递一个指向数组的指针
因此,传递数组作为参数,会自动转换为传递指针,那么指针的实质其实就是内存地址

对于编译器来说,这些数组的传递无非就是对应类型的指针

方式一:
很实在,本来就是指针,摊牌了

void myFunc(int *p) {    

}

方式二:
已定义大小的数组,满满的仪式感,数组该有的都得安排

void myFunc(int arr[3]) {

}

方式三:
未指定大小的数组,仪式感兼顾,折中一点

void myFunc(int arr[]) {

}

这几种函数都支持接收数组作为参数,但是数组作为函数的参数时,编译器并不会进行边界检查,因此方式二的声明方式稍显多余,作用并不比注释大

void myFunc1(int *p)
{
    for (int i = 0; i < 5; i++)
    {
        cout << *(p + i);
    }
    cout << endl;
}

void myFunc2(int arr[3])
{
    for (int i = 0; i < 3; i++)
    {
        cout << arr[i];
    }
    cout << endl;
}

void myFunc3(int arr[])
{
    for (int i = 0; i < 5; i++)
    {
        cout << arr[i];
    }
    cout << endl;
}

int main()
{

    int arr[] = {1, 3, 4, 7, 5};
    myFunc1(arr);
    myFunc2(arr);
    myFunc3(arr);
}

在这里插入图片描述

7、从函数返回数组

C++不允许返回一个完整的数组作为函数的参数,但是可以通过指定不带索引的数组名来返回指向数组的指针

int* myFunc()    // 返回指针类型
{
    
}

如果使用数组名返回,就是如下场景:
在这里插入图片描述
但是这样写存在问题,我们运行一下就知道了

int main()
{
    cout << *myFunc() << endl;
}

在这里插入图片描述
local反复被提及,说明是局部变量的问题
因为当函数结束时,局部数组将被销毁,指向它的指针将变得无效
C++ 不支持在函数外返回局部变量的地址,除非定义局部变量为static变量

int* myFunc()
{
    static int arr[3] = {1, 4, 7};   // 添加static关键字
    return arr;
}

或者,也可以使用动态内存分配的方式

int* myFunc()
{
    int* arr = new int[3];   // 动态申请内存
    arr[0] = 1;
    arr[1] = 4;
    arr[2] = 7;
    return arr;
}
int main()
{
    int* p = myFunc();
    cout << *p << endl;
    delete[] p;   // 注意释放内存
}

当使用动态分配数组时,要注意释放返回的数组
这是因为在函数内部分配的数组在函数结束时不会自动释放,避免造成内存泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值