23-24C++(42)——一维数组应用+new自定义动态数组**********************

一、sizeof 运算

用于得到某个变量或者某种类型占用的内存空间(单位是字节)。

【例 1】变量和类型长度

cout << sizeof(int) << " " << sizeof(double) << " " << sizeof(char) << endl;

int a; double b; char c;

cout << sizeof(a) << " " << sizeof(b) << " " << sizeof(c) << endl;

【运行结果】

4 8 1

4 8 1

cout << sizeof(int) << " " << sizeof(double) << " " << sizeof(char) << endl; 
int a; 
double b; 
char c; 
cout << sizeof(a) << " " << sizeof(b) << " " << sizeof(c) << endl; 

记住!!!!!!!!!!!!!!!!

sizeof 运算也可以得到数组占用的内存空间。

数组占用的内存空间=单个元素占用的内存空间*元素个数。

如果定义 int a[10];

则 a 数组在内存中占用 40 个字节, 即 sizeof(a)的值是 40。

连续的!!!!!!!

特点一:数组中的每个数据元素都是相同类型的数据元素

特点二:数组是由连续的内存位置组成的

*************************************************************************

二、根据变量值定义数组长度

在此前学到定义数组时,通常是给定数组长度,

例如长度为 10 的整型数组 a,可以定 义为 int a[10]; 也可以 const int n=10; int a[n];

但如果根据变量 n 定义一个长度为 n 的整型数组 a, 例如 int n; cin >> n; 则以下定义数组的方式是错误的:

int a[n];

原因在于数组的长度必须在程序运行之前确定。

换一种方式定义就可以:

int *a = new int[n];

这种方法称为动态申请数组空间,定义了一个长度为 n 的数组 a。这块知识本应该是下一章指针的内容,但 OJ 上经常需要用到,所以先行学习。

如果要定义长度为 n 的 double 类 型数组 b,则需要

double *b= new double[n];

使用动态数组,内存不会自动释放,需要在完全不需要使用后手动回收内存空间。

当数组名字为 a 时,释放空间的方法是 delete[ ] a;

注意,只有 new 的数组才可以 delete。

*************************************************************************

三、数组作为函数的实参

1、函数定义

如果函数 f 的返回值为 int,需要接收一个浮点类型的数组作为形参,那么 f 的声明: int f(double a[ ]); 表示形参 a 是一个 double 类型的数组。  

2、函数调用

当定义了 double a[10]; 如果需要调用上述函数 f,可以是 int b = f(a); 也就是说把数组 的名字当作实参,表示把一个 double 类型的数组当作实参传递给函数的形参。

当参数是数组时,形参和实参数组元素类型必须严格一致,即不可以形参是 int 数组, 而实参是 double 数组。

【例 1】斐波那契数列是这样一组有规律的数字:1、1、2、3、5、8、13、21、34、…。

这 组数字的前两项都是 1,从第三项开始,每个数字都是前两个数字的和。

输入一个正整数 n (n>=2),顺序输出斐波那契数列前 n 项,每两个数字之间有一个空格,最后一个数字后面 不要有空格,不要换行。由于当 n 很大时,数列元素的值可能会非常大,所以只要输出该元 素对 1e+8+7 取余数的结果。  

说明:

1e+8+7 是编程中用科学计数法表示的数字,

1e + 8 + 7 = 1 × 10 8 + 7 = 100000007 在数学中,

(𝑥 + 𝑦)%𝑧 = (𝑥 + 𝑦%𝑧)%𝑧 = (𝑥%𝑧 + 𝑦%𝑧)%𝑧,

利用这个特性,在每次计算数列 下一项时都做了取余数,避免加法过程中溢出,同时也保证了数学上的答案是相同的。

开辟空间:
对于一个数:
		类型* 名字 = new 类型; //申请的该段内存没有进行任何操作;
		类型* 名字 = new 类型(); //将该段内存初始化为0;
  		类型* 名字 = new 类型(初始化值); //将该段内存初始化为一个确定的值;
	
对于一个数组:
		类型* 名字 = new 类型[数组大小];
		类型* 名字 = new 类型[数组大小](初始化值); //该数组的所有元素都赋值为一个确定的值;
		类型* 名字 = new 类型[数组大小]();  //该数组的所有元素都赋值为0;
 
释放空间:
	delete 名字; //一个数;
	delete[] 名字; //一个数组;
#include <iostream>
 
using namespace std;
 
