考题:
什么是数组以及其特点是什么?还有它的内存空间的位置是如何排列的?
一维数组有哪三种定义方式?
一维数组组名的用途有哪些?
数组:
5.1 概述
Q:什么是数组以及其特点是什么?
A:数组是一个集合,里面存放了相同类型的数据元素,同时它是由连续的内存位置组成
ps:这里也就说明了为什么指针指向数组首元素,就相当于找到了数组所有元素的地址
所谓数组,就是一个集合,里面存放了相同类型的数据元素
特点1:数组中的每个数据元素都是相同的数据类型
特点2:数组是由连续的内存位置组成的
5.2 一维数组
5.2.1 一维数组定义方式
一维数组定义的三种方式:
1.数据类型 数组名[ 数组长度 ];
2.数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
3.数据类型 数组名= { 值1,值2 ...};
▪案例:
int main() { //定义方式1 //数据类型 数组名[元素个数]; int score[10]; //利用下标赋值 score[0] = 100; score[1] = 99; score[2] = 85; //利用下标输出 cout << score[0] << endl; cout << score[1] << endl; cout << score[2] << endl; //第二种定义方式 //数据类型 数组名[元素个数] = {值1,值2 ,值3 ...}; //如果{}内不足10个数据,剩余数据用0补全 int score2[10] = { 100, 90,80,70,60,50,40,30,20,10 }; //逐个输出 //cout << score2[0] << endl; //cout << score2[1] << endl; //一个一个输出太麻烦,因此可以利用循环进行输出 for (int i = 0; i < 10; i++) { cout << score2[i] << endl; } //定义方式3 //数据类型 数组名[] = {值1,值2 ,值3 ...}; int score3[] = { 100,90,80,70,60,50,40,30,20,10 }; for (int i = 0; i < 10; i++) { cout << score3[i] << endl; } system("pause"); return 0; }
! :数组中下标是从0开始索引
5.2.2 一维数组数组名
一维数组名称的用途:
1.可以统计整个数组在内存中的长度
2.可以获取数组在内存中的首地址
▪案例:
int main() { //数组名用途 //1、可以获取整个数组占用内存空间大小 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; cout << "整个数组所占内存空间为: " << sizeof(arr) << endl; cout << "每个元素所占内存空间为: " << sizeof(arr[0]) << endl; cout << "数组的元素个数为: " << sizeof(arr) / sizeof(arr[0]) << endl; //2、可以通过数组名获取到数组首地址 cout << "数组首地址为: " << (int)arr << endl; cout << "数组中第一个元素地址为: " << (int)&arr[0] << endl; cout << "数组中第二个元素地址为: " << (int)&arr[1] << endl; //arr = 100; 错误,数组名是常量,因此不可以赋值 system("pause"); return 0; }
补充:数组首元素地址和数组地址的关系:
https://blog.csdn.net/Raven_csdn/article/details/87874679
1、首先数组首元素的地址和数组地址的值是相等的。
2、数组首元素的地址和数组地址是两个不同的概念。
a的值是数组首元素的地址,所以a+1,就是第二个元素的地址,int类型占用4个字节,所以相差4
而&a是整个数组的地址,所以&a+1,就是向后移动(10*4)个单位。所以相差40.
注意:数组名是常量,不可以赋值
总结1:直接打印数组名,可以查看数组所占内存的首地址
总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小
▪案例:
练习案例1:五只小猪称体重
案例描述:
在一个数组中记录了五只小猪的体重,如:int arr[5] = {300,350,200,400,250};
找出并打印最重的小猪体重。
#include <iostream> using namespace std; int main(){ //1.创建5只小猪体重的数组 int arr[5]={300,350,200,400,250}; //2.从数组中找到最大值 int max=0; for(int i=0;i<5;i++){ if(arr[i]>max){ max=arr[i]; } } //3.打印最大值 cout<<"最重的小猪体重为:"<<max<<endl; system("pause"); return 0; }
**练习案例2:**数组元素逆置
**案例描述:**请声明一个5个元素的数组,并且将元素逆置.
(如原数组元素为:1,3,2,5,4;逆置后输出结果为:4,5,2,3,1);
#include <iostream> using namespace std; int main(){ //实现数组元素的逆置 //1.创建数组 int arr[5]={1,3,2,5,4}; int len=sizeof(arr)/sizeof(arr[0]); //获取数组的长度 cout<<"数组逆置前:"; for(int i=0;i<len;i++){ cout<<arr[i]<<" "; } cout<<endl; //2.实现逆置 //2.1记录起始下标位置 //2.2记录结束下标位置 //2.3起始下标与结束下标的元素互换 //2.4 起始位置++ 结束位置-- //2.5循环执行2.1操作,直到起始位置》=结束位置 int start=0;//起始下标 int end=len-1;//结束下标 while(start<end){ //实现元素互换 int temp=arr[start]; arr[start]=arr[end]; arr[end]=temp; //下标更新 start++; end--; } //打印逆置后的数组 cout<<"数组逆置后:"; for(int i=0;i<len;i++){ cout<<arr[i]<<" "; } cout<<endl; system("pause"); return 0; } //以上采取镜像转换的方式来逆序排序
冒泡排序
作用: 最常用的排序算法,对数组内元素进行排序
步骤:
1.每轮比较相邻元素。若前比后大,则交换二者。
注:对每一对相邻元素做同样的工作,执行后,找到第一个最大值。就像泡泡越升越大。
2.重复以上的步骤,每次比较次数-1(因为最大已找到),直到不需要比较
示例: 将数组 { 4,2,8,0,5,7,1,3,9 } 进行升序排序
#include <iostream> using namespace std; int main() { int arr[9] = { 4,2,8,0,5,7,1,3,9 }; int len=sizeof(arr)/sizeof(arr[0]); for (int i = 0; i < len - 1; i++)//趟数 len-1 ,9个数意味着要比较8趟,即需要把大的数浮到表面的次数为8次 { for (int j = 0; j < len - 1 - i; j++) //每一趟的比较次数 len-1-i { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout<<endl; system("pause"); return 0; }
5.3 二维数组
二维数组就是在一维数组上,多加一个维度。
5.3.1 二维数组定义方式
二维数组定义的四种方式:
1.数据类型 数组名[ 行数 ][ 列数 ];
2.数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
3.数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
4.数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性
▪案例:
int main() { //方式1 //数组类型 数组名 [行数][列数] int arr[2][3]; arr[0][0] = 1; arr[0][1] = 2; arr[0][2] = 3; arr[1][0] = 4; arr[1][1] = 5; arr[1][2] = 6; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << arr[i][j] << " "; } cout << endl; } //方式2 //数据类型 数组名[行数][列数] = { {数据1,数据2 } ,{数据3,数据4 } }; int arr2[2][3] = { {1,2,3}, {4,5,6} }; //方式3 //数据类型 数组名[行数][列数] = { 数据1,数据2 ,数据3,数据4 }; int arr3[2][3] = { 1,2,3,4,5,6 }; //方式4 //数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 }; int arr4[][3] = { 1,2,3,4,5,6 }; system("pause"); return 0; }
注意点:
▪注意点:
for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << arr[i][j] << " "; } cout << endl; //换行加缓冲区刷新 }
注意红字部分,只有这么写输出的才是
123
456
总结:在定义二维数组时,如果初始化了数据,可以省略行数
5.3.2 二维数组数组名
▪查看二维数组所占内存空间
▪获取二维数组首地址
▪案例:
int main() { //二维数组数组名 int arr[2][3] = { {1,2,3}, {4,5,6} }; cout << "二维数组大小: " << sizeof(arr) << endl; cout << "二维数组一行大小: " << sizeof(arr[0]) << endl; cout << "二维数组元素大小: " << sizeof(arr[0][0]) << endl; cout << "二维数组行数: " << sizeof(arr) / sizeof(arr[0]) << endl; cout << "二维数组列数: " << sizeof(arr[0]) / sizeof(arr[0][0]) << endl; //地址 cout << "二维数组首地址:" << arr << endl; cout << "二维数组第一行地址:" << arr[0] << endl; cout << "二维数组第二行地址:" << arr[1] << endl; cout << "二维数组第一个元素地址:" << &arr[0][0] << endl; cout << "二维数组第二个元素地址:" << &arr[0][1] << endl; system("pause"); return 0; }
总结1:二维数组名就是这个数组的首地址
总结2:对二维数组名进行sizeof时,可以获取整个二维数组占用的内存空间大小
5.3.3 二维数组应用案例
▪案例:
考试成绩统计:
案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩
int main() { int scores[3][3] = { {100,100,100}, {90,50,100}, {60,70,80}, }; string names[3] = { "张三","李四","王五" }; for (int i = 0; i < 3; i++) { int sum = 0; / for (int j = 0; j < 3; j++) { sum += scores[i][j]; } cout << names[i] << "同学总成绩为: " << sum << endl; } system("pause"); return 0; }
注意点:
int sum = 0 这一块要理解,
它的功能不仅是赋值,而且还附带将sum清0的效果
函数:
6.1 概述
作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
6.2 函数的定义
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
返回值类型 函数名 (参数列表) { 函数体语句 return表达式 }
▪返回值类型 :一个函数可以返回一个值。在函数定义中
▪函数名:给函数起个名称
▪参数列表:使用该函数时,传入的数据
▪函数体语句:花括号内的代码,函数内需要执行的语句
▪return表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据
示例:定义一个加法函数,实现两个数相加
//函数定义 int add(int num1, int num2) { int sum = num1 + num2; return sum; }
6.3 函数的调用
功能:使用定义好的函数
语法:函数名(参数)
示例:
//函数定义 int add(int num1, int num2) //定义中的num1,num2称为形式参数,简称形参 { int sum = num1 + num2; return sum; } int main() { int a = 10; int b = 10; //调用add函数 int sum = add(a, b);//调用时的a,b称为实际参数,简称实参 cout << "sum = " << sum << endl; a = 100; b = 100; sum = add(a, b); cout << "sum = " << sum << endl; system("pause"); return 0; }
总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参
6.5 函数的常见样式
常见的函数样式有4种
1.无参无返
2.有参无返
3.无参有返
4.有参有返
示例:
//函数常见样式 //1、 无参无返 void test01() { //void a = 10; //无类型不可以创建变量,原因无法分配内存 cout << "this is test01" << endl; //test01(); 函数调用 } //2、 有参无返 void test02(int a) { cout << "this is test02" << endl; cout << "a = " << a << endl; } //3、无参有返 int test03() { cout << "this is test03 " << endl; return 10; } //4、有参有返 int test04(int a, int b) { cout << "this is test04 " << endl; int sum = a + b; return sum; }
6.6 函数的声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
▪函数的声明可以多次,但是函数的定义只能有一次
示例:
//声明可以多次,定义只能一次 //声明 int max(int a, int b); int max(int a, int b); //定义 int max(int a, int b) { return a > b ? a : b; } int main() { int a = 100; int b = 200; cout << max(a, b) << endl; system("pause"); return 0; }
6.7 函数的分文件编写
作用:让代码结构更加清晰
函数分文件编写一般有4个步骤
1.创建后缀名为.h的头文件
2.创建后缀名为.cpp的源文件
3.在头文件中写函数的声明
4.在源文件中写函数的定义
示例:
//swap.h文件 #include<iostream> using namespace std; //实现两个数字交换的函数声明 void swap(int a, int b);
//main函数文件 #include "swap.h" int main() { int a = 100; int b = 200; swap(a, b); system("pause"); return 0; }
//swap.cpp文件 #include "swap.h" void swap(int a, int b) { int temp = a; a = b; b = temp; cout << "a = " << a << endl; cout << "b = " << b << endl; }
文件分布如下: