C++原始数组(不是array)

数组

int main(){
    int example[5];
    for(int i = 0; i<5; i++)
    {
        example[i] = i;
    }
    
}

对于数组,for循环的判断部分一般写小于数组长度。如果写i<=4,性能会有损失,因为需要做小于和等于的判断,另外这个数直接写数组的长度更容易理解。

在release模式下,数组越界不会报错,这导致可能修改其他地方的变量值(访问了不属于该数组的地址)。

1 数组的内存

// example数组首地址
cout<< example<< endl;
// 数组所占内存大小,输出20
cout<< sizeof(example)<< endl;
// 数组索引2对应的元素值,输出2
cout<< example[2]<< endl;

对于上述example数组,这里example相当于数组指针,指向example数组首地址。由于example数组是int,长度为5,因此数组总长度为4*5=20。example数组的内存如下:

00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 
example[0]	|example[1]	|example[2]	|example[3]	|example[4]|

2 数组的访问

用ptr指向example,对数组进行访问,那么以下几个表达式等价:

int* ptr = example;
// 以下表达式等价:
example[2] = 2;
*(ptr + 2) = 2;
*(int*)((char*)ptr + 8) = 2;
  • “*(ptr + 2) = 2” :因为ptr是int类型指针,因此偏移的最小单元是4个byte,ptr+2相当于example首地址+2*4,即example[2]的连续4个byte的空间。
  • “(int*)((char*)ptr + 8)”:ptr被强制转换为char类型指针,因此偏移最小单元是1个byte,因此此处+8才能访问到example[2]的第0个byte。但char类型指针只能访问数据长度为1byte的空间,因此还要在将其强制转化为int类型指针,才能访问属于example[2]的完整4byte空间。

3 栈和堆上的数组

栈和堆上的数据的区别是,保存在栈上的数据在作用域结束时会自动释放,但堆上的数据则需要手动释放。因此,如果一个函数需要返回在这个函数中创建的数组时,该新生成的数组只能保存在堆上(用new生成)。

内存间接寻址

class Entity
{
public:
	// int example[5];
    int* example = new int[5];
    Entity()
    {
        for (int i = 0; i < 5; i++)
            example[i] = 2;
    }
};

int main(){
    Entity e;
    
}

上述代码中,Entity类中有一个example数组。

  • 如果example数组保存在栈上(注释部分),实例化以后,e的地址就是数组的起始地址。
  • 如果example数组保存在堆上(new),e的地址保存的是一个地址(这里称该地址为address),而address保存着example数组的地址。这种情况下要访问example数组,会比保存在栈上多一次间接寻址(&e->&address)。因此在这种情况下更推荐在栈上创建数组,内存间接寻址会影响性能,所以不推荐

4 数组长度

原始数组无法直接得到数组长度。(sizeof是占用内存大小,不是数组元素个数)
对于创建在栈上的数组,可以用如下方式得到数组长度。

int example[5];
int length = sizeof(example)/sizeof(int);

但这个方法并不推荐。因为一旦这个变量因为一些原因变成了指针(比如放到函数中),sizeof(example)将变成指针所占内存大小,这里length就会变为1。另外,堆上数组的数组名就是指针,根本用不了这个方法。

可以用如下方式维护数组长度:

class Entity
{
public:
	// 这样维护数组长度
    static const int exampleSize = 5;
    int example[exampleSize];
    Entity()
    {
        for (int i = 0; i < exampleSize; i++)
            example[i] = i;
    }
};

当然也可以使用array:

#include <array>

class Entity
{
public:
	// <类型,长度>
    array<int, 5> another;
    Entity()
    {
    	// 调用size()
        for (int i = 0; i < another.size(); i++)
            another[i] = i;
    }
};

使用array会有一定代价,array会有单独变量来维护数组长度,并且会做边界检查等,会稍慢。但array会更方便,也会更安全。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
假设你要将一个整数数组中所有大于等于10且小于等于100的数存放到另一个数组中,可以按照以下步骤实现: 1. 定义两个整数数组,一个原始数组和一个目标数组。 ```c++ int originalArray[10]; // 假设原始数组长度为10 int targetArray[10]; // 假设目标数组长度为10 ``` 2. 通过循环向原始数组中添加随机整数。 ```c++ for (int i = 0; i < 10; i++) { originalArray[i] = rand() % 100 + 1; // 生成1到100之间的随机整数 } ``` 3. 定义一个变量来记录目标数组中已存储的元素个数。 ```c++ int targetIndex = 0; ``` 4. 再次循环遍历原始数组,如果某个元素大于等于10且小于等于100,则将其存储到目标数组中,并将目标数组指针后移一位。 ```c++ for (int i = 0; i < 10; i++) { if (originalArray[i] >= 10 && originalArray[i] <= 100) { targetArray[targetIndex] = originalArray[i]; targetIndex++; } } ``` 5. 最后,输出目标数组中的元素。 ```c++ for (int i = 0; i < targetIndex; i++) { cout << targetArray[i] << " "; } ``` 完整的代码如下: ```c++ #include <iostream> #include <cstdlib> using namespace std; int main() { int originalArray[10]; int targetArray[10]; int targetIndex = 0; for (int i = 0; i < 10; i++) { originalArray[i] = rand() % 100 + 1; } for (int i = 0; i < 10; i++) { if (originalArray[i] >= 10 && originalArray[i] <= 100) { targetArray[targetIndex] = originalArray[i]; targetIndex++; } } for (int i = 0; i < targetIndex; i++) { cout << targetArray[i] << " "; } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值