int main()
{
	int n = 10; //动态一维数组长度
	int* a = new int[n]; //申请一维动态数组的空间
	int i; //循坏变量
 
	for (i = 0; i < n; i++)
	{
		a[i] = i;
	}
 
	for (i = 0; i < n; i++)
	{
		cout << a[i] << "  ";
	}
 
	delete[] a; //释放一维数组的空间
 
	return 0;
}
int main()
{
int n;
cin >> n;
int* a = new int[n];
a[0] = a[1] = 1;
for (int i = 2; i < n; i++)
{
a[i] = (a[i - 1] + a[i - 2]) % (1e+8 + 7);
}
for (int i = 0; i < n; i++)
{
if (i == 0)
{
cout << a[i];
}
else
{
cout << " " << a[i];
}
}
delete[]a;
return 0;
}

我们经常会遇到一大段数字中间要有空格最后不用输出空格的情况该怎么处理最简单呢

for (int i = 0; i < n; i++)
{
if (i == 0)
{
cout << a[i];
}
else
{
cout << " " << a[i];
}
}

*************************************************************************

【例 2】数列:1、8、43、4、23、11、58、79、77、…。第一项是 1,之后每一项都是前一 项的值乘以 5 加 3。输入一个正整数 n,输出数列第 n 项对 107 取余数的结果。

说明:

数学上,(𝑥 × 𝑦)%𝑧 = (𝑥 × (𝑦%𝑧))%𝑧 = ((𝑥%𝑧) × (𝑦%𝑧))%𝑧

本题不用数组也可以做。

【例 3】输入一个正整数 n,然后输入 n 个范围从 1 到 10 之间的整数(包含 1 和 10),依次 输出每个数字出现的次数。

分析:定义一个长度为 11 的数组 a,a[1]存放 1 出现的次数,a[2]存放 2 出现的次数,…, a[10]存放 10 出现的次数。

#include<iostream>
using namespace std;
int main()
{
int n, b, a[11] = { 0 };
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> b;
a[b]++;
}
for (int i = 1; i <= 10; i++)
{
cout << a[i] << endl;
}
return 0;
}

【例 4】输入一个正整数 a,然后逐位调整 a 的值。如果 a 的某位数为偶数,则该位数保持 不变;如果 a 的某位数是奇数,则该位数减一,但当此位是最高位且为 1 时不要减。输出变化后的 a 值。

例如当 a 为 12701 时,应该把 a 改为 12600。

#include<iostream>
using namespace std;
int main()
{ int a, len = 0;//len 保存 a 的位数
int b[10] = { 0 };
cin >> a;
while (a > 0)
{
b[len] = a % 10;
a = a / 10;
len++;
}
//从 b[len-1]到 b[0]依次记录了 a 从高位到低//位的所有位的值

for (int i = len - 1; i >= 0; i--)
{
if (b[i] % 2 == 0 || i == len - 1 && b[i] == 1)
{
	continue;
}
b[i]--;
}
//重新拼凑回 a
a = 0;
for (int i = len - 1; i >= 0; i--)
{
	a = a * 10 + b[i];
}
cout << a;
return 0;
}

【例 5】输入一个正整数 n,然后输入 n 个整数存放在长度为 n 的数组 a 中,求其中的最小 值以及最小值对应的数组下标。(假设最小值只有一个,没有并列最小的情况)

分析:

用 min 存放当前的最小值,minPos 存放最小值对应的数组下标。

#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int* a = new int[n];
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
int min = a[0], minPos = 0;
for (int i = 1; i < n; i++)
{
if (a[i] < min)
{
min = a[i];
minPos = i;
}
}
cout << min << " " << minPos;
delete[]a;
return 0;
}

【例 6】输入一个正整数 n,然后输入 n 个整数存放在长度为 n 的数组 a 中,输出其中的最 小值,换行,再输出最小值对应的数组下标。(并列最小的时候依次输出所有并列最小元素 的下标,每两个下标之间有一个空格)

#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int* a = new int[n];
for (int i = 0; i < n; i++)
{
	cin >> a[i];
}
int min = a[0];
for (int i = 1; i < n; i++)
{
if (a[i] < min)
{
	min = a[i];
}
}
cout << min << endl;

bool first = true;
for (int i = 0; i < n; i++)
{
if (a[i] == min)
{
if (first) //第一个下标前不要空格,其它下标输出前都要先空格
{
	first = false;
}
else
{
	cout << " ";
}
cout << i;
}
}
delete[]a;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小7爱睡觉我爱她

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值